一、導(dǎo)論
java技術(shù)體系中所提到的內(nèi)存自動化管理歸根結(jié)底就是內(nèi)存的分配與回收兩個問題,之前已經(jīng)和大家談過java回收的相關(guān)知識,今天來和大家聊聊java對象的在內(nèi)存中的分配。通俗的講,對象的內(nèi)存分配就是在堆上的分配,對象主要分配在新生代的Eden上(關(guān)于對象在內(nèi)存上的分代在垃圾回收中會補上,想了解的也可以參考《深入理解java虛擬機》),如果啟動了本地線程分配緩沖,講按線程優(yōu)先在TLAB上分配。少數(shù)情況下也是直接在老年代中分配。
二、經(jīng)典的分配策略
1、對象優(yōu)先在Eden上分配
一般情況下對象都是優(yōu)先分配在Eden上,當(dāng)Eden沒有足夠的空間進行分配時,jvm會發(fā)起一次Minor GC。如果還是沒有足夠的空間分配,后面還有另外的措施,下面會提到。
設(shè)置虛擬機的偶記日志參數(shù)-XX:+PrintGCDetails,在垃圾回收的時候會打印內(nèi)存的回收日志,并且在進程退出的時候會輸出當(dāng)前內(nèi)存各區(qū)域的分配情況。下面來看下具體的例子,首先需要設(shè)置jvm的參數(shù)-Xms20m -Xmx20m -Xmn10m,這三個參數(shù)說明java堆大小為20M,且不可擴展,其中10M分配給新生代,剩下的10M分配給老年代。-XX:SurvivorRatio=8是jvm默認的新生代中Eden和Survivor比例,默認為8:1。原因是新生代中的對象98%都會在下一次GC的時候回收掉,所以很適合采用復(fù)制算法進行垃圾回收,所以新生代10M的內(nèi)存中,8M是Eden,1M是Survivor,另外的1M是未使用配合復(fù)制算法的內(nèi)存塊,也是Survivor。
1 public class ReflectTest { 2 3 private static final int _1MB = 1024*1024; 4 5 public static void testAllocation(){ 6 byte[] allocation1 , allocation2 , allocation3 , allocation4; 7 allocation1 = new byte[2 * _1MB]; 8 allocation2 = new byte[2 * _1MB]; 9 allocation3 = new byte[2 * _1MB];10 allocation4 = new byte[6 * _1MB];11 }12 13 public static void main(String[] a