java虛擬機簡單介紹

jvm

使用軟件模擬java字節碼的指令集

jvm的發展歷史

  1. 1996年jdk1.0(sun)發佈 :純解釋運行
  2. 1997年jdk1.1發佈,AWT、內部類、jdbc、rmi、反射
  3. 1998年jdk1.2發佈,java分se、me、ee,加入swing
  4. 2000年jdk1.3發佈,Hotspot作爲默認虛擬機
  5. 2002年jdk1.4發佈,classic vm退出歷史,加入assert、nio、ipv6、日誌
  6. 2004年jdk1.5發佈,加入泛型、註解、枚舉、裝箱、變長參數、foreach
  7. 2006年jdk1.6發佈,加入腳本語言支持、jdbc4.0
  8. 2011年jdk1.7發佈,加入動態語言增強、nio2.0、加入G1
  9. 2014年jdk1.8發佈,lambda表達式,函數式編程

jvm運行機制

1. java xxx 執行運行命令
2. 裝載配置(jvm.cnf)
3. 尋找dll(jvm.dll爲java虛擬機的主要實現)
4. 初始化jvm(JNIEnv爲jvm接口,findClass通過它實現)
5. 找到mian方法並運行

jvm的內部結構

jvm的內部結構

pc寄存器

每個線程都有一個獨立的pc寄存器

方法區

保存裝載的類信息

java堆

應用系統對象保存、所有線程共享堆、gc的主要工作空間、堆也是分代的(分代gc)

java棧

線程私有,棧由一些列幀組成、幀保存一個方法的局部變量、操作數棧、常量池指針,每一個方法調用創建一個幀、並壓棧

可見性

一個線程修改了變量,其他線程可以立即知道

保證可見性方式
volatile
synchronized unlock之前,將變量值寫會主存
final 一旦初始化完成,其他線程可見

有序性

本線程內,操作都是有序的

在線程外觀察,操作都是無序的(指令重排或者主存延時)

指令重排

保證線程內按順序執行的結果完全相同

指令重排原則:
順序原則:一個線程內保證語義的串行性
volatile規則:volatile變量的寫,先發生於讀
鎖規則:解鎖必然發生於隨後的加鎖前
傳遞性:a先於b,b先於c,則a必然先於c
線程的start先於他的每一個動作
線程的所有操作先於線程的終結
線程的中斷先於被中斷的線程的代碼
對象的構造函數的執行結束先於finalize()方法

jvm的配置參數

trace跟蹤參數

-verbose:gc   (打開gc跟蹤日誌)
-XX:+PrintGC  打印gc簡要信息
-XX:+PrintGCDetails 打印gc詳細信息
-XX:+PrintGCTimeStamps 打印gc發生的時間戳
-Xloggc:log/gc.log  指定gc的log文件的位置
-XX:+PrintHeapAtGC  每一個gc後,打印堆信息
-XX:+TraceClassLoading  監控類的加載
-XX:+PrintClassHistogram  按下ctrl+break後,打印類的信息(分別顯示:序號、實例數量、總大小、類型)

堆的分配參數

-Xmx -Xms  指定最大堆和最小堆空間
-Xmx20m    最大可用20m
-Xms5m     初始化佔用5m
-Xmn       設置新生代的大小的絕對值
-XX:NewRatio 設置新生代的大小比例(設置4 表示 新生代:老年代=14,即年輕代佔堆的1/5) 官方推薦佔3/8
-XX:SurvivorRatio 設置兩個survivor和Eden的比(設置8 表示s:e=2:8,即一個survivor佔年輕代的1/10) 官方推薦佔1/10
-XX:HeapDumpOnOutOfMenoryError 發生內存溢出時導出堆到文件
-XX:+HeapDumpPath 設置發生內存溢出導出文件的路徑
-XX:OnOutOfMenoryError  在發生內存溢出時執行一個腳本

永久區分配參數

-XX:PermSize    設置永久區的大小
-XX:MaxPermSize 設置永久區的最大空間大小
如果堆空間未使用完,發生了內存溢出,則有可能是永久代內存溢出

棧大小的分配

通常只有幾百k決定了函數調用的深度每個線程都有獨立的棧空間局部變量、參數分配在棧上

-Xss 分配棧空間的大小(e:-Xss128k)

GC算法和種類

GC:垃圾回收,GC的回收目標是堆空間和永久區

引用計數法

通過引用計算來回收垃圾 爲每個對象設計一個引用計數器,如果有對象引用該對象,則計數加1,引用釋放,則計數減1 比較影響性能,始終都伴隨着應用加和減 很難處理循環引用 java中沒有被使用

標記-清除算法

現代垃圾回收算法的思想基礎 分爲標記階段(通過根節點,標記所有從根節點開始的可達對象,未被標記的對象即是垃圾對象)和清除階段(清除所有未被標記的對象)

標記-整理算法

適用於存活對象較多的場合,如老年代 從根節點開始,對所有可達對象做一次標記,之後將所有存活對象整理到內存的一端,然後清理邊界外的所有空間

複製算法

是一種相對高效的算法 不適用於存活對象較多的場合 將原有空間分爲兩塊,每次只使用其中一塊,垃圾回收時,將正在使用的內存中的存活對象複製到未使用的內存中,之後清除正在使用塊的所有對象,然後交換兩個內存角色 比較浪費空間

分代思想

依據對象的存活週期,存活時間短的歸爲新生代,存活時間長的對象爲老年代 根據不同代的特點,選取合適的收集算法(少量對象存活,適合複製算法)(大量對象存活,適合標記清除和標記整理)

可觸及性

可觸及的從根節點可以觸及到這個對象

可復活的一旦所有引用被釋放,就是可復活狀態 在調用finalize()中可能復活的對象

不可觸及的執行finalize()之後會進入不可觸及狀態 不可觸及的對象不可能復活 可以被垃圾回收器回收

finalize()方法只會被調用一次,在第一次執行gc調用,之後的gc操作不會調用finalize()

注意事項

避免使用finalize(),操作不慎可能導致錯誤 gc的調用不確定 可以使用try-catch-finally處理資源的釋放

根節點

棧中引用的對象 方法區中靜態成員或者常量引用的對象 JNI(java native 方法)方法棧中引用的對象

Stop-The-World

java中一種全局暫停的現象 全局停頓,所有java代碼停止,native代碼可執行,但不能和jvm交互 多半由於gc引起(dump線程,死鎖檢查,堆dump也可能引起) 可能會導致(長時間停止服務,沒有響應 高可用系統中可能會引起主備切換,危害生產環境)

GC參數

串行回收器

最古老,最穩定,效率高,可能會產生比較長的停頓

-XX:+UseSerialGC //串行回收器
  //新生代,老年代會使用串行回收
  //新生代使用的是複製算法
  //老年代使用的是標記-整理算法
並行收集器

ParNew收集器

-XX:+UseParNewGC //並行回收器
 //新生代並行,老年代串行
 //Serial收集器新生代的並行版本
 //使用複製算法
 //多線程性能比較好,需要多核支持
-XX:ParallelGCThreads //限制線程數量

parallel收集器

//類似ParNew
//新生代使用複製算法
//老年代使用標記-整理算法
//更加關注吞吐量
//串行收集器在新生代以及老年代的並行化
-XX:+UseParallelGC //新生代並行,老年代串行
-XX:+UseParallelOldGC //新生代並行,老年代並行

並行收集器其他參數

-XX:MaxGCPauseMills //最大停頓時間,單位毫秒,GC儘量保證回收時間不超過該時間
-XX:GCTimeRatio //0-100的取值範圍,垃圾回收時間佔總時間的比值,默認99,即允許1%時間做GC
//這兩個參數是矛盾的,吞吐量和停頓時間不可能同時調優

CMS收集器

-XX:UseConcMarkSweepGC //CMS收集器,與應用程序一起並行執行,減少停頓(儘可能縮小,不能完全消除),降低吞吐量
//Concurrent Mark Sweep 併發標記清除
//使用標記-清除算法
//與標記-整理相比,併發階段會降低吞吐量
//是老年代收集器(新生代使用PerNew)
//運行過程:
    //初始標記【停頓】(標記根可直接關聯到的對象,速度快)
    //併發標記【並行】(主要標記過程,標記全部對象)
    //重新標記【停頓】(由於併發標記時,用戶線程依然運行,因此正式清理前再做修正)
    //併發清除【並行】(基於標記結果,直接清理對象)
    //併發重製【並行】(爲下次回收做準備)
//特點:
    //儘可能降低停頓
    //會影響系統整體吞吐量和性能
    //清理不徹底(和用戶線程一起執行,會產生新的垃圾)
    //不能再空間即將滿的時候再清理(如果預留空間不足,會引起concurrent mode failure,如果出現該錯誤,會使用[串行收集器]作爲後備)
    -XX:CMSInitiatingOccupancyFraction //設置觸發GC的閾值,當堆空間佔用的比值達到該閾值即觸發
    -XX:+UseCMSCompactAtFullCollection //full gc之後進行一次內存整理,整理期間停頓
    -XX:CMSFullGCsBeforeCompaction //設置進行幾次full gc之後進行一次碎片整理
    -XX:ParallelCMSThreads //設定CMS的線程數,一般情況約爲CPU數量
    -XX:+CMSClassUnoladingEnabled //允許對類的元數據進行回收
    -XX:CMSInitiatingPermOccupancyFraction //當永久區佔用率達到該百分比值時,啓用CMS收集器
    -XX:UseCMSInitiatingOccupancyOnly //表示只在達到閾值的時候,才進行CMS回收

G1收集器

-XX:+UseG1GC  //G1收集器
//G1(Garbage-First)是面向服務端應用的垃圾收集器。
//特點:
    //並行與併發,G1收集器可以通過併發的方式讓Java程序繼續執行
    //分代收集,G1可以不需要其他收集器配合就能獨立管理整個GC堆,採用不同的方式去處理新創建的對象和已經存活了一段時間、熬過多次GC的舊對象以獲取更好的收集效果。
    //空間整合,G1從整體來看是基於 標記—整理算法 實現的收集器,從局部來看是基於 複製算法 實現的,這兩種算法都意味着G1運作期間不會產生內存空間碎片。
    //可預測的停頓,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒。

//使用G1收集器時,Java堆的內存佈局就與其他收集器有很大差別,它將整個Java堆劃分爲多個大小相等的獨立區域(Region),雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔離的了,它們都是一部分Region(不需要連續)的集合。
-XX:G1HeapRegionSize  //設置region的大小
//G1收集器之所以能建立可預測的停頓時間模型,是因爲它可以有計劃地避免在整個Java堆中進行全區域的垃圾收集。G1跟蹤各個Region裏面的垃圾堆積的價值大小(回收所獲得的空間大小以及回收所需時間的經驗值),在後臺維護一個優先列表,每次根據允許的收集時間,優先回收價值最大的Region(這也就是Garbage-First名稱的來由)。這種使用Region劃分內存空間以及有優先級的區域回收方式,保證了G1收集器在有限的時間內可以獲取儘可能高的收集效率。
//執行過程:
    //初始標記【停頓】(標記根可以直接關聯到的對象,並修改TAMS[next top at mark start]的值),讓下一階段用戶程序併發執行時,能在正確的可用Region中創建新對象
    //併發標記【並行】(標記所有對象,與用戶程序併發執行)
    //最終標記【停頓】(修正在併發標記期間因用戶程序繼續運行而導致的標記變動)
    //篩選回收【停頓】(對各個Region的回收價值和成本進行排序,根據用戶期望的停頓時間制定回收計劃,這個階段可以做到並行執行,但是隻回收一部分Regina,時間是用戶可控制的,停頓可以大幅提高收集效率)
-XX:InitiatingHeapOccupancyPercent  //堆內存佔用達到該百分比值時啓動併發GC
-XX:MaxTenuringThreshold  //提升老年代的最大臨界值,默認爲15
-XX:G1ReservePercent  //預留多少內存,防止晉升失敗的情況,默認值是10

類加載器

class加載過程

加載-->鏈接(驗證,準備,解析)-->初始化

加載:讀取二進制文件,轉換爲方法區數據結構,在java堆生成對應的Class對象

鏈接:驗證–>驗證class文件格式(class文件以0xcafebabe開頭),版本號是否合理,驗證元數據(語法語義校驗),字節碼檢查,符號引用驗證(訪問方法的權限,屬性類是否存在等)

        準備-->分配內存,併爲類設置初始值

        解析-->將符號引用替換爲直接引用(符號替換爲真實內存地址)

初始化:執行類構造器(ClassInit),賦值static變量(final變量除外)和執行靜態代碼塊,子類初始化之前保證父類先初始化,ClassInit是線程安全的

ClassLoader

抽象類,負責類裝載過程中的加載階段,將java字節碼裝載到jvm中,可以定製,滿足不同的字節碼流獲取方式

重要方法loadClass(載入並返回一個Class)、defineClass(定義一個類,不公開調用)、findClass(loadClass回調該方法,自定義時推薦重載該方法)、findLoadedClass(尋找已經加載的類)

幾種類加載器:啓動加載(Bootstrap ClassLoader)、擴展加載(Extension ClassLoader)、應用加載(App ClassLoader)、自定義加載(Custom ClassLoader)

除了Bootstrap外每個ClassLoader都有一個parents父類(雙親委派)

默認加載方式:自底向上檢查是否已加載(Bootstrap爲最上方),然後自頂向下加載類

-Xbootclasspath/a:D:/tmp/clz_dir
//指定bootstrap加載器的附加加載目錄

//上下文加載器,是一個角色,用以解決頂層ClassLoader無法訪問底層ClassLoader的類的問題,原理是在頂層ClassLoader中傳入底層ClassLoader的實例
Thread.setContextClassLoader()

雙親模式是默認的,但不是必須這麼做,如tomcat的WebAPPClassLoader就會先加載自己的class,找不到再委託parent,而不是先委託parent加載

性能監控工具

uptime(linux):系統運行時間,連接數,系統在1,5,15分鐘內的平均負載

top(linux):cpu,內存使用情況

vmstat(linux):統計cpu,內存,swap(上下文切換),io等情況

pidstat(linux):(需要安裝 sysstat)細緻觀察進程,監控cpu,io,mem,可以顯示進程中的線程信息(-t參數)

perfmon(win):windows性能監控工具

process Explorer(win):系統性能監控,查看線程運行情況

pslist(win cmd):(需要安裝)顯示java程序的運行情況

//java 自帶的監控工具
jdb            java調試工具
jhat           分析java堆
jinfo          查看正在運行的java程序的參數,支持運行時修改部分參數,-flag <name>(打印指定jvm參數值)
jmap           生成java程序的堆快照和對象的統計信息,-histo,-dump
jps            列出java進程,-q(只輸出pid),-m(輸出主函數參數),-l(主函數完整路徑),-v(顯示傳遞給jvm的參數)
jrunscript 		一個命令行腳本外殼
jstack         打印線程dump,-l(打印鎖信息),-m(打印java和native的幀信息),-F(強制dump,當jstack沒有響應時使用)

jstat			查看堆內存各部分的使用量,以及加載類的數量
jstatd		用於監控基於HotSpot的JVM中資源的創建及銷燬
jConsole       圖形化工具,查看java程序運行情況,監控堆信息,永久區使用情況,類加載情況等
jvisualvm      多合一的可視化監控工具,可以分析堆信息

jvm堆分析

內存溢出的原因

jvm內存中的內存區間:堆,永久區,線程棧,直接內存

堆溢出:佔用大量堆空間,直接溢出(解決:增大堆空間或及時釋放內存)

永久區溢出:大量的類信息導致(增大perm區,允許class回收)

棧溢出:操作系統無法爲線程分配棧空間,即超過一定的線程數(每個線程獨立分配一塊空間),導致內存不足(解決:減少堆內存,減少線程棧大小)

直接內存溢出:操作系統無法獲得足夠空間,外部內存超過系統可用內存(解決:減少堆內存,有意觸發gc)

MAT軟件(堆分析軟件)

eclipse下的軟件,可在eclipse官網下載

淺堆:一個對象結構所佔用的內存大小,與對象內容無關,只與對象結構有關

深堆:一個對象被gc回收後,可以真實釋放的內存大小,即可以通過對象訪問到的所有對象的淺堆之和

線程安全

使用鎖維護程序的串行訪問和安全性

對象頭mark

對象頭標記,32位

描述對象的hash,鎖信息,垃圾回收標記,年齡

偏向鎖

大部分情況是沒有競爭的,所以可以通過偏向來提高性能,鎖會偏向當前已經佔有鎖的線程,將對象頭的mark標記置爲偏向,並寫入線程id,只要沒有競爭,獲得偏向鎖的線程在將來進入同步塊時不需要做同步,當其他線程請求相同的鎖時,偏向模式結束,在競爭激烈的場合,偏向鎖會增加系統負擔

-XX:+UseBiasedLocking  //1.6之後默認啓用
-XX:BiasedLockingStartupDelay //設置偏向鎖在程序啓動後的延遲時間,偏向鎖在系統啓動不會立馬啓用
輕量級鎖

BasicObjectLock

輕量級鎖是一種快速的鎖定方法,如果對象沒有被鎖定,將對象頭的mark指針保存到鎖對象中,將對象頭設置爲指向鎖的指針(在線程棧中),如果存在競爭,則升級爲重量級鎖

自旋鎖

當競爭存在時,如果線程可以很快獲得鎖,那麼可以不在系統層掛起線程,讓線程做幾個空操作,1.7之後爲默認啓用,如果同步塊很長,自旋失敗,會降低系統性能,如果同步塊很短,自旋成功,會節省系統切換時間

鎖的優化

減少鎖的持有時間:縮小同步塊,儘量不同步整個方法

減小鎖粒度:將大對象拆成小對象,如ConcurrentHashMap,將table分爲多個segment進行操作

鎖分離:根據功能進行鎖分離,如讀寫鎖

鎖粗化:對統一鎖多次請求,同步,釋放,可以將鎖放大化,增加鎖範圍

鎖消除:如果發現不可能被共享的對象,則可以消除這些對象的鎖操作(-XX:+DoEscapeAnalysis(逃逸分析) -XX:+EliminateLocks(粗化鎖區域))

無鎖:無鎖是樂觀的操作,再應用層面判斷多線程的干擾,如果有干擾,則重試,無鎖的實現(cas(比較交換指令)),如atomic包下的類

Class文件結構

語言無關性

各種jvm語言都可以編譯成class文件,運行在jvm上,並不是只有java語言,即java語言和jvm是兩個分離的部分

class文件結構

u1/u2/u4表示無符號整型以及佔用的字節數,文件結構如下

類型 名稱 數量 說明
u4 magic 1 魔數
u2 minor_version 1 小版本
u2 major_version 1 大版本
u2 const_pool_count 1 常量數
cp_info const_pool const_pool_count-1 常量
u2 access_flag 1 訪問修飾符
u2 this_class 1 當前類,指向常量池的Class
u2 super_class 1 父類,指向常量池的Class
u2 interface_count 1 接口數量
u2 interfaces interface_count 接口,指向常量池的Class
u2 field_count 1 字段數量
field_info fileds field_count 字段
u2 method_count 1 方法數量
method_info methods method_count 方法
u2 attr_count 1 屬性數量
attr_info attrs attr_count 屬性

魔數magic:class文件魔數爲 0xCAFEBABE

minor.major:java編譯版本

常量池:支持的常用類型 (1)指向utf8的索引 (2)指向class的索引 (3)指向NameAndType的索引

描述 類型 結構
utf-8編碼的Unicode字符串 utf8 tag 1,length u2,byte len
int類型的字面值 Integer tag 3,byte u4
float類型的字面值 Float tag 4
long類型的字面值 Long tag 5
double類型的字面值 Double tag 6
對一個類或接口的符號引用 Class tag 7,name_index u2(1)
string類型字面值的引用 String tag 8,string_index u2(1)
對一個字段的符號引用 Fieldref tag 9,class_index u2(2),nameandtype_index u2(3)
對一個類中方法的符號引用 Methodref tag 10,class_index u2(2),nameandtype_index u2(3)
對一個接口中方法的符號引用 InterfaceMethodref tag 11,class_index u2(2),nameandtype_index u2(3)
對一個字段或方法的部分符號引用 NameAndType tag 12,name_index u2(1),desc_index u2(1)

類的標識符

標識 value 說明
ACC_PUBLIC 0x0001 public
ACC_FINAL 0x0010 final 不能被繼承
ACC_SUPER 0x0020 是否允許使用invokespecial指令,1.2後爲true
ACC_INTERFACE 0x0200 是否爲接口
ACC_ABSTRACT 0x0400 抽象類
ACC_SYNTHETIC 0x1000 不是由用戶代碼生成,運行時生成,沒有源碼
ACC_ANNOTATION 0x2000 是否爲註解
ACC_ENUM 0x4000 是否是枚舉

字段標識符:access_flag

標識 value 描述
ACC_PUBLIC 0x0001 public
ACC_PRIVATE 0x0002 private
ACC_PROTECTED 0x0004 protected
ACC_STATIC 0x0008 static
ACC_FINAL 0x0010 final
ACC_VOLATILE 0x0040 volatile
ACC_TRANSIENT 0x0080 transient
ACC_SYNTHETIC 0x1000 synthetic;沒有源碼,編譯器生成
ACC_ENUM 0x4000 enum枚舉類型

字段:常量池引用,表示字段的名字 name_index u2,descriptor_index u2

標識 類型
B byte
C char
D double
F float
I int
J long
S short
Z boolean
V void
L 對象 – Ljava/lang/Object
[ 數組 – [Ljava/lang/String

方法標識符:指向常量池的索引,方法描述 (args)return 如: (I)V 爲 參數爲int返回值空,name_index u2,descriptor_index u2

標識 value 描述
ACC_PUBLIC 0x0001 public
ACC_PRIVATE 0x0002 private
ACC_PROTECTED 0x0004 protected
ACC_STATIC 0x0008 static
ACC_FINAL 0x0010 final
ACC_SYNCHRONIZED 0x0020 synchronized
ACC_BRIDGE 0x0040 編譯器產生,橋接方法
ACC_VARARGS 0x0080 可變參數
ACC_NATIVE 0x0100 native
ACC_ABSTRACT 0x0400 abstract
ACC_STRICT 0x0800 strictfp
ACC_SYNTHETIC 0x1000 不在源碼中,編譯器生成

文件屬性:在field和method中,可以有若干個attr,類文件也有attr用於描述一些額外的信息,attr本身也可以包含其他的attr

attribute_name_index u2 名字,指向常量池utf8

attribute_length u4 長度

info【attribute_length】 u1 內容

名稱 使用者 說明
Deprecated field method 字段、方法、類被廢棄,attribute_length=0
ConstantValue field final常量,attribute_length=2,constantvalue_index u2指向常量池
Code method 方法的字節碼和其他數據
Exceptions method 方法的異常
LineNumberTable Code_Attribute 方法行號和字節碼映射
LocalVaribleTable Code_Attribute 方法局部變量表描述
SourceFile Class file 源文件名,attribute_length=2
Synthetic field method 編譯器產生的方法或字段

feild_info

–access_flags u2

–name_index u2

–descriptor_index u2

–attributes_count u2

–attribute_info  attributes [attributes_count];

method_info

–access_flags  u2

–name_index  u2

–descriptor_index u2

–attributes_count  u2

–attribute_info  attributes [attributes_count];

sourceFile

–attribute_name_index u2

–attribute_length u4(固定爲2)

–soucefile_index u2(UTF-8常量索引)

exception

–attribute_name_index  u2

–attribute_length  u4

–number_of_exceptions  u2

–exception_index_table [number_of_exceptions] u2(指向Constant_Class的索引)

LocalVariableTable

LocalVariableTable_attribute {

	u2 attribute_name_index;
	
	u4 attribute_length;
	
	u2 local_variable_table_length;
	
	{ 
		u2 start_pc;
		
		u2 length;
		
		u2 name_index;
		
		u2 descriptor_index;
		
		u2 index;
	
	} local_variable_table [local_variable_table_length];

}

LineNumberTable

LineNumberTable_attribute {

	u2 attribute_name_index;
	
	u4 attribute_length;
	
	u2 line_number_table_length;
	
	{ 
		u2 start_pc;
		
		u2 line_number;
	
	} line_number_table [line_number_table_length];

}

code

Code_attribute {

	u2 attribute_name_index;
	
	u4 attribute_length;
	
	u2 max_stack;
	
	u2 max_locals;
	
	u4 code_length;
	
	 u1 code [code_length];
	
	u2 exception_table_length;
	
	{ 
		u2 start_pc;
		
		u2 end_pc;
		
		u2 handler_pc;
		
		u2 catch_type;
	
	} exception_table [exception_table_length];
	
	u2 attributes_count;
	
	attribute_info attributes [attributes_count];

}

字節碼的執行

javap //JDK自帶的反彙編器

jit:just in time 將執行比較頻繁的代碼編譯成機器碼,-XX:CompileThreshold=100(設定jit閾值),-XX:+PrintCompilation(打印編譯信息)


其他說明

(1)dump:在特定時刻,將整個儲存裝置或儲存裝置之某部分的內容記錄在另一儲存裝置中

(2)新生代GC(Minor GC):指發生在新生代的垃圾收集動作,因爲Java對象大多都具備朝生夕滅的特性,所以Minor GC非常頻繁,一般回收速度也比較快

(3)老年代GC(Major GC / Full GC):指發生在老年代的GC,出現了Major GC,經常會伴隨至少一次的Minor GC(但非絕對的,在Parallel Scavenge收集器的收集策略裏就有直接進行Major GC的策略選擇過程)。Major GC的速度一般會比Minor GC慢10倍以上。

(4)吞吐量:吞吐量就是CPU用於運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量 = 運行用戶代碼時間 /(運行用戶代碼時間 + 垃圾收集時間)。

(5)Region:G1默認把堆內存分爲1024個分區,後續垃圾收集的單位都是以Region爲單位的。Region是實現G1算法的基礎,每個Region的大小相等,通過-XX:G1HeapRegionSize參數可以設置Region的大小。

同類文章 https://www.cnblogs.com/yxwkf/p/5222589.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章