jvm區域總體分兩類,heap區和非heap區。heap區又分:Eden Space(伊甸園)、Survivor Space(幸存者區)、Tenured Gen(老年代-養老區)。 非heap區又分:Code Cache(代碼緩存區)、Perm Gen(永久代)、Jvm Stack(java虛擬機棧)、Local Method Statck(本地方法棧)。
HotSpot虛擬機GC算法采用分代收集算法:
1、一個人(對象)出來(new 出來)后會在Eden Space(伊甸園)無憂無慮的生活,直到GC到來打破了他們平靜的生活。GC會逐一問清楚每個對象的情況,有沒有錢(此對象的引用)啊,因為GC想賺錢呀,有錢的才可以敲詐嘛。然后富人就會進入Survivor Space(幸存者區),窮人的就直接kill掉。
2、並不是進入Survivor Space(幸存者區)后就保證人身是安全的,但至少可以活段時間。GC會定期(可以自定義)會對這些人進行敲詐,億萬富翁每次都給錢,GC很滿意,就讓其進入了Genured Gen(養老區)。萬元戶經不住幾次敲詐就沒錢了,GC看沒有啥價值啦,就直接kill掉了。
3、進入到養老區的人基本就可以保證人身安全啦,但是億萬富豪有的也會揮霍成窮光蛋,只要錢沒了,GC還是kill掉。
分區的目的:新生區由於對象產生的比較多並且大都是朝生夕滅的,所以直接采用標記-清理算法。而養老區生命力很強,則采用復制算法,針對不同情況使用不同算法。
非heap區域中Perm Gen中放着類、方法的定義,jvm Stack區域放着方法參數、局域變量等的引用,方法執行順序按照棧的先入后出方式。
以上轉自:http://lhc1986.iteye.com/blog/1421832
以下轉自:http://www.cnblogs.com/xhr8334/archive/2011/12/01/2270994.html
JVM在程序運行過程當中,會創建大量的對象,這些對象,大部分是短周期的對象,小部分是長周期的對象,對於短周期的對象,需要頻繁地進行垃圾回收以保證無用對象盡早被釋放掉,對於長周期對象,則不需要頻率垃圾回收以確保無謂地垃圾掃描檢測。為解決這種矛盾,Sun JVM的內存管理采用分代的策略。
1)年輕代(Young Gen):年輕代主要存放新創建的對象,內存大小相對會比較小,垃圾回收會比較頻繁。年輕代分成1個Eden Space和2個Suvivor Space(命名為A和B)。當對象在堆創建時,將進入年輕代的Eden Space。垃圾回收器進行垃圾回收時,掃描Eden Space和A Suvivor Space,如果對象仍然存活,則復制到B Suvivor Space,如果B Suvivor Space已經滿,則復制到Old Gen。同時,在掃描Suvivor Space時,如果對象已經經過了幾次的掃描仍然存活,JVM認為其為一個持久化對象,則將其移到Old Gen。掃描完畢后,JVM將Eden Space和A Suvivor Space清空,然后交換A和B的角色(即下次垃圾回收時會掃描Eden Space和BSuvivor Space。這么做主要是為了減少內存碎片的產生。
我們可以看到:Young Gen垃圾回收時,采用將存活對象復制到到空的Suvivor Space的方式來確保盡量不存在內存碎片,采用空間換時間的方式來加速內存中不再被持有的對象盡快能夠得到回收。
2)年老代(Tenured Gen):年老代主要存放JVM認為生命周期比較長的對象(經過幾次的Young Gen的垃圾回收后仍然存在),內存大小相對會比較大,垃圾回收也相對沒有那么頻繁(譬如可能幾個小時一次)。年老代主要采用壓縮的方式來避免內存碎片(將存活對象移動到內存片的一邊,也就是內存整理)。當然,有些垃圾回收器(譬如CMS垃圾回收器)出於效率的原因,可能會不進行壓縮。
3)持久代(Perm Gen):持久代主要存放類定義、字節碼和常量等很少會變更的信息。