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