java有内置的垃圾回收器做記憶體回收,通過強引用、軟引用、弱引用和虛引用給對象做"标記",告訴垃圾回收器在什麼時機回收什麼記憶體。我先通過JVM options參數探測JVM内部不同垃圾回收的政策。
minimum size of heap:10MB
maximum size of heap:20MB
new size of heap:5MB

截圖是以空main方法運作後JVM的記憶體使用概要。新生代記憶體大小為5MB,PSYoungGen區可用記憶體大小為4608K,eden、from和to區分别為4MB、512K和512K;老年代可用記憶體大小為5120K。
建立allocate1數組在eden區配置設定了4096KB*0.25=1MB記憶體。
JVM将3MB的對象放到了老年代:
為什麼JVM不GC然後在新生代上配置設定3MB空間?這和記憶體配置設定與回收政策有關:
即:
新生代初始36%的記憶體空間沒有可GC的空間。
新生代的eden+from剩餘3.1MB,足以提供3MB空間,但記憶體按page配置設定(4K/page),如果在新生代配置設定會使得對象分開儲存在不同的區(eden和from),是否存儲對象的記憶體隻能在一個區裡,這點待驗證。
垃圾收集器為保吞吐量,當新生代無足夠記憶體時,把對象配置設定到了老年代。
初始我們給heap配置設定了最大20MB的記憶體空間,下面看下GC的場景。
此時發生了GC和Full GC:
刨除初始被占用的36%的eden區,20MB的heap大小不滿足記憶體配置設定要求,觸發了java.lang.OutOfMemoryError: Java heap space錯誤。
此時将allocate1=null,觸發GC,heap剛好可以完成記憶體配置設定。此時是在釋放了eden空間後,轉移到老年代進行記憶體配置設定:
To be continued...