《深刻理解Java虛擬機》筆記二

大部份內容都是《深刻理解Java虛擬機上的內容》的總結,少部份內容是來自於網上或者本身的理解。讀完應該會把沒筆記的markdown文件放在github上。

本部分筆記對應的是《深刻理解Java虛擬機》第四章,第五章和第六章。java

虛擬機性能監控和故障處理工具

命令行工具

名稱git

主要做用github

jps數組

JVM Process Status Tool,顯示指定系統內全部HotSpot虛擬機進程瀏覽器

jstat緩存

JVM Statistics Monitoring Tool,用於收集HotSpot虛擬機個方面運行數據服務器

jinfomarkdown

Configuration Info for Java,顯示虛擬機配置信息數據結構

jmapide

Memory Map for Java,生成虛擬機的內存轉儲快照(heapdump文件)

jhat

JVM Heap Dump Browser,用於分析heapdump文件,它會創建一個HTTP/HTML服務器讓用戶能夠在瀏覽器上查看分析結果

jstack

Stack Trace for Java,顯示虛擬機的線程快照

可視化工具

  • JConsole
  • VisualVM

調優案例分析與實戰

經過64位JDK來使用內存

  • 內存回收致使長時間的停頓
  • 相同程序在64位JDK消耗的內存通常比32位的大,因爲指針膨脹,數據類型對齊等緣由

使用若干個32位虛擬機創建邏輯集羣來利用硬件資源

  • 節點的全局競爭,磁盤競爭
  • 很難高效的利用某些資源池
  • 受到32位的內存限制
  • 大量的使用本地緩存

垃圾回收時,虛擬機雖然會對Direct Memory進行回收,可是Direct Memory卻不能向新生代,老年代那樣,發現空間不足就通知收集器進行垃圾回收,它只能等待老年代滿了後發生Full GC,而後幫它清理掉內存的廢棄對象,否者它只能拋出內存溢出異常。

類文件結構

Class文件結構

各類不一樣平臺的虛擬機與全部平臺都統一使用的程序存儲格式——字節碼(ByteCode)

實現語言無關性的基礎是虛擬機和字節碼存儲格式,Java虛擬機不和包括Java在內的任何語言綁定,它只與「Class文件」這種特定的二進制文件有所關聯,Class文件中包括了Java虛擬機指令集和符號表以及若干其餘輔助信息。

Class文件是一組以8位字節爲基礎單位的二進制流,各個數據項目嚴格按照順序緊湊地排列在Class文件之中,當遇到佔用8字節以上空間的數據項時,則會按照高位在前的方式分割成若干個8位字節進行存儲中間沒有分隔符,因此Class文件內容都是被嚴格限定的

Class文件中結構只有兩個類型--無符號和表

無符號

基本的數據類型,u1,u2,u4,u8表示1個字節,2個字節,4個字節,8個字節的無符號數

由多個無符號數或者其餘表做爲數據結構項構成複合數據數據類型,表都是習慣性以_info結尾。整個Class文件本質上就是一張表

類型 名稱 數量 說明
u4 magic 1 魔術 0xCAFEBABE
u2 minor_version 1 次版本號
u2 major_version 1 主版本號
u2 constant_pool_count 1 常量池容量計數值
cp_info constant_pool constant_pool_count - 1
u2 access_flags 1 訪問標誌
u2 this_class 1 類索引
u2 super_class 1 父類索引
u2 interfaces_count 1
u2 interfaces interfaces_count 接口索引集合
u2 fields_count 1
field_info fields fields_count 字段表集合
u2 methods_count 1
method_info methods methods_count 方法表集合
u2 attributes_count 1
attribute_info attributes attributes_count 屬性表集合

字節碼指令

Java虛擬機的指令由一個字節長度的,表明着某種特定操做含義的數據(稱爲操做碼,Opcode)以及跟隨後的零至多個表明此操做所需參數(稱爲操做數,Operands)而構成。相似於機器指令,在屬性表集合中的Code屬性中。Java的操做碼只有1個字節長度。

操做碼助記符

i表明int類型數據操做,l表明long,s表明short,b表明byte,c表明char,d表明double,f表明float,a表明reference。**

加載和存儲指令

  • 將一個局部變量加載到操做棧 <操做碼助記符>load。
  • 將一個數值從操做棧存儲到局部變量表 <操做碼助記符>store
  • 將一個常量加載到操做棧,bipush,sipush,ldc,ldc_w, ldc2_w, aconst_null, iconen_m1, iconst__, lconst_<l>, fconst__<f>, dconst__<d>,
  • 擴充局部變量表的訪問索引指令,wide
  • 把一個數組元素加載到操做數棧的指令,<操做碼助記符>aload
  • 將一個操做數棧的值存儲到數組元素中的指令,<操做碼助記符>astore

運算指令符

  • 加法指令,<操做碼助記符>add
  • 減法指令,<操做碼助記符>sub
  • 乘法指令,<操做碼助記符>mul
  • 除法指令,<操做碼助記符>div
  • 求餘指令,<操做碼助記符>rem
  • 取反指令,<操做碼助記符>neg
  • 位移指令,ishl, ishr, iushr, lshl, lshr, lushr
  • 按位或指令,ior, lor
  • 按位與指令,iand, land
  • 按位異或指令,ixor, lxor
  • 局部變量自增指令,iinc
  • 比較指令,dcmpg, dcmpl, fcmpg, fcmpl, lcmp

非正規浮點數值, 逐級下溢

類型轉換指令

i2b, i2c, i2s,

l2i,

f2i,f2l,

d2i,d2l,d2f

對象建立與訪問指令

  • 建立類實例的指令 new
  • 建立數組的指令 newarray,anewarray,multianewarray
  • 訪問類字段和實例字段,getfield,putfield,getstatic,putstatic
  • 獲取數組長度的指令,arraylength
  • 檢查類實例類型的指令,instanceof,checkcast

操做數棧管理指令

  • 將操做數的棧頂一個或者兒歌元素出棧,pop,pop2
  • 複製棧頂一個或兩個數值並將複製值或雙份複製值從新壓入棧頂,dup,dup2,dup_x1,dup2_x1,dup_x2,dup2_x2
  • 將棧最頂端的兩個數值互換 swap

控制轉移指令

  • 條件分支, ifeq, iflt, ifle, ifne, ifgt, ifge, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmplt, if_icmpgt, if_icmple,if_icmpge, if_acmpeq 和if_acmpne
  • 複合條件分支, tableswitch,lookupswitch
  • 無條件分支,goto,goto_w,jsr,jsr_w,ret

方法調用和返回指令

方法調用

  • invokevirtual,調用對象的實例方法
  • invokeinterface, 調用接口方法,它會在運行時,搜索一個實現了這個接口方法的對象
  • invokespecial,調用一些須要特殊處理的實方法,如實例初始化方法,實例私有方法或父類方法
  • invokestatic,調用類方法
  • invokedynamic,在運行時動態解析出調用點限定符所引用的方法

返回指令

  • 返回null,return
  • 返回類型,<操做碼助記符>return

異常處理指令

在java程序中都是有athrow指令實現。在java虛擬機中有異常表實現

同步指令

Java虛擬機能夠支持方法級的同步和方法內部一段指令序列的同步,這個兩種同步結構都是使用管程實現

方法級的同步,是隱式的。經過方法表中的ACC_SYNCHRONIZED訪問標誌來申明是否爲同步方法。若是是,執行線程要求先成功持有管程,而後在執行方法,執行完以後釋放管程。

同步一段指令序列一般由synchronize語句塊,由monitorenter和monitorexit兩條指令來支持synchronize關鍵字的語義。

相關文章
相關標籤/搜索