1.jvm內(nèi)存分配與回收
1.1 對象優(yōu)先在Eden區(qū)分配
新生代GC(Minor GC):指發(fā)生新生代的垃圾收集動作抖拦,Minor GC非常頻繁,回收速度一般也比較快舷暮。
老年代GC (Major GC/Full GC):指發(fā)生在老年代的GC态罪,出現(xiàn)了Major GC 經(jīng)常會伴隨至少一次的Minor GC(并非絕對),Major GC的速度一般會比Minor GC的慢10倍以上脚牍。
當(dāng)對象在Eden 區(qū)沒有足夠空間分配向臀,而且survior 區(qū)也無法存入時,只有通過分配擔(dān)保機(jī)制把新生代的對象提前轉(zhuǎn)移到老年代中去诸狭。老年代空間足夠放這個對象時不會出現(xiàn)Full GC券膀。
大對象直接進(jìn)入老年代:大對象就是需要大量連續(xù)內(nèi)存空間的對象(比如:字符串君纫,數(shù)組)
為什么這么做:避免為大對象分配內(nèi)存時由于分配擔(dān)保機(jī)制帶來的復(fù)制而降低效率。
長期存活的對象將進(jìn)入老年代芹彬。默認(rèn)年齡增加到15蓄髓,就會晉升到老年代中玩郊,就會被晉升到老年代中预茄。對象晉升到老年代的年齡閾值,可以通過參數(shù) -XX:MaxTenuringThreshold 來設(shè)置
2.如何判斷對象可以被回收
2.1 引用計數(shù)法——沒有使用,因為很難解決對象之間相互循環(huán)引用的問題。
2.2 可達(dá)性分析算法——通過一系列的被稱為“GC Roots” 的對象作為起點裁眯,從這些節(jié)點開始向下搜索晌坤,節(jié)點所走過的路徑稱為引用鏈,當(dāng)一個對象到GC Roots 沒有任何引用鏈相連的話,則證明此對象是不可用的鲜戒。
2.3?finalize()方法最終判定對象是否存活
即使在可達(dá)性分析算法中不可達(dá)的對象,也并非是“非死不可”的柏蘑,這時候它們暫時處于“緩刑”階段黔攒,要真正宣告一個對象死亡不傅,至少要經(jīng)歷再次標(biāo)記過程。
標(biāo)記的前提是對象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒有與GC Roots相連接的引用鏈。
2.5 如何判斷一個類是無用的類
1.該類所有的實例都已經(jīng)被回收叮趴,也就是 Java 堆中不存在該類的任何實例
2.加載該類的 ClassLoader 已經(jīng)被回收
3.該類對應(yīng)的 java.lang.Class 對象沒有在任何地方被引用般码,無法在任何地方通過反射訪問該類的方法
垃圾搜集算法
標(biāo)記-清除:
不足:
1.效率問題
2.空間問題(標(biāo)記清除后會產(chǎn)生大量不連續(xù)的碎片)
復(fù)制算法:
為了解決效率問題,“復(fù)制”收集算法出現(xiàn)了。它可以將內(nèi)存分為大小相同的兩塊蜓堕,每次使用其中的一塊慕淡。當(dāng)這一塊的內(nèi)存使用完后携兵,就將還存活的對象復(fù)制到另一塊去,然后再把使用的空間一次清理掉拂檩。這樣就使每次的內(nèi)存回收都是對內(nèi)存區(qū)間的一半進(jìn)行回收
標(biāo)記-整理算法: