Survivor空間溢出實例

jvm系列java

本文演示survivor空間溢出的場景。

實例代碼

class MemoryObject{
    private byte[] bytes;

    public MemoryObject(int objectSize){
        this.bytes = new byte[objectSize];
    }
}

/**
     * eden 13184K ,s0/s1 1600k 共16M
     * old 24m

-Xms40m -Xmx40m -Xmn16m -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution

     * @throws InterruptedException
     */
    public static void survivorNotEnough2OldSpace() throws InterruptedException {
//        Thread.sleep(50000);
        MemoryObject object = new MemoryObject(1024*1024);
        MemoryObject m2Object = new MemoryObject(1024*1024*2);
        happenMinorGC(9);
        Thread.sleep(2000);
    }

private static void happenMinorGC(int happenMinorGCIndex) throws InterruptedException {
        for(int i=0;i<happenMinorGCIndex;i++){
            if(i == happenMinorGCIndex - 1){
//                Thread.sleep(2000);
                System.out.println("minor gc should happen:"+printCurrent());
            }
            new MemoryObject(1024*1024);
            System.out.println("allocate last:"+printCurrent());
        }
    }

輸出

allocate last:2014-11-04 15-43-18-829
allocate last:2014-11-04 15-43-18-830
allocate last:2014-11-04 15-43-18-830
allocate last:2014-11-04 15-43-18-831
allocate last:2014-11-04 15-43-18-831
allocate last:2014-11-04 15-43-18-832
allocate last:2014-11-04 15-43-18-833
{Heap before GC invocations=0 (full 0):
 def new generation   total 14784K, used 13182K [0x00000007f8600000, 0x00000007f9600000, 0x00000007f9600000)
  eden space 13184K,  99% used [0x00000007f8600000, 0x00000007f92df8b0, 0x00000007f92e0000)
  from space 1600K,   0% used [0x00000007f92e0000, 0x00000007f92e0000, 0x00000007f9470000)
  to   space 1600K,   0% used [0x00000007f9470000, 0x00000007f9470000, 0x00000007f9600000)
 tenured generation   total 24576K, used 0K [0x00000007f9600000, 0x00000007fae00000, 0x00000007fae00000)
   the space 24576K,   0% used [0x00000007f9600000, 0x00000007f9600000, 0x00000007f9600200, 0x00000007fae00000)
 compacting perm gen  total 21248K, used 3994K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)
   the space 21248K,  18% used [0x00000007fae00000, 0x00000007fb1e6950, 0x00000007fb1e6a00, 0x00000007fc2c0000)
No shared spaces configured.
[GC [DefNew
Desired survivor size 819200 bytes, new threshold 1 (max 15)
- age   1:    1638400 bytes(1600K),    1638400 total
這個狀況是survivor空間溢出,survivor空間被佔滿,而後溢出的部分,直接放到了年老代(2401K),溢出以後,計算survivor空間裏頭對象的年齡分佈,發現年齡爲1的對象大小總和超過了survivor的desired值,因而設置新的閾值爲該age=1。
(每次young gc以後打印survivor區域內對象的年齡分佈)
若是底下age的total大小大於Desired survivor size的大小,那麼就表明了survivor空間溢出了,被填滿,而後會從新計算threshold。


: 13182K->1600K(14784K), 0.0057500 secs] 13182K->4001K(39360K), 0.0057720 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap after GC invocations=1 (full 0):
 def new generation   total 14784K, used 1600K [0x00000007f8600000, 0x00000007f9600000, 0x00000007f9600000)
  eden space 13184K,   0% used [0x00000007f8600000, 0x00000007f8600000, 0x00000007f92e0000)
  from space 1600K, 100% used [0x00000007f9470000, 0x00000007f9600000, 0x00000007f9600000)
  to   space 1600K,   0% used [0x00000007f92e0000, 0x00000007f92e0000, 0x00000007f9470000)
 tenured generation   total 24576K, used 2401K [0x00000007f9600000, 0x00000007fae00000, 0x00000007fae00000)
   the space 24576K,   9% used [0x00000007f9600000, 0x00000007f98586d8, 0x00000007f9858800, 0x00000007fae00000)
 compacting perm gen  total 21248K, used 3994K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)
   the space 21248K,  18% used [0x00000007fae00000, 0x00000007fb1e6950, 0x00000007fb1e6a00, 0x00000007fc2c0000)
No shared spaces configured.
}
allocate last:2014-11-04 15-43-18-839
minor gc should happen:2014-11-04 15-43-18-839
allocate last:2014-11-04 15-43-18-839
Heap
 def new generation   total 14784K, used 4202K [0x00000007f8600000, 0x00000007f9600000, 0x00000007f9600000)
  eden space 13184K,  19% used [0x00000007f8600000, 0x00000007f888a820, 0x00000007f92e0000)
  from space 1600K, 100% used [0x00000007f9470000, 0x00000007f9600000, 0x00000007f9600000)
  to   space 1600K,   0% used [0x00000007f92e0000, 0x00000007f92e0000, 0x00000007f9470000)
 tenured generation   total 24576K, used 2401K [0x00000007f9600000, 0x00000007fae00000, 0x00000007fae00000)
   the space 24576K,   9% used [0x00000007f9600000, 0x00000007f98586d8, 0x00000007f9858800, 0x00000007fae00000)
 compacting perm gen  total 21248K, used 4001K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)
   the space 21248K,  18% used [0x00000007fae00000, 0x00000007fb1e8710, 0x00000007fb1e8800, 0x00000007fc2c0000)
No shared spaces configured.

小結

並非都得等到對象年齡達到晉升閾值才提高到年老代

若是在Survivor空間中相同年齡全部對象大小的總和>Survivor空間的一半( -XX:TargetSurvivorRatio)時,年齡>=該年齡的對象就能夠直接進入年老代

Desired survivor size = (survivor_capacity TargetSurvivorRatio) / 100 sizeof(a pointer):survivor_capacity(一個survivor space的大小)乘以TargetSurvivorRatio

-XX:TargetSurvivorRatio

目標存活率,默認爲50%
代表全部age的survivor space對象的大小若是超過Desired survivor size,則從新計算threshold,以age和MaxTenuringThreshold的最小值爲準,不然以MaxTenuringThreshold爲準.

-XX:TargetSurvivorRatio

目標Survivor空間佔用是HotSpot嘗試在MinorGC以後仍然維持的Survivor空間佔用,默認值爲50是由於HotSpot研發團隊對不一樣類型的應用程序進行了大量的負荷測試,結果代表50%的目標Survivor空間佔用能適應大多數應用程序,能應對MinorGC時存活對象的急速增長。

相關文章
相關標籤/搜索