日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java对象垃圾回收调用,JVM垃圾回收之哪些对象可以被回收

發(fā)布時(shí)間:2024/7/19 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java对象垃圾回收调用,JVM垃圾回收之哪些对象可以被回收 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.背景

Java語言相比于C和C++,一個(gè)最大的特點(diǎn)就是不需要程序員自己手動(dòng)去申請(qǐng)和釋放內(nèi)存,這一切交由JVM來完成。在Java中,運(yùn)行時(shí)的數(shù)據(jù)區(qū)域分為程序計(jì)數(shù)器、Java虛擬機(jī)棧、本地方法棧、方法區(qū)和堆。其中,程序計(jì)數(shù)器、虛擬機(jī)棧和本地方法棧是線程私有的,線程銷毀后自動(dòng)釋放。垃圾回收的行為發(fā)生在堆和方法區(qū),主要是堆,而堆中存儲(chǔ)的主要是對(duì)象。那么自然而然地就會(huì)有這么幾個(gè)問題,哪些對(duì)象可以被回收?通過什么方式回收?本文主要探討第一個(gè)問題,以及JVM對(duì)Java中幾種引用的回收策略。

2.如何判斷一個(gè)對(duì)象是否可以被回收 2.1 引用計(jì)數(shù)法

主要思想是:給對(duì)象添加一個(gè)引用計(jì)數(shù)器,這個(gè)對(duì)象被引用一次,計(jì)數(shù)器就加1;不再引用了,計(jì)數(shù)器就減1。如果一個(gè)對(duì)象的引用計(jì)數(shù)器為0,說明沒有人使用這個(gè)對(duì)象,那么這個(gè)對(duì)象就可以被回收了。這種方法實(shí)現(xiàn)起來比較簡單,效率也比較高,大多數(shù)情況下都是有效的。但是,這種方法有一個(gè)漏洞。比如A.property = B,B.property = A,A和B兩個(gè)對(duì)象互相引用,并且沒有其他對(duì)象引用A和B。按照引用計(jì)數(shù)法的思想,A和B對(duì)象的引用計(jì)數(shù)器都不為0,都不能被釋放,但實(shí)際情況是A和B已經(jīng)沒人使用他們了,這就造成了內(nèi)存泄漏。所以,引用計(jì)數(shù)法雖然實(shí)現(xiàn)簡單,但并不是一個(gè)完美的解決方案,實(shí)際中的Java也沒有采用它。

2.2 可達(dá)性分析算法

主要思想是:首先確定確定一系列肯定不能被回收的對(duì)象,即GC Roots。然后,從這些GC Roots出發(fā),向下搜索,去尋找它直接和間接引用的對(duì)象。最后,如果一個(gè)對(duì)象沒有被GC Roots直接或間接地引用,那么這個(gè)對(duì)象就可以被回收了。這種方法可以有效解決循環(huán)引用的問題,實(shí)際中Java也是采用這種判斷方法。那么問題來了,哪些對(duì)象可以作為GC Roots呢?這里可以使用MAT工具進(jìn)行觀察。運(yùn)行下面的demo:

import java.util.concurrent.TimeUnit; public class GCRootsTest { public static void main(String[] args) throws InterruptedException { Object o = new Object(); TimeUnit.SECONDS.sleep(100); }}

主線程sleep的時(shí)候,在terminal窗口執(zhí)行jmap -dump:format=b,live,file=heapdump.bin 2872命令,生成堆轉(zhuǎn)儲(chǔ)快照dump文件,其中2872是進(jìn)程id,可以使用jps命令查看。然后使用MAT工具打開dump文件,可以很明顯地看到一共有四類對(duì)象可以作為GC Roots,下面詳細(xì)介紹下。

第一類,系統(tǒng)類對(duì)象(System Class)。比如,java.lang.String的Class對(duì)象,這個(gè)也很好理解,如果這些核心的系統(tǒng)類對(duì)象被回收了,程序就沒辦法運(yùn)行了。

第二類,native方法引用的對(duì)象。

第三類,活動(dòng)線程中正在引用的對(duì)象。可以看出,代碼中變量o指向的Object對(duì)象可以被當(dāng)作GC Roots。

第四類,正在加鎖的對(duì)象。

3.Java中的幾種引用

在可達(dá)性分析算法中,判斷一個(gè)對(duì)象是不是可以被回收,主要看從GC Roots出發(fā)是否可以找到一個(gè)引用指向該對(duì)象。java中的引用一共有四種,按照引用的強(qiáng)弱依次為強(qiáng)引用(Strong Reference)、軟引用(Soft Reference)、弱引用(Weak Reference)、虛引用(Phantom Reference)。這樣就可以對(duì)不同引用指向的對(duì)象采取不同的回收策略。比如一個(gè)強(qiáng)引用指向一個(gè)對(duì)象,那么這個(gè)對(duì)象肯定不會(huì)被回收,哪怕發(fā)生OOM。而對(duì)于弱引用指向的對(duì)象,只要發(fā)生垃圾回收,該對(duì)象就會(huì)被回收。下面詳細(xì)介紹下不同引用的用法。

3.1強(qiáng)引用

所謂強(qiáng)引用,就是平時(shí)使用最多的,類似于Object obj = new Object()的引用。垃圾回收器永遠(yuǎn)不會(huì)回收被強(qiáng)引用指向的對(duì)象。

3.2軟引用

軟引用,在Java中使用SoftReference類來實(shí)現(xiàn)軟引用。在下面的代碼中,softReference作為軟用指向一個(gè)Object對(duì)象,而otherObject變量可以通過軟引用的get方法間接引用到Object對(duì)象。

public static void main(String[] args) { // 軟引用 SoftReference

總結(jié)

以上是生活随笔為你收集整理的Java对象垃圾回收调用,JVM垃圾回收之哪些对象可以被回收的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。