JVM內存區域詳解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)


 

JVM區域總體分兩類,heap區和非heap區。
heap區又分為:

  • Eden Space(伊甸園)、
  • Survivor Space(幸存者區)、
  • Old Gen(老年代)。

非heap區又分:

  • Code Cache(代碼緩存區);
  • Perm Gen(永久代);
  • Jvm Stack(java虛擬機棧);
  • Local Method Statck(本地方法棧)

下面我們對每一個內存區域做詳細介紹。
Eden Space字面意思是伊甸園,對象被創建的時候首先放到這個區域,進行垃圾回收后,不能被回收的對象被放入到空的survivor區域。

Survivor Space幸存者區,用於保存在eden space內存區域中經過垃圾回收后沒有被回收的對象。

Survivor有兩個,分別為To Survivor、 From Survivor,這個兩個區域的空間大小是一樣的。

執行垃圾回收的時候Eden區域不能被回收的對象被放入到空的survivor(也就是To Survivor,同時Eden區域的內存會在垃圾回收的過程中全部釋放),

另一個survivor(即From Survivor)里不能被回收的對象也會被放入這個survivor(即To Survivor),然后To Survivor 和 From Survivor的標記會互換,始終保證一個survivor是空的。

這里寫圖片描述
Eden Space和Survivor Space都屬於新生代,新生代中執行的垃圾回收被稱之為Minor GC(因為是對新生代進行垃圾回收,所以又被稱為Young GC),每一次Young GC后留下來的對象age加1。

注:GC為Garbage Collection,垃圾回收。

 

Old Gen老年代,用於存放新生代中經過多次垃圾回收仍然存活的對象,也有可能是新生代分配不了內存的大對象會直接進入老年代。經過多次垃圾回收都沒有被回收的對象,這些對象的年代已經足夠old了,就會放入到老年代。

當老年代被放滿的之后,虛擬機會進行垃圾回收,稱之為Major GC。由於Major GC除並發GC外均需對整個堆進行掃描和回收,因此又稱為Full GC。

heap區即堆內存,整個堆大小=年輕代大小 + 老年代大小。堆內存默認為物理內存的1/64(<1GB);默認空余堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制,可以通過MinHeapFreeRatio參數進行調整;默認空余堆內存大於70%時,JVM會減少堆直到-Xms的最小限制,可以通過MaxHeapFreeRatio參數進行調整。

下面我們來認識下非堆內存(非heap區)
Code Cache代碼緩存區,它主要用於存放JIT所編譯的代碼CodeCache代碼緩沖區的大小在client模式下默認最大是32m,在server模式下默認是48m,這個值也是可以設置的,它所對應的JVM參數為ReservedCodeCacheSizeInitialCodeCacheSize,可以通過如下的方式來為Java程序設置。

-XX:ReservedCodeCacheSize=128m
  • 1

CodeCache緩存區是可能被充滿的,當CodeCache滿時,后台會收到CodeCache is full的警告信息,如下所示:
“CompilerThread0” java.lang.OutOfMemoryError: requested 2854248 bytes for Chunk::new. Out of swap space?

注:JIT編譯器是在程序運行期間,將Java字節碼編譯成平台相關的二進制代碼。正因為此編譯行為發生在程序運行期間,所以該編譯器被稱為Just-In-Time編譯器。

Perm Gen全稱是Permanent Generation space,是指內存的永久保存區域,因而稱之為永久代。這個內存區域用於存放Class和Meta的信息,Class在被 Load的時候被放入這個區域。因為Perm里存儲的東西永遠不會被JVM垃圾回收的,所以如果你的應用程序LOAD很多CLASS的話,就很可能出現PermGen space錯誤。默認大小為物理內存的1/64。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM