JVM常用垃圾回收算法----內容爲自己記憶所用

瞭解垃圾回收算法先了解一些東西

什麼是對象死亡?

當一個對象當不在被調用時,便判定爲死亡

如何判定對象死亡?

兩種方法:

引用計數器

給對象添加一個計數器,當這個對象被調用時該計數器+1,當引用失效時該計數器-1。

當計數器爲0時表示該對象不可能再被使用。此時該對象便定義爲死亡

根搜索算法

通過一個名爲GC Roots的對象作爲起始點,然後從這個節點開始向下搜索,可以達到的節點進行了標記。當沒有標記的對象則爲已經死亡的對象。

引用?

爲什麼會說引用,因爲引用和引用計數法和根搜索法有關

引用可以分爲四種

強引用

強引用是指程序在代碼中普遍存在類似   Object obj=new Object() 這種便是強引用,只要強引用還在,垃圾回收機器永遠不會回收被引用的對象。

軟引用

描述一些還有用,但並非必需的對象。在內存將要溢出前會將這些對象進行回收。

弱引用

也是來描述非必需的對象,這些對象無論內存是否足夠,在下一次垃圾回收器之前進行回收

虛引用

它時最弱的引用,唯一的作用就是在垃圾回收時得到一個系統通知。

常用垃圾回收算法一共有四種

1.標記清除法

標記清除法是當內存不夠用的時候,暫停當前程序,運行使用該算法

標記清除法,正如同它名字一樣。分爲兩個步驟分爲標記和清除

標記:標記所有根部可到達的對象,給可達到的對象所有打上一個標記

清除:遍歷所有元素,將未標記所有對象的內存回收

缺點:

遍歷兩遍所以效率不高

當它回收後,內存都是一段一段不連續的地址,當需要更大內存時,卻需要其它的算法來重新清除內存。

2.複製算法

複製算法就是將所有內存對半分爲兩部分ab都爲內存的一半。每次使用只用內存的一半,也就是ab只使用其中一個。

當需要內存時,都存入a部分,當內存a需要清理時,,將a所有的活動的對象存入b中,把所有不需要的內存回收。

此時b就是現在所存的內存,而a就是空閒內存。

其實就是相當於兩個相同長度的數組ab。a和b的和爲總內存。

當需要內存是,將存入a,最後a中有些空間已經被取出,但是此時a數組已經遍歷到了最後前邊內存雖然爲空閒但是也無法使用,所以將a中所存的數據都按順序存入b中,此時就將之前不用內存又可以使用了

優點:

這個算法明顯解決了標記清理法的缺點

缺點:

但是又產生了一個的缺點就是將所有內存減少爲原來的一半

3.標記整理法

標記整理就是在標記清除法上改進的。分爲標記和整理

1.首先將所有需要的對象進行標記

2.其次將已經標記的對象向一端,而將未標記的對象移除內存。

優點:

這樣就解決了標記清除法的弊端,這樣所有的需要的對象已經存儲到 一端連續的內存,這樣就不存在一個個片段的內存。都是一段連續的內存。

缺點:

效率更加的低,對需要清除的內存和活動內存都需要標記。

4.分代收集

分代收集算法,相當於將前3個算法結合

瞭解這個算法首先得了解三個名詞:新生代、永久代、老生代。

新生代:就是活動時間不長的對象。它所佔用內存時間不長就要回收的。

老生代:相對新生代,它存活時間比較長。它所佔用內此時間比較長但是還是要回收的。

永久代:它幾乎永久佔用內存。

新生代和老生代在jvm堆中存儲。

永久代存儲在方法區。

新生代會佔用內存的20%,但是對於新生代應用的是複製算法,相當於只佔了10%的內存。因爲新生代內存本來存活時間短所以清理的也快。

老生代使佔用了內存80%,老生代是有新生代中移過來的,比如有些對象經歷了10次內存清理,則此時把新生代的對象移到老生代中。因爲老生代存活時間比較長所以佔用內存也比較多,使用的算法也是標記清除法。

永生代:使用算法未標記清理法。


上邊內容爲我在網上找資料學習加深自己的記憶

我學習文章的鏈接:https://blog.csdn.net/mccand1234/article/details/52078645

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