java gc 可以对方法区进行回收_浅谈 Java 之 GC
閱讀本文假設(shè)你對java內(nèi)存模型已有一些了解。
1、Java虛擬機中哪些內(nèi)存需要回收?
先來看看jvm內(nèi)存模型,如下圖
線程隔離的區(qū)域隨線程而生,隨線程而滅;程序計數(shù)器可保存著虛擬機字節(jié)碼指令的地址(可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器);棧中的棧幀(與方法關(guān)聯(lián))隨著方法的進入和退出執(zhí)行壓棧出棧操作。既然每一個棧幀與方法關(guān)聯(lián),那每個棧幀分配多少內(nèi)存基本上在類結(jié)構(gòu)確定下來就已知。可以看出線程隔離的區(qū)域內(nèi)存的分配和回收具有確定性,當(dāng)方法結(jié)束或線程結(jié)束時,內(nèi)存自然就進行回收了,不需要我們?nèi)タ紤]回收的問題。而在java堆和方法區(qū)來說,一個接口可能有多個實現(xiàn)類,我們只有在程序運行期間才知道創(chuàng)建了哪些對象,也即在運行時動態(tài)分配內(nèi)存,并且是否回收是根據(jù)對象是否還可用進行回收判斷的,java的GC關(guān)注的就是這部分的內(nèi)存。
2、什么時候回收?
當(dāng)對象已經(jīng)“死亡“(即不可能再被任何途徑使用的對象)。
那么判斷對象是否存活的算法有哪些?
(1)引用計數(shù)算法:給對象添加一個引用計數(shù)器,每當(dāng)有一個地方引用它,計數(shù)器加1;引用失效時,計數(shù)器減1,任何計數(shù)器為0的對象就是不可能再被使用的。該算法實現(xiàn)簡單,判斷效率高,但是Java虛擬機里并沒有選用該算法來管理內(nèi)存,因為該算法很難解決對象相互循環(huán)引用問題(相互引用的對象除了它們倆之間沒有其他別的引用)。
(2)可達性分析算法:通過一系列的“GC Roots”作為對象的起點,從這些節(jié)點開始向下搜索,搜索走過的路徑稱為引用鏈,當(dāng)一個對象到GC Roots沒有任何引用鏈相連(即不可達),則該對象是不可用的。如下圖對象5、6為可回收對象。
在Java中,可作為GC Roots 的對象包括以下:
1) 虛擬機棧(棧幀中的本地變量表)中引用的對象;
2) 方法區(qū)中類靜態(tài)屬性引用的對象;
3) 方法區(qū)中常量引用的對象;
4) 本地方法棧中JNI(Java Native Interface)引用的對象。
但是,請注意,不可達對象并非是“非死不可”,宣告對象“死亡”要經(jīng)過至少兩次標記過程,沒有引用鏈到達GC Roots標記第一次,并進行篩選,篩選的條件是此對象是否有必要執(zhí)行finalize()方法。當(dāng)對象沒有重寫finalize()方法時或finalize()已被虛擬機調(diào)用過,虛擬機將這兩種情況視為沒有必要執(zhí)行。Finalize() 方法是對象自我拯救的最后機會,資源重新與引用鏈上的任何一個對象建立關(guān)聯(lián),在第二次標記它將被移除出即將回收的集合。
方法區(qū)上的回收時機
垃圾回收包含兩部分內(nèi)容:廢棄常量和無用的類。
廢棄常量:與java堆對象回收相似,沒有再被任何對象引用,就會被回收;
無用的類:滿足以下條件,即為無用類,可被回收。
1) 該類的所有實例都已經(jīng)被回收,java堆中不存在該類的任何實例;
2) 加載該類的ClassLoader已經(jīng)被回收;
3) 該類對應(yīng)的java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。
3、垃圾回收算法
(1)標記-清除算法:算法分為“標記”和“清除”兩個階段,首先標記出所有要回收的對象,然后統(tǒng)一回收被標記的對象,由于死亡的對象大部分不是連續(xù)的,該算法會較多的內(nèi)存碎片,在下一次對較大對象分配內(nèi)存時可能會因為無法分配足夠大的連續(xù)空間而再次進行垃圾回收;
(2)復(fù)制算法:將內(nèi)存進行分區(qū),一塊區(qū)域用完就進行垃圾回收,把存活對象復(fù)制到另一塊區(qū)域,然后清空原來區(qū)域。在新生代中就是使用復(fù)制算法,把內(nèi)存以8:1:1分配,分別稱為Eden,From Survivor,To Survivor,至于為什么要8:1:1分配,可以參考以下兩個鏈接
(3)標記-整理算法:與標記清理相似,但后續(xù)不是直接清理而是先移到一端后在進行清理,避免了該內(nèi)存里的內(nèi)存碎片產(chǎn)生。
(4)分代回收算法:新生代使用復(fù)制算法,老年代使用標記-整理算法
書暫時看到這部分,下次再來講講垃圾回收算法在jvm的基本實現(xiàn)及具體的垃圾回收器。
來源:https://www.cnblogs.com/X-huang/p/10811723.html
超強干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的java gc 可以对方法区进行回收_浅谈 Java 之 GC的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java class 转 字节_[转]J
- 下一篇: java实现登陆面试题_【Javaweb