瞭解垃圾回收算法先了解一些東西
什麼是對象死亡?
當一個對象當不在被調用時,便判定爲死亡
如何判定對象死亡?
兩種方法:
引用計數器
給對象添加一個計數器,當這個對象被調用時該計數器+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