程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> [問題貼]小白請教幾個關於Java虛擬機內存分配策略的問題,java虛擬機

[問題貼]小白請教幾個關於Java虛擬機內存分配策略的問題,java虛擬機

編輯:JAVA綜合教程

[問題貼]小白請教幾個關於Java虛擬機內存分配策略的問題,java虛擬機


最近在看周志明所著的《深入理解Java虛擬機》,有幾個問題不太明白,希望對虛擬機有研究的哥們兒幫我解答一下。
先說一下我進行試驗的環境:

操作系統:Mac OS X 10.11.6 EI Capitan

Java環境: java version "1.8.0_92"

Java(TM) SE Runtime Environment (build 1.8.0_92-b14)

Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

1. 我發現在年輕代中,即使我只是一個空類,沒有進行任何的內存分配工作,Eden區域內存還是會被占用一部分,例子如下:

public class BlankedClassSize {

  public static void main(String[] args) {

  // TODO Auto-generated method stub
  }
}

虛擬機參數設置:

-verbose:gc -XX:+UseSerialGC -XX:+PrintGCDetails -Xmx20M -Xms20M -Xmn10M

虛擬機GC情況如下:

Heap

def new generation  total 9216K, used1164K
[0x00000007bf000000, 0x00000007bfa00000, 0x00000007bfa00000)

eden space 8192K,  14% used [0x00000007bf000000, 0x00000007bf1231d0, 0x00000007bf800000)

from space 1024K,   0% used [0x00000007bf800000, 0x00000007bf800000, 0x00000007bf900000)

to   space 1024K,   0% used [0x00000007bf900000, 0x00000007bf900000, 0x00000007bfa00000)

tenured generation   total 6144K, used 0K [0x00000007bfa00000, 0x00000007c0000000, 0x00000007c0000000)

the space 6144K,   0% used [0x00000007bfa00000, 0x00000007bfa00000, 0x00000007bfa00200, 0x00000007c0000000)

Metaspace       used 2666K, capacity 4486K, committed 4864K, reserved 1056768K

class space    used 289K, capacity 386K, committed 512K, reserved 1048576K

問題1:這裡是什麼占用了內存?

2.當年輕代進行一次GC後,因為年輕代GC是采用復制算法收集內存的,那麼正常情況下進行一次Minor GC後,Eden區域占存為什麼不是零?是什麼占用著內存?例子如下:

public class MinorGC {

    private static final int_1MB = 1024*1024;
    
    public static void main(String[] args) {

        // TODO Auto-generated method stub

        testEdenGC();

    }

    public static void testEdenGC(){

        byte[] allocation1,allocation2,allocation3,allocation4,allocation5,allocation6;

        allocation1=newbyte[_1MB];

        allocation2=newbyte[_1MB];

        allocation3=newbyte[_1MB];

        allocation4=newbyte[_1MB];

        allocation5=newbyte[_1MB];

        allocation6=newbyte[_1MB];

    }

}

虛擬機參數設置:

-verbose:gc -XX:TenuringThreshold=1 -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRation=3 -XX:+PrintGCDetails -XX:+UseSerialGC

虛擬機GC情況:

[GC (Allocation Failure) DefNew: 6029K->1354K(8192K), 0.0032985 secs] 6029K->5450K(18432K), 0.0033216 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

def new generation   total 8192K, used 2440K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)

eden space 6144K,  17% used [0x00000007bec00000, 0x00000007bed0f748, 0x00000007bf200000)

from space 2048K,  66% used [0x00000007bf400000, 0x00000007bf5529b0, 0x00000007bf600000)

to   space 2048K,   0% used [0x00000007bf200000, 0x00000007bf200000, 0x00000007bf400000)

tenured generation   total 10240K, used 4096K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)

the space 10240K,  40% used [0x00000007bf600000, 0x00000007bfa00040, 0x00000007bfa00200, 0x00000007c0000000)

Metaspace       used 2666K, capacity 4486K, committed 4864K, reserved 1056768K

class space    used 289K, capacity 386K, committed 512K, reserved 1048576K

問題2:根據6026K->1354K(8192K)可知,進行GC後,allocation1轉入survivor1,allocation2~4轉入老年區,此時eden中還有1354K內存被占用,是什麼占用的?根據6029K->5450K(18432K),知道GC後,Java堆內存減少了579K,減少的這部分是誰的內存(明顯新建的幾個對象都可達,不至於被回收)?

3. 當給新對象分配內存的時候,因為年輕代空間不足,會發生一次minor GC,將年輕代中依然存活的對象復制到老年區,給新對象騰出空間,根據我的實驗,此時若老年區內存不夠將年輕代對象復制過去但是夠新對象的存儲,(此時會發生擔保失敗)則會直接將新對象放進老年代,例子如下:

public class MinorGC {

  private static  final int_1MB = 1024*1024;

  public static void main(String[] args) {

    // TODO Auto-generated method stub

    testAllocation();
  }

  public static void testAllocation(){

    byte[] allocation1,allocation2,allocation3,allocation4;

    allocation1 = newbyte[2*_1MB];

    allocation2 = newbyte[2*_1MB];

    allocation3 = newbyte[2*_1MB];

    allocation4 = newbyte[4*_1MB];

  }
}

 虛擬機參數設置如下:

-verbose:gc -Xms16M -Xmx16M -Xmn10M -XX:+PrintGCDetails  -XX:SurvivorRatio=8  -XX:+HeapDumpOnOutOfMemoryError -XX:MaxTenuringThreshold=15 -XX:+UseSerialGC

GC情況如下:

[GC (Allocation Failure) [DefNew (promotion failed) : 7144K->7474K(9216K), 0.0028055 secs][Tenured: 4096K->4096K(6144K), 0.0015627 secs] 7144K->6473K(15360K), [Metaspace: 2660K->2660K(1056768K)], 0.0044048 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

def new generation   total 9216K, used 6555K [0x00000007bf000000, 0x00000007bfa00000, 0x00000007bfa00000)

eden space 8192K,  80% used [0x00000007bf000000, 0x00000007bf666ed0, 0x00000007bf800000)

from space 1024K,   0% used [0x00000007bf900000, 0x00000007bf900000, 0x00000007bfa00000)

to   space 1024K,   0% used [0x00000007bf800000, 0x00000007bf800000, 0x00000007bf900000)

tenured generation   total 6144K, used 4096K[0x00000007bfa00000, 0x00000007c0000000, 0x00000007c0000000)

the space 6144K,  66% used [0x00000007bfa00000, 0x00000007bfe00020, 0x00000007bfe00200, 0x00000007c0000000)

Metaspace       used 2666K, capacity 4486K, committed 4864K, reserved 1056768K

class space    used 289K, capacity 386K, committed 512K, reserved 1048576K

根據上面輸出結果,可以看出,GC過程中,年輕代7144K->;7144K(9216K),並沒有將年輕代中的對象轉移走,而老年代中4096K->4096K(6144K),tenured generation   total 6144K, used 4096K,說明allocation4直接被轉移到老年代中了。

問題3:難道這種情況下虛擬機會自動設置大對象阈值??將新對象直接放入老年去?

以上三個問題讓我這個虛擬機小白百思不得其解,還希望大家幫我解釋一下,在此謝過。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved