1.運行時數(shù)據(jù)區(qū)域
1.1 程序計數(shù)器
當(dāng)前線程執(zhí)行的字節(jié)碼的行號指示器击喂,占用空間小,也無法干涉
1.2 虛擬機棧
每個線程私有的碰辅,線程在運行時懂昂,在執(zhí)行每個方法的時候都會打包成一個棧幀,存儲了局部變量表没宾,操作數(shù)棧凌彬,動態(tài)鏈接,方法出口等信息循衰,然后放入棧铲敛。每個時刻正在執(zhí)行的當(dāng)前方法就是虛擬機棧頂?shù)臈E。方法的執(zhí)行就對應(yīng)著棧幀在虛擬機棧中入棧和出棧的過程会钝。
棧楨大小缺省為1M伐蒋,可用參數(shù) –Xss調(diào)整大小,例如-Xss256k
1.3 本地方法棧
本地方法棧保存的是native方法的信息迁酸,當(dāng)一個JVM創(chuàng)建的線程調(diào)用native方法后先鱼,JVM不再為其在虛擬機中創(chuàng)建棧幀,JVM只是簡單地動態(tài)鏈接并直接調(diào)用native方法奸鬓。
1.4 堆
幾乎所有對象都分配在這里焙畔,也是垃圾回收發(fā)生的主要區(qū)域,可用以下參數(shù)調(diào)整:
-Xms:堆的最小值串远;
-Xmx:堆的最大值宏多;
-Xmn:新生代的大小抑淫;
-XX:NewSize绷落;新生代最小值;
-XX:MaxNewSize:新生代最大值始苇;
例如- Xmx256m
1.5 方法區(qū)/永久代
用于存儲已經(jīng)被虛擬機加載的類信息砌烁,常量("zdy","123"等),靜態(tài)變量(static變量)等數(shù)據(jù)催式,可用以下參數(shù)調(diào)整:
jdk1.7及以前:-XX:PermSize函喉;-XX:MaxPermSize益愈;
jdk1.8以后:-XX:MetaspaceSize取董; -XX:MaxMetaspaceSize
jdk1.8以后大小就只受本機總內(nèi)存的限制
如:-XX:MaxMetaspaceSize=3M
1.6 直接內(nèi)存
不是虛擬機運行時數(shù)據(jù)區(qū)的一部分,也不是java虛擬機規(guī)范中定義的內(nèi)存區(qū)域唤殴;如果使用了NIO,這塊區(qū)域會被頻繁使用哺窄,在java堆內(nèi)可以用directByteBuffer對象直接引用并操作捐下;
這塊內(nèi)存不受java堆大小限制账锹,但受本機總內(nèi)存的限制,可以通過-XX:MaxDirectMemorySize來設(shè)置(默認與堆內(nèi)存最大值一樣)坷襟,所以也會出現(xiàn)OOM異常奸柬。
2.各個版本內(nèi)存區(qū)域的變化
3.站在線程角度來看
3.1 深入辨析堆和棧
功能
- 以棧幀的方式存儲方法調(diào)用的過程,并存儲方法調(diào)用過程中基本數(shù)據(jù)類型的變量(int婴程、short廓奕、long、byte档叔、float桌粉、double、boolean衙四、char等)以及對象的引用變量铃肯,其內(nèi)存分配在棧上,變量出了作用域就會自動釋放届搁;
- 而堆內(nèi)存用來存儲Java中的對象缘薛。無論是成員變量,局部變量卡睦,還是類變量宴胧,它們指向的對象都存儲在堆內(nèi)存中;
線程獨享還是共享
- 棧內(nèi)存歸屬于單個線程表锻,每個線程都會有一個棧內(nèi)存恕齐,其存儲的變量只能在其所屬線程中可見,即棧內(nèi)存可以理解成線程的私有內(nèi)存瞬逊。
- 堆內(nèi)存中的對象對所有線程可見显歧。堆內(nèi)存中的對象可以被所有線程訪問。
空間大小
- 棧的內(nèi)存要遠遠小于堆內(nèi)存
3.2 方法的出入棧
-
方法會打包成棧幀确镊,一個棧幀包括局部變量表士骤、操作數(shù)和幀數(shù)據(jù)區(qū)等
3.3 棧上分配
虛擬機提供的一種優(yōu)化技術(shù),基本思想是蕾域,對于線程私有的對象拷肌,將它打散分配在棧上,而不分配在堆上旨巷。好處是對象跟著方法調(diào)用自行銷毀巨缘,不需要進行垃圾回收,可以提高性能采呐。
棧上分配需要的技術(shù)基礎(chǔ)若锁,逃逸分析。逃逸分析的目的是判斷對象的作用域是否會逃逸出方法體斧吐。注意又固,任何可以在多個線程之間共享的對象仲器,一定都屬于逃逸對象。
public void test(int x,inty ){
String x = “”;
User u = ….
…
}
User類型的對象u就沒有逃逸出方法test仰冠。
public User test(int x,inty ){
String x = “”;
User u = …
…
return u;
}
User類型的對象u就逃逸出方法test娄周。
啟用棧上分配
-server JVM運行的模式之一, server模式才能進行逃逸分析, JVM運行的模式還有mix/client
-Xmx10m和-Xms10m:堆的大小
-XX:+DoEscapeAnalysis:啟用逃逸分析(默認打開)
-XX:+PrintGC:打印GC日志沪停;這個改為了-Xlog:gc
-XX:+EliminateAllocations:標(biāo)量替換(默認打開)
-XX:-UseTLAB 關(guān)閉本地線程分配緩沖
TLAB: ThreadLocalAllocBuffer
對棧上分配發(fā)生影響的參數(shù)就是三個,-server裳涛、-XX:+DoEscapeAnalysis和-XX:+EliminateAllocations木张,任何一個發(fā)生變化都不會發(fā)生棧上分配,因為啟用逃逸分析和標(biāo)量替換默認是打開的端三,所以舷礼,在我們的例子中,JVM的參數(shù)只用-server一樣可以有棧上替換的效果-
啟用棧上分配
-
不啟用棧上分配
4.虛擬機中的對象
4.1 對象的分配
虛擬機遇到一條new指令時:
step1 先執(zhí)行相應(yīng)的類加載過程郊闯。
step2 接下來虛擬機將為新生對象分配內(nèi)存妻献。為對象分配空間的任務(wù)等同于把一塊確定大小的內(nèi)存從Java堆中劃分出來。
如果Java堆中內(nèi)存是絕對規(guī)整的团赁,所有用過的內(nèi)存都放在一邊育拨,空閑的內(nèi)存放在另一邊,中間放著一個指針作為分界點的指示器欢摄,那所分配內(nèi)存就僅僅是把那個指針向空閑空間那邊挪動一段與對象大小相等的距離熬丧,這種分配方式稱為“指針碰撞”。
如果Java堆中的內(nèi)存并不是規(guī)整的怀挠,已使用的內(nèi)存和空閑的內(nèi)存相互交錯析蝴,那就沒有辦法簡單地進行指針碰撞了,虛擬機就必須維護一個列表绿淋,記錄上哪些內(nèi)存塊是可用的闷畸,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄吞滞,這種分配方式稱為“空閑列表”佑菩。
選擇哪種分配方式由Java堆是否規(guī)整決定,而Java堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定冯吓。
除如何劃分可用空間之外倘待,還有另外一個需要考慮的問題是對象創(chuàng)建在虛擬機中是非常頻繁的行為,即使是僅僅修改一個指針?biāo)赶虻奈恢米楹兀诓l(fā)情況下也并不是線程安全的凸舵,可能出現(xiàn)正在給對象A分配內(nèi)存,指針還沒來得及修改失尖,對象B又同時使用了原來的指針來分配內(nèi)存的情況啊奄。
解決這個問題有兩種方案渐苏,一種是對分配內(nèi)存空間的動作進行同步處理——實際上虛擬機采用CAS配上失敗重試的方式保證更新操作的原子性;
另一種是把內(nèi)存分配的動作按照線程劃分在不同的空間之中進行菇夸,即每個線程在Java堆中預(yù)先分配一小塊私有內(nèi)存琼富,也就是本地線程分配緩沖(Thread Local Allocation Buffer,TLAB),如果設(shè)置了虛擬機參數(shù) -XX:UseTLAB庄新,在線程初始化時鞠眉,同時也會申請一塊指定大小的內(nèi)存,只給當(dāng)前線程使用择诈,這樣每個線程都單獨擁有一個Buffer械蹋,如果需要分配內(nèi)存,就在自己的Buffer上分配羞芍,這樣就不存在競爭的情況哗戈,可以大大提升分配效率,當(dāng)Buffer容量不夠的時候荷科,再重新從Eden區(qū)域申請一塊繼續(xù)使用唯咬。
TLAB的目的是在為新對象分配內(nèi)存空間時,讓每個Java應(yīng)用線程能在使用自己專屬的分配指針來分配空間畏浆,減少同步開銷胆胰。
TLAB只是讓每個線程有私有的分配指針,但底下存對象的內(nèi)存空間還是給所有線程訪問的全度,只是其它線程無法在這個區(qū)域分配而已煮剧。當(dāng)一個TLAB用滿(分配指針top撞上分配極限end了),就新申請一個TLAB将鸵。step3 內(nèi)存分配完成后勉盅,虛擬機需要將分配到的內(nèi)存空間都初始化為零值(如int值為0,boolean值為false等等)顶掉。這一步操作保證了對象的實例字段在Java代碼中可以不賦初始值就直接使用草娜,程序能訪問到這些字段的數(shù)據(jù)類型所對應(yīng)的零值。
step4 接下來痒筒,虛擬機要對對象進行必要的設(shè)置宰闰,例如這個對象是哪個類的實例、如何才能找到類的元數(shù)據(jù)信息簿透、對象的哈希碼移袍、對象的GC分代年齡等信息。這些信息存放在對象的對象頭之中老充。
step5 在上面工作都完成之后葡盗,從虛擬機的視角來看,一個新的對象已經(jīng)產(chǎn)生了啡浊,但從Java程序的視角來看觅够,對象創(chuàng)建才剛剛開始胶背,所有的字段都還為零值。所以喘先,一般來說钳吟,執(zhí)行new指令之后會接著把對象按照程序員的意愿進行初始化,這樣一個真正可用的對象才算完全產(chǎn)生出來窘拯。
4.2 對象的內(nèi)存布局
在HotSpot虛擬機中红且,對象在內(nèi)存中存儲的布局可以分為3塊區(qū)域:對象頭(Header)、實例數(shù)據(jù)(Instance Data)和對齊填充(Padding)涤姊。
對象頭包括兩部分信息:
- 第一部分用于存儲對象自身的運行時數(shù)據(jù)直焙,如哈希碼(HashCode)、GC分代年齡砂轻、鎖狀態(tài)標(biāo)志、線程持有的鎖斤吐、偏向線程ID搔涝、偏向時間戳等。
對象頭的另外一部分是類型指針和措,即對象指向它的類元數(shù)據(jù)的指針庄呈,虛擬機通過這個指針來確定這個對象是哪個類的實例。 - 第三部分對齊填充并不是必然存在的派阱,也沒有特別的含義诬留,它僅僅起著占位符的作用。由于HotSpot VM的自動內(nèi)存管理系統(tǒng)要求對對象的大小必須是8字節(jié)的整數(shù)倍贫母。當(dāng)對象其他數(shù)據(jù)部分沒有對齊時文兑,就需要通過對齊填充來補全。
4.3 對象的定位訪問
建立對象是為了使用對象腺劣,我們的Java程序需要通過棧上的reference數(shù)據(jù)來操作堆上的具體對象绿贞。目前主流的訪問方式有使用句柄和直接指針兩種。
如果使用句柄訪問的話橘原,那么Java堆中將會劃分出一塊內(nèi)存來作為句柄池籍铁,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數(shù)據(jù)與類型數(shù)據(jù)各自的具體地址信息趾断。
如果使用直接指針訪問拒名, reference中存儲的直接就是對象地址。這兩種對象訪問方式各有優(yōu)勢芋酌,使用句柄來訪問的最大好處就是reference中存儲的是穩(wěn)定的句柄地址增显,在對象被移動(垃圾收集時移動對象是非常普遍的行為)時只會改變句柄中的實例數(shù)據(jù)指針,而reference本身不需要修改隔嫡。
使用直接指針訪問方式的最大好處就是速度更快甸怕,它節(jié)省了一次指針定位的時間開銷甘穿,由于對象的訪問在Java中非常頻繁,因此這類開銷積少成多后也是一項非成液迹可觀的執(zhí)行成本温兼。對Sun HotSpot而言,它是使用直接指針訪問方式進行對象訪問的武契。
5.堆參數(shù)設(shè)置募判、對性能的影響和內(nèi)存溢出實戰(zhàn)
5.1 堆溢出
出現(xiàn)java.lang.OutOfMemoryError: GC overhead limit exceeded 一般是(某個循環(huán)里可能性最大)在不停的分配對象,但是分配的太多咒唆,把堆撐爆了届垫。
出現(xiàn)java.lang.OutOfMemoryError: Java heap space一般是分配了巨型對象
- 不停分配對象,逐漸累加
測試代碼參考OOM.java
參數(shù) : -Xms5m -Xmx5m -Xlog:gc
List<Object> list = new LinkedList<>();
int i=0;
while(true) {
i++;
if(i%10000==0) System.out.println("i="+i);
list.add(new Object());
}
[0.016s][info][gc] Using G1
[0.124s][info][gc] GC(0) Pause Young (G1 Evacuation Pause) 2M->1M(6M) 1.186ms
[0.159s][info][gc] GC(1) Pause Young (G1 Evacuation Pause) 2M->2M(6M) 1.812ms
i=10000
i=20000
[0.173s][info][gc] GC(2) Pause Young (G1 Evacuation Pause) 3M->2M(6M) 4.282ms
i=30000
i=40000
i=50000
[0.186s][info][gc] GC(3) Pause Young (G1 Evacuation Pause) 3M->3M(6M) 5.562ms
i=60000
i=70000
i=80000
[0.197s][info][gc] GC(4) To-space exhausted
[0.197s][info][gc] GC(4) Pause Initial Mark (G1 Evacuation Pause) 4M->6M(6M) 9.169ms
[0.197s][info][gc] GC(5) Concurrent Cycle
[0.205s][info][gc] GC(6) To-space exhausted
[0.205s][info][gc] GC(6) Pause Young (G1 Evacuation Pause) 6M->6M(6M) 7.298ms
[0.213s][info][gc] GC(7) Pause Full (Allocation Failure) 6M->4M(6M) 7.560ms
[0.213s][info][gc] GC(5) Concurrent Cycle 15.794ms
i=90000
i=100000
[0.220s][info][gc] GC(8) To-space exhausted
[0.220s][info][gc] GC(8) Pause Young (G1 Evacuation Pause) 5M->5M(6M) 6.307ms
[0.220s][info][gc] GC(9) Pause Initial Mark (G1 Evacuation Pause) 5M->5M(6M) 0.258ms
[0.220s][info][gc] GC(10) Concurrent Cycle
[0.233s][info][gc] GC(11) Pause Full (Allocation Failure) 5M->5M(6M) 12.788ms
[0.252s][info][gc] GC(12) Pause Full (Allocation Failure) 5M->5M(6M) 18.872ms
[0.253s][info][gc] GC(10) Concurrent Cycle 32.273ms
[0.253s][info][gc] GC(13) Pause Young (G1 Evacuation Pause) 5M->5M(6M) 0.368ms
[0.253s][info][gc] GC(14) Pause Initial Mark (G1 Evacuation Pause) 5M->5M(6M) 0.170ms
[0.253s][info][gc] GC(15) Concurrent Cycle
[0.256s][info][gc] GC(16) Pause Full (Allocation Failure) 5M->1M(6M) 2.667ms
[0.256s][info][gc] GC(15) Concurrent Cycle 2.794ms
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.wz.ch1.OOM.main(OOM.java:22)
Process finished with exit code 1
- 一次性申請大對象
測試代碼參考OOM.java
參數(shù) : -Xms5m -Xmx5m -Xlog:gc
String[] strings = new String[100000000];
[0.019s][info][gc] Using G1
[0.123s][info][gc] GC(0) Pause Young (G1 Evacuation Pause) 2M->1M(6M) 1.361ms
[0.143s][info][gc] GC(1) Pause Initial Mark (G1 Humongous Allocation) 1M->1M(6M) 3.665ms
[0.143s][info][gc] GC(2) Concurrent Cycle
[0.143s][info][gc] GC(3) Pause Young (G1 Humongous Allocation) 1M->1M(6M) 0.277ms
[0.146s][info][gc] GC(4) Pause Full (Allocation Failure) 1M->1M(6M) 2.558ms
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.wz.ch1.OOM.main(OOM.java:25)
[0.148s][info][gc] GC(5) Pause Full (Allocation Failure) 1M->1M(6M) 2.282ms
[0.149s][info][gc] GC(2) Concurrent Cycle 6.141ms
Process finished with exit code 1
5.2 虛擬機棧和本地方法棧溢出
參數(shù):-Xss256k
java.lang.StackOverflowError 一般的方法調(diào)用是很難出現(xiàn)的全释,如果出現(xiàn)了要考慮是否有無限遞歸装处。
虛擬機棧帶給我們的啟示:方法的執(zhí)行因為要打包成棧楨,所以天生要比實現(xiàn)同樣功能的循環(huán)慢浸船,所以樹的遍歷算法中:遞歸和非遞歸(循環(huán)來實現(xiàn))都有存在的意義妄迁。遞歸代碼簡潔,非遞歸代碼復(fù)雜但是速度較快李命。
- 無線遞歸導(dǎo)致棧溢出
測試代碼參考StackOOM.java
private void diGui(int x,String y) {
stackLength++;
diGui(x,y);
}
stackLength = 16408
java.lang.StackOverflowError
at com.wz.ch1.StackOOM.diGui(StackOOM.java:14)
at com.wz.ch1.StackOOM.diGui(StackOOM.java:14)
at com.wz.ch1.StackOOM.diGui(StackOOM.java:14)
at com.wz.ch1.StackOOM.diGui(StackOOM.java:14)
at com.wz.ch1.StackOOM.diGui(StackOOM.java:14)
at com.wz.ch1.StackOOM.diGui(StackOOM.java:14)
5.3 本機直接內(nèi)存溢出
-Xmx10M -XX:MaxDirectMemorySize=10M
測試程序參考DirectMem.java
ByteBuffer b = ByteBuffer.allocateDirect(1024*1024*14);
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.base/java.nio.Bits.reserveMemory(Bits.java:187)
at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:310)
at com.wz.ch1.DirectMem.main(DirectMem.java:14)
Process finished with exit code 1
5.4 Metaspace溢出(老版本:方法區(qū)和運行時常量池溢出)
-XX:MaxMetaspaceSize=3M
public class MetaSpace {
public static void main(String[] args) {
List<Object> list = new LinkedList<>();
int i=0;
while(true) {
i++;
if(i%10000==0) System.out.println("i="+i);
list.add(new Object());
}
}
}
Error occurred during initialization of VM
MaxMetaspaceSize is too small.
Process finished with exit code 1
5.5 新生代配置
新生代配置代碼請參考NewSize.java
新生代大小配置參數(shù)的優(yōu)先級:
高:-XX:NewSize/MaxNewSize
中間 -Xmn (NewSize= MaxNewSize)
低:-XX:NewRatio 表示比例登淘,例如=2,表示 新生代:老年代 = 1:2
-XX:SurvivorRatio 表示Eden和Survivor的比值封字,
缺省為8 表示 Eden:FromSurvivor:ToSurvivor= 8:1:1
同樣的代碼情況下:
-Xms20M -Xmx20M -XX:+PrintGCDetails –Xmn2m -XX:SurvivorRatio=2
jdk1.10改為:-XX:+UseParallelGC -Xms20M -Xmx20M -Xlog:gc* -Xmn2m -XX:SurvivorRatio=2
沒有垃圾回收(我的電腦上是發(fā)生了垃圾回收G荨)
數(shù)組都在老年代
[0.003s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
[0.014s][info ][gc] Using Parallel
[0.015s][info ][gc,heap,coops] Heap address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit
[0.066s][info ][gc,start ] GC(0) Pause Young (Allocation Failure)
[0.075s][info ][gc,heap ] GC(0) PSYoungGen: 1024K->488K(1536K)
[0.075s][info ][gc,heap ] GC(0) ParOldGen: 0K->240K(18432K)
[0.075s][info ][gc,metaspace ] GC(0) Metaspace: 3243K->3243K(1056768K)
[0.075s][info ][gc ] GC(0) Pause Young (Allocation Failure) 1M->0M(19M) 8.809ms
[0.075s][info ][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.01s
[0.120s][info ][gc,start ] GC(1) Pause Young (Allocation Failure)
[0.121s][info ][gc,heap ] GC(1) PSYoungGen: 1506K->496K(1536K)
[0.121s][info ][gc,heap ] GC(1) ParOldGen: 240K->757K(18432K)
[0.121s][info ][gc,metaspace ] GC(1) Metaspace: 4624K->4624K(1056768K)
[0.121s][info ][gc ] GC(1) Pause Young (Allocation Failure) 1M->1M(19M) 1.363ms
[0.121s][info ][gc,cpu ] GC(1) User=0.00s Sys=0.00s Real=0.00s
[0.138s][info ][gc,heap,exit ] Heap
[0.138s][info ][gc,heap,exit ] PSYoungGen total 1536K, used 833K [0x00000000ffe00000, 0x0000000100000000, 0x0000000100000000)
[0.138s][info ][gc,heap,exit ] eden space 1024K, 32% used [0x00000000ffe00000,0x00000000ffe544f0,0x00000000fff00000)
[0.138s][info ][gc,heap,exit ] from space 512K, 97% used [0x00000000fff80000,0x00000000ffffc2b0,0x0000000100000000)
[0.138s][info ][gc,heap,exit ] to space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
[0.138s][info ][gc,heap,exit ] ParOldGen total 18432K, used 10997K [0x00000000fec00000, 0x00000000ffe00000, 0x00000000ffe00000)
[0.138s][info ][gc,heap,exit ] object space 18432K, 59% used [0x00000000fec00000,0x00000000ff6bd4a0,0x00000000ffe00000)
[0.138s][info ][gc,heap,exit ] Metaspace used 5438K, capacity 5512K, committed 5632K, reserved 1056768K
[0.138s][info ][gc,heap,exit ] class space used 463K, capacity 492K, committed 512K, reserved 1048576K
Process finished with exit code 0
-Xms20M -Xmx20M -XX:+PrintGCDetails -Xmn7m -XX:SurvivorRatio=2
jdk1.10改為:-XX:+UseParallelGC -Xms20M -Xmx20M -Xlog:gc* -Xmn7m -XX:SurvivorRatio=2
發(fā)生了垃圾回收
新生代存了部分?jǐn)?shù)組,老年代也保存了部分?jǐn)?shù)組阔籽,發(fā)生了晉升現(xiàn)象
[0.016s][info][gc] Using Parallel
[0.016s][info][gc,heap,coops] Heap address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit
[0.125s][info][gc,start ] GC(0) Pause Young (Allocation Failure)
[0.127s][info][gc,heap ] GC(0) PSYoungGen: 3492K->1525K(5632K)
[0.127s][info][gc,heap ] GC(0) ParOldGen: 0K->1032K(13312K)
[0.127s][info][gc,metaspace ] GC(0) Metaspace: 5392K->5392K(1056768K)
[0.127s][info][gc ] GC(0) Pause Young (Allocation Failure) 3M->2M(18M) 1.719ms
[0.127s][info][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s
[0.127s][info][gc,start ] GC(1) Pause Young (Allocation Failure)
[0.135s][info][gc,heap ] GC(1) PSYoungGen: 4716K->1504K(5632K)
[0.135s][info][gc,heap ] GC(1) ParOldGen: 1032K->4062K(13312K)
[0.135s][info][gc,metaspace ] GC(1) Metaspace: 5393K->5393K(1056768K)
[0.135s][info][gc ] GC(1) Pause Young (Allocation Failure) 5M->5M(18M) 7.613ms
[0.135s][info][gc,cpu ] GC(1) User=0.05s Sys=0.00s Real=0.01s
[0.135s][info][gc,start ] GC(2) Pause Young (Allocation Failure)
[0.139s][info][gc,heap ] GC(2) PSYoungGen: 4672K->1520K(5632K)
[0.139s][info][gc,heap ] GC(2) ParOldGen: 4062K->7134K(13312K)
[0.139s][info][gc,metaspace ] GC(2) Metaspace: 5393K->5393K(1056768K)
[0.139s][info][gc ] GC(2) Pause Young (Allocation Failure) 8M->8M(18M) 3.505ms
[0.139s][info][gc,cpu ] GC(2) User=0.00s Sys=0.00s Real=0.00s
[0.142s][info][gc,heap,exit ] Heap
[0.142s][info][gc,heap,exit ] PSYoungGen total 5632K, used 4725K [0x00000000ff900000, 0x0000000100000000, 0x0000000100000000)
[0.142s][info][gc,heap,exit ] eden space 4096K, 78% used [0x00000000ff900000,0x00000000ffc21048,0x00000000ffd00000)
[0.142s][info][gc,heap,exit ] from space 1536K, 99% used [0x00000000ffd00000,0x00000000ffe7c3f0,0x00000000ffe80000)
[0.142s][info][gc,heap,exit ] to space 1536K, 0% used [0x00000000ffe80000,0x00000000ffe80000,0x0000000100000000)
[0.142s][info][gc,heap,exit ] ParOldGen total 13312K, used 7134K [0x00000000fec00000, 0x00000000ff900000, 0x00000000ff900000)
[0.142s][info][gc,heap,exit ] object space 13312K, 53% used [0x00000000fec00000,0x00000000ff2f79d0,0x00000000ff900000)
[0.142s][info][gc,heap,exit ] Metaspace used 5428K, capacity 5512K, committed 5632K, reserved 1056768K
[0.142s][info][gc,heap,exit ] class space used 463K, capacity 492K, committed 512K, reserved 1048576K
-Xms20M -Xmx20M -XX:+PrintGCDetails -Xmn15m -XX:SurvivorRatio=8
jdk1.10改為:-XX:+UseParallelGC -Xms30M -Xmx30M -Xlog:gc* -Xmn20m -XX:SurvivorRatio=8
新生代可以放下所有的數(shù)組
老年代沒放
[0.018s][info][gc] Using Parallel
[0.018s][info][gc,heap,coops] Heap address: 0x00000000fe200000, size: 30 MB, Compressed Oops mode: 32-bit
[0.134s][info][gc,heap,exit ] Heap
[0.134s][info][gc,heap,exit ] PSYoungGen total 18432K, used 13970K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000)
[0.134s][info][gc,heap,exit ] eden space 16384K, 85% used [0x00000000fec00000,0x00000000ff9a49d0,0x00000000ffc00000)
[0.134s][info][gc,heap,exit ] from space 2048K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x0000000100000000)
[0.134s][info][gc,heap,exit ] to space 2048K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x00000000ffe00000)
[0.134s][info][gc,heap,exit ] ParOldGen total 10240K, used 0K [0x00000000fe200000, 0x00000000fec00000, 0x00000000fec00000)
[0.134s][info][gc,heap,exit ] object space 10240K, 0% used [0x00000000fe200000,0x00000000fe200000,0x00000000fec00000)
[0.134s][info][gc,heap,exit ] Metaspace used 5433K, capacity 5512K, committed 5632K, reserved 1056768K
[0.134s][info][gc,heap,exit ] class space used 462K, capacity 492K, committed 512K, reserved 1048576K
-Xms20M -Xmx20M -XX:+PrintGCDetails -XX:NewRatio=2
jdk1.10改為-XX:+UseParallelGC -Xms20M -Xmx20M -Xlog:gc* -XX:NewRatio=2
發(fā)生了垃圾回收
出現(xiàn)了空間分配擔(dān)保流妻,而且發(fā)生了FullGC
[0.015s][info][gc] Using Parallel
[0.015s][info][gc,heap,coops] Heap address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit
[0.128s][info][gc,start ] GC(0) Pause Young (Allocation Failure)
[0.129s][info][gc,heap ] GC(0) PSYoungGen: 4675K->512K(6144K)
[0.129s][info][gc,heap ] GC(0) ParOldGen: 0K->3025K(13824K)
[0.129s][info][gc,metaspace ] GC(0) Metaspace: 5394K->5394K(1056768K)
[0.129s][info][gc ] GC(0) Pause Young (Allocation Failure) 4M->3M(19M) 1.643ms
[0.129s][info][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s
[0.130s][info][gc,start ] GC(1) Pause Young (Allocation Failure)
[0.134s][info][gc,heap ] GC(1) PSYoungGen: 5795K->512K(6144K)
[0.134s][info][gc,heap ] GC(1) ParOldGen: 3025K->8210K(13824K)
[0.134s][info][gc,metaspace ] GC(1) Metaspace: 5396K->5396K(1056768K)
[0.134s][info][gc ] GC(1) Pause Young (Allocation Failure) 8M->8M(19M) 3.740ms
[0.134s][info][gc,cpu ] GC(1) User=0.00s Sys=0.00s Real=0.00s
[0.134s][info][gc,start ] GC(2) Pause Full (Ergonomics)
[0.134s][info][gc,phases,start] GC(2) Marking Phase
[0.136s][info][gc,phases ] GC(2) Marking Phase 1.797ms
[0.136s][info][gc,phases,start] GC(2) Summary Phase
[0.136s][info][gc,phases ] GC(2) Summary Phase 0.008ms
[0.136s][info][gc,phases,start] GC(2) Adjust Roots
[0.137s][info][gc,phases ] GC(2) Adjust Roots 1.024ms
[0.137s][info][gc,phases,start] GC(2) Compaction Phase
[0.143s][info][gc,phases ] GC(2) Compaction Phase 5.915ms
[0.143s][info][gc,phases,start] GC(2) Post Compact
[0.143s][info][gc,phases ] GC(2) Post Compact 0.059ms
[0.143s][info][gc,heap ] GC(2) PSYoungGen: 512K->0K(6144K)
[0.143s][info][gc,heap ] GC(2) ParOldGen: 8210K->8573K(13824K)
[0.143s][info][gc,metaspace ] GC(2) Metaspace: 5396K->5396K(1056768K)
[0.143s][info][gc ] GC(2) Pause Full (Ergonomics) 8M->8M(19M) 8.894ms
[0.143s][info][gc,cpu ] GC(2) User=0.02s Sys=0.00s Real=0.01s
[0.143s][info][gc,heap,exit ] Heap
[0.143s][info][gc,heap,exit ] PSYoungGen total 6144K, used 3265K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
[0.143s][info][gc,heap,exit ] eden space 5632K, 57% used [0x00000000ff980000,0x00000000ffcb07c8,0x00000000fff00000)
[0.143s][info][gc,heap,exit ] from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
[0.143s][info][gc,heap,exit ] to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
[0.143s][info][gc,heap,exit ] ParOldGen total 13824K, used 8573K [0x00000000fec00000, 0x00000000ff980000, 0x00000000ff980000)
[0.143s][info][gc,heap,exit ] object space 13824K, 62% used [0x00000000fec00000,0x00000000ff45f730,0x00000000ff980000)
[0.143s][info][gc,heap,exit ] Metaspace used 5404K, capacity 5448K, committed 5632K, reserved 1056768K
[0.143s][info][gc,heap,exit ] class space used 460K, capacity 492K, committed 512K, reserved 1048576K
參考
- 1)享學(xué)課堂Mark老師筆記