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