年輕代:
所有新生成的對象首先都是放在年輕代的。年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對象。年輕代分三個區(qū)。一個Eden區(qū),兩個 Survivor區(qū)(一般而言)。大部分對象在Eden區(qū)中生成。當(dāng)Eden區(qū)滿時,還存活的對象將被復(fù)制到Survivor區(qū)(兩個中的一個),當(dāng)這個 Survivor區(qū)滿時,此區(qū)的存活對象將被復(fù)制到另外一個Survivor區(qū),當(dāng)這個Survivor去也滿了的時候,從第一個Survivor區(qū)復(fù)制 過來的并且此時還存活的對象,將被復(fù)制“年老區(qū)(Tenured)”。需要注意,Survivor的兩個區(qū)是對稱的,沒先后關(guān)系,所以同一個區(qū)中可能同時 存在從Eden復(fù)制過來 對象,和從前一個Survivor復(fù)制過來的對象,而復(fù)制到年老區(qū)的只有從第一個Survivor去過來的對象。而且,Survivor區(qū)總有一個是空 的。同時,根據(jù)程序需要,Survivor區(qū)是可以配置為多個的(多于兩個),這樣可以增加對象在年輕代中的存在時間,減少被放到年老代的可能。
年老代:
在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對象,就會被放到年老代中。因此,可以認(rèn)為年老代中存放的都是一些生命周期較長的對象。
持久代:
用于存放靜態(tài)文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應(yīng)用可能動態(tài)生成或者調(diào)用一些class,例如Hibernate 等,在這種時候需要設(shè)置一個比較大的持久代空間來存放這些運(yùn)行過程中新增的類。持久代大小通過-XX:MaxPermSize=<N>進(jìn)行設(shè) 置。
什么情況下觸發(fā)垃圾回收
由于對象進(jìn)行了分代處理,因此垃圾回收區(qū)域、時間也不一樣。GC有兩種類型:Scavenge GC 和Full GC 。
Scavenge GC
一般情況下,當(dāng)新對象生成,并且在Eden申請空間失敗時,就會觸發(fā)Scavenge GC,對Eden區(qū)域進(jìn)行GC,清除非存活對象,并且把尚且存活的對象移動到Survivor區(qū)。然后整理Survivor的兩個區(qū)。這種方式的GC是對 年輕代的Eden區(qū)進(jìn)行,不會影響到年老代。因?yàn)榇蟛糠謱ο蠖际菑腅den區(qū)開始的,同時Eden區(qū)不會分配的很大,所以Eden區(qū)的GC會頻繁進(jìn)行。因 而,一般在這里需要使用速度快、效率高的算法,使Eden去能盡快空閑出來。
Full GC
對整個堆進(jìn)行整理,包括Young、Tenured和Perm。Full GC因?yàn)樾枰獙φ麄€對進(jìn)行回收,所以比Scavenge GC要慢,因此應(yīng)該盡可能減少Full GC的次數(shù)。在對JVM調(diào)優(yōu)的過程中,很大一部分工作就是對于FullGC的調(diào)節(jié)。有如下原因可能導(dǎo)致Full GC:
年老代(Tenured)被寫滿
持久代(Perm)被寫滿
System.gc()被顯示調(diào)用
上一次GC之后Heap的各域分配策略動態(tài)變化
串行處理器:
--適用情況:數(shù)據(jù)量比較小(100M左右);單處理器下并且對響應(yīng)時間無要求的應(yīng)用。
--缺點(diǎn):只能用于小型應(yīng)用
并行處理器:
--適用情況:“對吞吐量有高要求”,多CPU、對應(yīng)用響應(yīng)時間無要求的中、大型應(yīng)用。舉例:后臺處理、科學(xué)計(jì)算。
--缺點(diǎn):垃圾收集過程中應(yīng)用響應(yīng)時間可能加長
并發(fā)處理器:
--適用情況:“對響應(yīng)時間有高要求”,多CPU、對應(yīng)用響應(yīng)時間有較高要求的中、大型應(yīng)用。舉例:Web服務(wù)器/應(yīng)用服務(wù)器、電信交換、集成開發(fā)環(huán)境。
===================================
今天使用jmap和jhat試圖解決permgen out of memory的問題,找到了一個很好的文章:
http://blogs.sun.com/fkieviet/entry/how_to_fix_the_dreaded
貼個開頭,防止原帖丟了,連google的線索都沒有
How to fix the dreaded "java.lang.OutOfMemoryError: PermGen space" exception (classloader leaks)
In the previous blog entry Classloader leaks: the dreaded "java.lang.OutOfMemoryError: PermGen space" exception I explained how this type of problem can originate in the application code that you deploy to an application server. In this post I'll explain how to track down the leak so that you can fix it.
Profilers
Memory leak? Use a profiler. Right? Well... generally speaking the answer is yes, but classloader leaks are a bit special...