點擊 查看 個人另外一篇文章 《深刻理解Java虛擬機》(三)垃圾收集器與內存分配策略java
Microsoft Windows [版本 10.0.14393]
java version "1.8.0_112" Java(TM) SE Runtime Environment (build 1.8.0_112-b15) Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)
IntelliJ IDEA 2017.2
這裏咱們來經過一個小程序進行一下堆內存分析,代碼以下:
package net.penglei.test; public class HeapTest { private static final int _1M = 1024 * 1024; public static void main(String[] args) throws InterruptedException { byte[] byte1 = new byte[2 * _1M]; byte[] byte2 = new byte[2 * _1M]; byte[] byte3 = new byte[2 * _1M]; byte[] byte4 = new byte[2 * _1M]; byte[] byte5 = new byte[2 * _1M]; byte[] byte6 = new byte[5 * _1M]; byte[] byte7 = new byte[2 * _1M]; } }
-Xms20m -Xmx20m -Xmn10m -verbose:gc -XX:+PrintGCDetails #輸出詳細GC日誌模式 -XX:+PrintTenuringDistribution #輸出每次minor GC後新的存活週期的閾值 -XX:+PrintGCTimeStamps #輸出gc的觸發時間
個人 IntelliJ IDEA 配置python
jps -l
看進程,經過 jmap -heap pid
查看堆的概要信息$ jps -l 5636 net.penglei.test.HeapTest
$ jmap -heap 5636 Attaching to process ID 5636, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.112-b15 using thread-local object allocation. Parallel GC with 8 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 #GC後若是發現空閒堆內存佔到整個預估堆內存的N%(百分比) MaxHeapSize = 20971520 (20.0MB) # 堆最大空閒 jvm參數 -Xms20m NewSize = 10485760 (10.0MB) # 年輕代空間 jvm參數 -Xmn10m MaxNewSize = 10485760 (10.0MB) # 年輕代最大空間 OldSize = 10485760 (10.0MB) # 老年代空間 =(等於)堆內存大小 -(減去)年輕代大小 NewRatio = 2 SurvivorRatio = 8 # 年輕代內存又被分紅三部分 Eden 空間 80% 而From Survivor 空間 和 To Survivor空間 分別佔用10% MetaspaceSize = 21807104 (20.796875MB) # 設置元空間的最大值 jvm參數 -XX:MaxMetaspaceSize CompressedClassSpaceSize = 1073741824 (1024.0MB) # 類指針壓縮空間大小, 默認爲1G MaxMetaspaceSize = 17592186044415 MB # 是分配給類元數據空間的最大值 G1HeapRegionSize = 0 (0.0MB) # G1區塊的大小, 取值爲1M至32M. 其取值是要根據最小Heap大小劃分出2048個區塊 ...
byte[] byte3 = new byte[2 * _1M];
$ jmap -heap 5636 ... Heap Usage: PS Young Generation Eden Space: capacity = 8388608 (8.0MB) used = 7635080 (7.281379699707031MB) free = 753528 (0.7186203002929688MB) 91.01724624633789% used From Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used To Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used PS Old Generation capacity = 10485760 (10.0MB) used = 0 (0.0MB) free = 10485760 (10.0MB) 0.0% used 1628 interned Strings occupying 148560 bytes.
數據區塊 | 堆總容量 | 使用容量 | 剩餘容量 | 使用佔比 |
---|---|---|---|---|
年輕代 | 8.0MB | 7.28MB | 0.71MB | 91.0% |
倖存者0 | 1.0MB | 0.00MB | 1.0MB | 0.0% |
倖存者1 | 1.0MB | 0.00MB | 1.0MB | 0.0% |
老年代 | 10.0MB | 0.00MB | 10.MB | 0.0% |
byte[] byte4 = new byte[2 * _1M]
641.638: [GC (Allocation Failure) Desired survivor size 1048576 bytes, new threshold 7 (max 15) [PSYoungGen: 7456K->728K(9216K)] 7456K->6880K(19456K), 0.0036244 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 641.642: [Full GC (Ergonomics) [PSYoungGen: 728K->0K(9216K)] [ParOldGen: 6152K->6700K(10240K)] 6880K->6700K(19456K), [Metaspace: 2848K->2848K(1056768K)], 0.0068164 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
$ jmap -heap 5636 ... Heap Usage: PS Young Generation Eden Space: capacity = 8388608 (8.0MB) used = 2097168 (2.0000152587890625MB) free = 6291440 (5.9999847412109375MB) 25.00019073486328% used From Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used To Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used PS Old Generation capacity = 10485760 (10.0MB) used = 6861768 (6.543891906738281MB) free = 3623992 (3.4561080932617188MB) 65.43891906738281% used 1556 interned Strings occupying 143760 bytes.
641.638: [GC (Allocation Failure) Desired survivor size 1048576 bytes, new threshold 7 (max 15) [PSYoungGen: 7456K->728K(9216K)] 7456K->6880K(19456K), 0.0036244 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Parallel Scavenge 是年輕代 GC 收集器程序員
641.638: [GC (Allocation Failure)
Minor GC
(年輕代垃圾收集),Minor GC 很是頻繁,回收速度快。Desired survivor size 1048576 bytes, new threshold 7 (max 15)
[PSYoungGen: 7456K->728K(9216K)]
格式爲:[PSYoungGen: a->b(c)]算法
年輕代使用的是多線程垃圾收集器
Parallel Scavenge
(新生代收集器,通常採用複製算法,並行的多線程收集器)
7456K->6880K(19456K)
格式爲:x->y(z)小程序
, 0.0036244 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
老年代佔用內存空間 計算方式segmentfault
Parallel Old 是Parallel Scavenge 收集器的老年代版本數組
641.642: [Full GC (Ergonomics) [PSYoungGen: 728K->0K(9216K)] [ParOldGen: 6152K->6700K(10240K)] 6880K->6700K(19456K), [Metaspace: 2848K->2848K(1056768K)], 0.0068164 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
641.642: [Full GC (Ergonomics)
老年代GC 又稱爲Major GC,常常會伴隨一次Minor GC(年輕代垃圾回收)速度比較慢多線程
[PSYoungGen: 728K->0K(9216K)]
格式爲:[PSYoungGen: a->b(c)]jvm
年輕代使用的是多線程垃圾收集器
Parallel Scavenge
(新生代收集器,通常採用複製算法,並行的多線程收集器)
[ParOldGen: 6152K->6700K(10240K)]
格式爲:[ParOldGen: x->y(z)]socket
老年代GC,使用 Parallel Old收集器,是Parallel Scavenge收集器的老年代版本,一搬採用多線程和「標記-整理」算法
6880K->6700K(19456K)
格式爲:e->f(g)]
[Metaspace: 2848K->2848K(1056768K)]
java8 特性是 把永久代 (Permanent Generation (PermGen)) 移植到元空間(Metaspace)
格式爲:t->y(u)]
JDK8 HotSpot JVM 使用本地內存來存儲類元數據信息並稱之爲:元空間(Metaspace);這與Oracle JRockit 和IBM JVM’很類似。這將是一個好消息:意味着不會再有java.lang.OutOfMemoryError: PermGen
問題默認狀況下,類元數據只受可用的本地內存限制(容量取決因而32位或是64位操做系統的可用虛擬內存大小)
, 0.0068164 secs]
[Times: user=0.00 sys=0.00, real=0.01 secs]
提供cpu使用及時間消耗
數據區塊 | 堆總容量 | 使用容量 | 剩餘容量 | 使用佔比 |
---|---|---|---|---|
年輕代 | 8.0MB | 2.00MB | 5.99MB | 25.0% |
倖存者0 | 1.0MB | 0.00MB | 1.00MB | 0.0% |
倖存者1 | 1.0MB | 0.00MB | 1.00MB | 0.0% |
老年代 | 10.0MB | 6.54MB | 3.45MB | 65.4% |
byte[] byte5 = new byte[2 * _1M];
$ jmap -heap 5636 ... Heap Usage: PS Young Generation Eden Space: capacity = 8388608 (8.0MB) used = 4356568 (4.154747009277344MB) free = 4032040 (3.8452529907226562MB) 51.9343376159668% used From Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used To Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used PS Old Generation capacity = 10485760 (10.0MB) used = 6861768 (6.543891906738281MB) free = 3623992 (3.4561080932617188MB) 65.43891906738281% used 1556 interned Strings occupying 143760 bytes.
數據區塊 | 堆總容量 | 使用容量 | 剩餘容量 | 使用佔比 |
---|---|---|---|---|
年輕代 | 8.0MB | 4.15MB | 3.84MB | 51.9% |
倖存者0 | 1.0MB | 0.00MB | 1.00MB | 0.0% |
倖存者1 | 1.0MB | 0.00MB | 1.00MB | 0.0% |
老年代 | 10.0MB | 6.54MB | 3.45MB | 65.4% |
byte[] byte6 = new byte[5 * _1M];
10342.704: [ Full GC (Ergonomics) [PSYoungGen: 4254K->2048K(9216K)] [ParOldGen: 6700K->8745K(10240K)] 10955K->10793K(19456K), [Metaspace: 2848K->2848K(1056768K)], 0.0154383 secs ] [Times: user=0.00 sys=0.03, real=0.02 secs]
這個GC 日誌詳細解讀請參考,上面解讀,執行完 byte4 的日誌 ps(那個解讀更詳細)
$ jmap -heap 5636 ... Heap Usage: PS Young Generation Eden Space: capacity = 8388608 (8.0MB) used = 7507856 (7.1600494384765625MB) free = 880752 (0.8399505615234375MB) 89.50061798095703% used From Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used To Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used PS Old Generation capacity = 10485760 (10.0MB) used = 8955872 (8.540985107421875MB) free = 1529888 (1.459014892578125MB) 85.40985107421875% used 1556 interned Strings occupying 143760 bytes.
數據區塊 | 堆總容量 | 使用容量 | 剩餘容量 | 使用佔比 |
---|---|---|---|---|
年輕代 | 8.0MB | 7.16MB | 0.83MB | 89.5% |
倖存者0 | 1.0MB | 0.00MB | 1.00MB | 0.0% |
倖存者1 | 1.0MB | 0.00MB | 1.00MB | 0.0% |
老年代 | 10.0MB | 8.54MB | 1.45MB | 85.4% |
byte[] byte7 = new byte[2 * _1M];
OutOfMemoryError
。10427.298: [Full GC (Ergonomics) [PSYoungGen: 7331K->7168K(9216K)] [ParOldGen: 8745K->8745K(10240K)] 16077K->15913K(19456K), [Metaspace: 2849K->2849K(1056768K)], 0.0065366 secs] [Times: user=0.09 sys=0.02, real=0.01 secs] 10427.305: [Full GC (Allocation Failure) [PSYoungGen: 7168K->7168K(9216K)] [ParOldGen: 8745K->8745K(10240K)] 15913K->15913K(19456K), [Metaspace: 2849K->2849K(1056768K)], 0.0027873 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space Heap at net.penglei.test.HeapTest.main(HeapTest.java:16) PSYoungGen total 9216K, used 7462K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) eden space 8192K, 91% used [0x00000000ff600000,0x00000000ffd49b60,0x00000000ffe00000) from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) ParOldGen total 10240K, used 8745K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) object space 10240K, 85% used [0x00000000fec00000,0x00000000ff48a708,0x00000000ff600000) Metaspace used 2880K, capacity 4486K, committed 4864K, reserved 1056768K class space used 309K, capacity 386K, committed 512K, reserved 1048576K Disconnected from the target VM, address: '127.0.0.1:59679', transport: 'socket' Process finished with exit code 1 。
[Full GC (Ergonomics) [PSYoungGen: 7331K->7168K(9216K)]
[ParOldGen: 8745K->8745K(10240K)]
16077K->15913K(19456K)
這些是告訴你,Exception 前 內存溢出前的堆佔用狀況
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space Heap at net.penglei.test.HeapTest.main(HeapTest.java:16) PSYoungGen total 9216K, used 7462K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) eden space 8192K, 91% used [0x00000000ff600000,0x00000000ffd49b60,0x00000000ffe00000) from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) ParOldGen total 10240K, used 8745K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) object space 10240K, 85% used [0x00000000fec00000,0x00000000ff48a708,0x00000000ff600000) Metaspace used 2880K, capacity 4486K, committed 4864K, reserved 1056768K class space used 309K, capacity 386K, committed 512K, reserved 1048576K
[Full GC (Allocation Failure) [PSYoungGen: 7168K->7168K(9216K)] [ParOldGen: 8745K->8745K(10240K)] 15913K->15913K(19456K)
大多數狀況下,對象優先在新生代的Eden區分配。
當Eden區沒有足夠的空間時,虛擬機將發起一次Minor GC。
Minor GC與Full GC。
PretenureSizeThreshold
,大於這個參數的對象將直接在老年代分配。MaxTenuringThreshold
來設置。4.動態對象年齡的斷定
《深刻理解Java虛擬機:JVM高級特性與最佳實踐_周志明.高清掃描版.pdf》
下載地址:連接:http://pan.baidu.com/s/1miBQCBY 密碼:9kbn
《深刻理解Java虛擬機》(四)虛擬機性能監控與故障處理工具
《深刻理解Java虛擬機》(六)堆內存使用分析,GC 日誌解讀