可以做代發(fā)貨源的網(wǎng)站seo外包公司怎么樣
如何判斷堆上的對象沒有被引用?
常見的有兩種判斷方法:引用計(jì)數(shù)法和可達(dá)性分析法。
引用計(jì)數(shù)法會為每個對象維護(hù)一個引用計(jì)數(shù)器,當(dāng)對象被引用時加1,取消引用時減1。
引用計(jì)數(shù)法的優(yōu)點(diǎn)是實(shí)現(xiàn)簡單,缺點(diǎn)有兩點(diǎn):
1.每次引用和取消引用都需要維護(hù)計(jì)數(shù)器,對系統(tǒng)性能會有一定的影響
2.存在循環(huán)引用問題,所謂循環(huán)引用就是當(dāng)A引用B,B同時引用A時會出現(xiàn)對象無法回收的問題。
可達(dá)性分析算法
Java使用的是可達(dá)性分析算法來判斷對象是否可以被回收??蛇_(dá)性分析將對象分為兩類:垃圾回收的根對象(GC
Root)和普通對象,對象與對象之間存在引用關(guān)系。
下圖中A到B再到C和D,形成了一個引用鏈,可達(dá)性分析算法指的是如果從某個到GC Root對象是可達(dá)的,對象就
不可被回收。
可達(dá)性分析算法
哪些對象被稱之為GC Root對象呢?
? 線程Thread對象,引用線程棧幀中的方法參數(shù)、局部變量等。
? 系統(tǒng)類加載器加載的java.lang.Class對象,引用類中的靜態(tài)變量。
? 監(jiān)視器對象,用來保存同步鎖synchronized關(guān)鍵字持有的對象。
? 本地方法調(diào)用時使用的全局對象。
如何判斷堆上的對象有沒有被引用?
引用計(jì)數(shù)法會為每個對象維護(hù)一個引用計(jì)數(shù)器,當(dāng)對象被引用時加1,取消引用時減
1,存在循環(huán)引用問題所以Java沒有使用這種方法。
Java使用的是可達(dá)性分析算法來判斷對象是否可以被回收??蛇_(dá)性分析將對象分為兩
類:垃圾回收的根對象(GC Root)和普通對象。
可達(dá)性分析算法指的是如果從某個到GC Root對象是可達(dá)的,對象就不可被回收。最
常見的是GC Root對象會引用棧上的局部變量和靜態(tài)變量導(dǎo)致對象不可回收
JVM 中都有哪些引用類型
? 強(qiáng)引用,JVM中默認(rèn)引用關(guān)系就是強(qiáng)引用,即是對象被局部變量、靜態(tài)變量等GC Root關(guān)聯(lián)的對象引用,只要
這層關(guān)系存在,普通對象就不會被回收。
? 軟引用,軟引用相對于強(qiáng)引用是一種比較弱的引用關(guān)系,如果一個對象只有軟引用關(guān)聯(lián)到它,當(dāng)程序內(nèi)存不足
時,就會將軟引用中的數(shù)據(jù)進(jìn)行回收。軟引用主要在緩存框架中使用。
? 弱引用,弱引用的整體機(jī)制和軟引用基本一致,區(qū)別在于弱引用包含的對象在垃圾回收時,不管內(nèi)存夠不夠都
會直接被回收,弱引用主要在ThreadLocal中使用。
? 虛引用(幽靈引用/幻影引用),不能通過虛引用對象獲取到包含的對象。虛引用唯一的用途是當(dāng)對象被垃圾回
收器回收時可以接收到對應(yīng)的通知。直接內(nèi)存中為了及時知道直接內(nèi)存對象不再使用,從而回收內(nèi)存,使用了
虛引用來實(shí)現(xiàn)。
? 終結(jié)器引用,終結(jié)器引用指的是在對象需要被回收時,終結(jié)器引用會關(guān)聯(lián)對象并放置在Finalizer類中的引用隊(duì)
列中,在稍后由一條由FinalizerThread線程從隊(duì)列中獲取對象,然后執(zhí)行對象的finalize方法,在對象第二次
被回收時,該對象才真正的被回收
ThreadLocal中為什么要使用弱引用?
ThreadLocal可以在線程中存放線程的本地變量,保證數(shù)據(jù)的線程安全。
ThreadLocal中是這樣去保存對象的:
1、在每個線程中,存放了一個ThreadLocalMap對象,本質(zhì)上就是一個數(shù)組實(shí)現(xiàn)的哈希表,里邊存放多個Entry對象。
2、每個Entry對象繼承自弱引用,內(nèi)部存放ThreadLocal對象。同時用強(qiáng)引用,引用保存的ThreadLocal對應(yīng)的value值。
以代碼為例:
threadLocal.set(new User(1,“main線程對象”));
User user = threadLocal.get();
不再使用Threadlocal對象時, threadlocal = null;由于是弱引用,那么在垃圾回收之后,ThreadLocal對象就可以被
回收。
此時還有Entry對象和value對象沒有能被回收,所以在ThreadLocal類的set、get、remove方法中,在某些特定條件滿
足的情況下,會主動刪除這兩個對象。
如果一直不調(diào)用set、get、remove方法或者調(diào)用了沒有滿足條件,這部分對象就會出現(xiàn)內(nèi)存泄漏。強(qiáng)烈建議在
ThreadLocal不再使用時,調(diào)用remove方法回收將Entry對象的引用關(guān)系去掉,這樣就可以回收這兩個對象了
ThreadLocal中為什么要使用弱引用?
當(dāng)threadlocal對象不再使用時,使用弱引用可以讓對象被回收;因?yàn)閮H有弱引用沒
有強(qiáng)引用的情況下,對象是可以被回收的。
弱引用并沒有完全解決掉對象回收的問題,Entry對象和value值無法被回收,所以合
理的做法是手動調(diào)用remove方法進(jìn)行回收,然后再將threadlocal對象的強(qiáng)引用解除