《深刻理解Java虛擬機》(六)堆內存使用分析,垃圾收集器 GC 日誌解讀

堆內存使用分析,垃圾收集器 GC 日誌解讀

重要的東東

  • 在Java中,對象實例都是在堆上建立。一些類信息,常量,靜態變量等存儲在方法區。堆和方法區都是線程共享的。
  • GC機制是由JVM提供,用來清理須要清除的對象,回收堆內存。
  • GC機制將Java程序員從內存管理中解放了出來,能夠更關注於業務邏輯。
  • 在Java中,GC是由一個被稱爲垃圾回收器的守護線程執行的。
  • 在從內存回收一個對象以前會調用對象的finalize()方法。
  • 做爲一個Java開發者不能強制JVM執行GC;GC的觸發由JVM依據堆內存的大小來決定。
  • System.gc()和Runtime.gc()會向JVM發送執行GC的請求,可是JVM不保證必定會執行GC。
  • 若是堆沒有內存建立新的對象了,會拋出OutOfMemoryError。

什麼樣的對象會被GC回收?

  • 在垃圾收集器進行回收前,第一件事就是肯定這些對象哪些還存活,哪些已經死去。

點擊 查看 個人另外一篇文章 《深刻理解Java虛擬機》(三)垃圾收集器與內存分配策略java

測試環境

  • 系統
Microsoft Windows [版本 10.0.14393]
  • JDK
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];


    }
}

設置JVM 參數配置

-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個區塊

...

執行完 byte3

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%

簡單總結

  • PS Young Generation 年輕代空間,使用量達到 91.0%,內存剩餘0.71MB,當下次執行byte4(佔用年輕代2M內存),會觸發Eden Space 空間(年輕代) Minor GC (年輕代垃圾收集)。
  • PS Old Generation 老年代空間,使用量達到 0.00%,內存剩餘10.MB,當下次執行 byte4(佔用年輕代2M內存),上面 Eden Space 空間(年輕代) Minor GC (年輕代垃圾收集),會老年代佔用一部份內存。

執行完 byte4

byte[] byte4 = new byte[2 * _1M]

控制檯打印的GC日誌

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]

GC日誌分塊圖解 ps(畫的很差)

圖片描述

$ 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.

GC日誌詳細分析

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)
  • 1641.638:是本次GC發生的時間,從jvm啓動起開始計時,單位爲秒。這是一次Minor GC(年輕代垃圾收集),Minor GC 很是頻繁,回收速度快。
Desired survivor size 1048576 bytes, new threshold 7 (max 15)
  • 指望的倖存者大小1048576字節,新的存活週期的閾值爲7(max 15)。
[PSYoungGen: 7456K->728K(9216K)]

格式爲:[PSYoungGen: a->b(c)]算法

年輕代使用的是多線程垃圾收集器 Parallel Scavenge(新生代收集器,通常採用複製算法,並行的多線程收集器)
  • PSYoungGen,表示 GC發生在年輕代。
  • a 爲GC前年輕代已佔用空間,年輕代又細分爲一個Eden 空間和From Survivor 空間 和 To Survivor空間。
  • b 爲 Minor GC以後Eden空間GC後年輕代已佔用空間 或者Survivor中已被佔用的空間。
  • c 括號裏的c表示整個年輕代的大小。
7456K->6880K(19456K)

格式爲:x->y(z)小程序

  • x 表示GC前堆的已佔用空間,
  • y 表示GC後堆已佔用空間,
  • z 表示堆的總大小。
, 0.0036244 secs]
  • 表示本次GC所消耗的時間。
[Times: user=0.00 sys=0.00, real=0.00 secs]
  • 提供cpu使用及時間消耗,user是用戶態消耗的cpu時間,sys是系統態消耗的cpu時間,real是實際的消耗時間。

老年代佔用內存空間 計算方式segmentfault

  • 老年代的內存大小 = (等於) 堆內存總大小 - (減去)年輕代內存大小。
  • 此例中就是19456K - 9216K = 10240K

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(年輕代垃圾回收)速度比較慢多線程

  • 641.642:是本次GC發生的時間,從jvm啓動起開始計時,單位爲秒。[Full GC (Ergonomics) ,表示執行全局垃圾回收
[PSYoungGen: 728K->0K(9216K)]

格式爲:[PSYoungGen: a->b(c)]jvm

年輕代使用的是多線程垃圾收集器 Parallel Scavenge(新生代收集器,通常採用複製算法,並行的多線程收集器)
  • PSYoungGen,表示 GC發生在年輕代。
  • a 爲GC前年輕代已佔用空間,年輕代又細分爲一個Eden 空間和From Survivor 空間 和 To Survivor空間。
  • b 爲 Minor GC以後Eden空間GC後年輕代已佔用空間 或者Survivor中已被佔用的空間。
  • c 括號裏的c表示整個年輕代的大小。
[ParOldGen: 6152K->6700K(10240K)]

格式爲:[ParOldGen: x->y(z)]socket

老年代GC,使用 Parallel Old收集器,是Parallel Scavenge收集器的老年代版本,一搬採用多線程和「標記-整理」算法
  • ParOldGen 表示 GC 發生在老年代。
  • x 爲GC前老年代已佔用空間
  • y 爲GC後老年代已佔用空間
  • 括號裏的 z 爲整個老年代的大小
6880K->6700K(19456K)

格式爲:e->f(g)]

  • e 爲GC前堆堆內存佔用,
  • f 爲GC後堆堆內存佔用,
  • 括號裏的 g 爲JVM整個堆的總大小。
[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位操做系統的可用虛擬內存大小)

  • t 爲元空間的垃圾回收前內存佔用
  • y 爲元空間的垃圾回收後內存佔用
  • 括號裏的 u 爲JVM元空間內存總大小
, 0.0068164 secs]
  • 表示本次GC所消耗的時間。
[Times: user=0.00 sys=0.00, real=0.01 secs]

提供cpu使用及時間消耗

  • user :用是用戶態消耗的cpu時間
  • sys :是系統態消耗的cpu時間
  • real :本次GC是實際的消耗時間
數據區塊 堆總容量 使用容量 剩餘容量 使用佔比
年輕代 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%

簡單總結

  • 年輕代 Eden Space 空間,使用量達到 25.0%,內存剩餘5.99MB,當下次執行byte5(佔用年輕代2M內存) 不會觸發年輕代 Eden Space 空間 Minor GC(年輕代垃圾收集)。
  • 老年代空間,使用量達到 6.54%,內存剩餘3.45MB,當下次執行byte5(佔用年輕代2M內存),不會觸發老年代空間 Major GC(老年代垃圾收集),由於年輕代空間還夠用。

執行完 byte5

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%

簡單總結

  • 年輕代 Eden Space 空間,使用量達到 51.9%,內存剩餘3.84MB,當下次執行byte6(佔用年輕代5M內存),致使年輕代空間不夠用了, 會觸發年輕代 Eden Space 空間 Minor GC(年輕代垃圾收集),把一部份內存轉移到 PS Old Generation 老年代。
  • 老年代 PS Old Generation 空間,使用量達到 6.54%,內存剩餘3.45MB,當下次執行byte6(佔用年輕代5M內存),因爲年輕代的一部份內存,轉移到了老年代,致使老年代空間不夠用了,會觸發老年代 PS Old Generation 空間 Major GC(老年代垃圾收集)。

執行完 byte6

byte[] byte6 = new byte[5 * _1M];

控制檯打印的GC日誌

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(那個解讀更詳細)

  • 這個是日誌其實說的就是 :年輕代G回收先後,老年代GC回收先後,整個堆的GC回收先後,原數據空間回收先後,的內存使用狀況。三個內存區塊GC回收所消耗的時間,提供cpu使用及時間消耗時間

簡單解讀GC日誌

  • PS Young Generation 年輕代 Eden Space 空間,使用量達到 4254K,當執行byte6(佔用年輕代5M內存),致使年輕代空間不夠用了,會先觸發年輕代 Eden Space 空間 Minor GC(年輕代垃圾收集),把一部份內存轉移到 PS Old Generation 老年代,GC回收後 Eden Space 空間 剩餘 2048K。
  • PS Old Generation 老年代空間,使用量達到 6700K,當執行byte6(佔用年輕代5M內存),因爲年輕代的一部份內存,轉移到了老年代,致使老年代空間不夠用了,會先觸發老年代 PS Old Generation 空間 Major GC(老年代垃圾收集)。GC回收後 Eden Space 空間 剩餘 8745K。
$ 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%

執行完 byte7

byte[] byte7 = new byte[2 * _1M];

簡單總結

  • 參考 byte6 執行後,PS Young Generation 年輕代 Eden Space 空間,使用量達到 89.5%,內存剩餘0.83MB,執行byte7(佔用年輕代2M內存),致使年輕代空間不夠用了,會觸發Eden Space 空間(年輕代) Minor GC (年輕代垃圾收集)
  • 參考 byte6 執行後,PS Old Generation 老年代空間,使用量達到 85.4%,內存剩餘1.45MB,執行byte7(佔用年輕代2M內存),會致使年輕代的GC回收放到老年代,而老年代也承擔不了,會 OutOfMemoryError

控制檯打印的GC日誌

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)]
  • 本次 Minor GC 發生在PS Young Generation 年輕代 Eden Space 空間,因爲老年代已經佔用85.4%,老年代空間不夠用,本次年輕代垃圾回收沒什麼太大做用,只回收了一丟丟。
[ParOldGen: 8745K->8745K(10240K)]
  • 本次 Major GC 發生在 PS Old Generation 老年代 ,因爲老年代已經佔用85.4% , 空間不夠回收用,致使老年代回收沒有效果**
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
  • 此刻的 PS Young Generation 年輕代JVM 堆回收前佔用16077K,年輕代JVM 堆回收後佔用16077K ,JVM 堆總大小 19456K
[Full GC (Allocation Failure)
[PSYoungGen: 7168K->7168K(9216K)] [ParOldGen: 8745K->8745K(10240K)] 15913K->15913K(19456K)
  • PSYoungGen 年輕代 Minor GC , ParOldGen 老年代 Major GC 老年代承擔不了 15913K 內存,而後就 OutOfMemoryError 堆內存溢出了
  • 爲什了 老年代此次要 承擔15913K 內存呢?由於前兩次 Full GC 都沒有成功,致使內存積壓了一些在堆空間,堆空間天然放不下,而後要放到老年代,老年代放不下就堆內存溢出了

總結 內存分配與回收策略

  • 對象優先在新生代分配
  • 大對象直接進入老年代
  • 長期存活的對象將進入老年代
  • 動態對象年齡判斷:若是在Survivor空間中相同年齡全部對象大小總和大於Survivor空間的一半,大於或等於該年齡的對象直接進入老年代。
  • 空間分配擔保:發生Minor GC前,虛擬機會先檢查老年代最大可用連續空間是否大於新生代全部對象總空間,若是不成立,虛擬機會查看HandlePromotionFailure設置值是否容許擔保失敗,若是容許繼續檢查老年代最大可用的連續空間是否大於歷次晉升到老年代的平均大小,若是大於會嘗試進行一次Minor GC;若是小於或者不容許冒險,會進行一次Full GC。

1 對象優先在eden分配

大多數狀況下,對象優先在新生代的Eden區分配。
當Eden區沒有足夠的空間時,虛擬機將發起一次Minor GC。
Minor GC與Full GC。

  • Minor GC:新生代GC,很是頻繁,回收速度快。
  • Fulll GC:老年代GC,又稱爲Major GC,常常會伴隨一次Minor GC,速度比較慢。

2 大對象直接進入老年代

  • 大對象是指須要大量連續的內存空間的Java對象,最典型的大對象就是那種很長的字符串以及數組。
  • 虛擬機提供了一個參數:PretenureSizeThreshold,大於這個參數的對象將直接在老年代分配。

3 長期存活的對象將進入老年代

  • 虛擬機給每一個對象定義了一個對象年齡計數器(Age),對象每通過一次Minor GC後仍然存活,且能被Survivor容納的話,年齡就 +1 ,當年齡增長到必定程度(默認爲15),就會被晉升到老年代中,這個閾值能夠經過參數 MaxTenuringThreshold 來設置。

4.動態對象年齡的斷定

4 動態對象年齡斷定

  • 若是在Survivor空間中相同年齡全部對象大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的對象就能夠直接進入老年代。

5 空間分配擔保

  • 爲了更好的適應不一樣程序的內存情況,對象年齡不是必須到達閾值纔會進入老年代。
  • 只要老年代的連續空間大於新生代對象總大小或者歷次晉升的平均大小就會進行Minor GC,不然將進行Full GC。

《深刻理解Java虛擬機:JVM高級特性與最佳實踐_周志明.高清掃描版.pdf》

下載地址:連接:http://pan.baidu.com/s/1miBQCBY 密碼:9kbn

推薦閱讀

《深刻理解Java虛擬機》(一)Java虛擬機發展史

《深刻理解Java虛擬機》(二)Java虛擬機運行時數據區

《深刻理解Java虛擬機》(三)垃圾收集器與內存分配策略

《深刻理解Java虛擬機》(四)虛擬機性能監控與故障處理工具

《深刻理解Java虛擬機》(五)JVM調優 - 工具

《深刻理解Java虛擬機》(六)堆內存使用分析,GC 日誌解讀

Contact

  • 做者:鵬磊
  • 出處:http://www.ymq.io
  • Email:admin@souyunku.com
  • 版權歸做者全部,轉載請註明出處
  • Wechat:關注公衆號,搜雲庫,專一於開發技術的研究與知識分享

關注公衆號-搜雲庫

相關文章
相關標籤/搜索