深入理解JAVA虛擬機(三)內存分配與回收機制

一.JAVA內存

Java的內存通常分爲堆內存和非堆內存,堆內存由 Java 對象使用,非堆內存則用於存放 JNI、Java 線程對象等非 Java 數據。

 

二.垃圾收集

JVM Generational Collecting(分代)原理是這樣的:把對象分爲年青代(Young)、年老代(Tenured)、持久代(Perm),對不同生命週期的對象使用不同的算法。(基於對對象生命週期分析)

1. Young(年輕代)

年輕代分三個區。一個 Eden 區,兩個 Survivor 區。大部分對象在 Eden 區中生成。 倖存者 0 區(Survivor 0 space)和倖存者 1 區(Survivor1 space):當伊甸園的空間用完時,程序又需要創建對象;此時 JVM 的垃圾回收器將對伊甸園區進行垃圾回收,將伊甸園區中的不再被其他對象所引用的對象進行銷燬工作。同時將伊甸園中的還有其他對象引用的對象移動到倖存者 0 區。倖存者 0 區就是用於存放伊甸園垃圾回收時所幸存下來的 JAVA 對象。當將伊甸園中的還有其他對象引用的對象移動到倖存者 0 區時,如果倖存者 0 區也沒有空間來存放這些對象時,JVM 的垃圾回收器將對倖存者 0 區進行垃圾回收處理,將倖存者 0 區中不在有其他對象引用的 JAVA 對象進行銷燬,將倖存者 0 區中還有其他對象引用的對象移動到倖存者 1 區。倖存者 1 區的作用就是用於存放倖存者 0 區垃圾回收處理所幸存下來的JAVA 對象。 


2.Tenured(年老代)

年老代存放從年輕代存活的對象。一般來說年老代存放的都是生命期較長的對象。  


3.Perm(持久代)

用於存放靜態文件,如今 Java 類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應用可能動態生成或者調用一些 class,例如 Hibernate 等, 在這種時候需要設置一個比較大的持久代空間來存放這些運行過程中新增的類。持久代大小通過-XX:MaxPermSize=進行設置。

 

舉個例子:當在程序中生成對象時,正常對象會在年輕代中分配空間,如果是過大的對象也可能會直接在年老代生成(據觀測在運行某程序時候每次會生成一個十兆的 空間用收發消息,這部分內存就會直接在年老代分配)。年輕代在空間被分配完的時候就會發起內存回收,大部分內存會被回收,一部分倖存的內存會被拷貝至 Survivor 的 from 區,經過多次回收以後如果from區內存也分配完畢,就會也發生內存回收然後將剩餘的對象拷貝至to區。等到 to 區也滿的時 候,就會再次發生內存回收然後把倖存的對象拷貝至年老區。

 

通常我們說的 JVM 內存回收總是在指堆內存回收,確實只有堆中的內容是動態申請分配的,所以以上對象的年輕代和年老代都是指的 JVM 的 Heap 空間,而持久代則是之前提到的 Method Area,不屬於 Heap。



補充:http://blog.csdn.net/wzy_1988/article/details/47722649

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章