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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【深入Java虚拟机JVM 07】JVM如何判断对象已死

發(fā)布時間:2025/3/20 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深入Java虚拟机JVM 07】JVM如何判断对象已死 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

說明:文章所有內容均摘自《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版)》

?

?

在堆里面存放著Java世界中幾乎所有的對象實例,垃圾收集器在對堆進行回收前,第一件事情就是要確定這些對象之中哪些還“存活”著,哪些已經“死去”(即不可能再被任何途徑使用的對象)。

?

1 引用計數算法

很多教科書判斷對象是否存活的算法是這樣的:給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的對象就是不可能再被使用的。作者面試過很多的應屆生和一些有多年工作經驗的開發(fā)人員,他們對于這個問題給予的都是這個答案。

客觀地說,引用計數算法(Reference Counting)的實現簡單,判定效率也很高,在大部分情況下它都是一個不錯的算法,也有一些比較著名的應用案例,例如微軟公司的COM(Component Object Model)技術、使用ActionScript 3的FlashPlayer、Python語言和在游戲腳本領域被廣泛應用的Squirrel中都使用了引用計數算法進行內存管理。但是,至少主流的Java虛擬機里面沒有選用引用計數算法來管理內存,其中最主要的原因是它很難解決對象之間相互循環(huán)引用的問題。

舉個簡單的例子,請看代碼清單3-1中的testGC()方法:對象objA和objB都有字段instance,賦值令objA.instance=objB及objB.instance=objA,除此之外,這兩個對象再無任何引用,實際上這兩個對象已經不可能再被訪問,但是它們因為互相引用著對方,導致它們的引用計數都不為0,于是引用計數算法無法通知GC收集器回收它們。

/***testGC()方法執(zhí)行后,objA和objB會不會被GC呢?*@author zzm*/ public class ReferenceCountingGC{public Object instance=null;private static final int_1MB=1024*1024;/***這個成員屬性的唯一意義就是占點內存,以便能在GC日志中看清楚是否被回收過*/private byte[]bigSize=new byte[2*_1MB];public static void testGC(){ReferenceCountingGC objA=new ReferenceCountingGC();ReferenceCountingGC objB=new ReferenceCountingGC();objA.instance=objB;objB.instance=objA;objA=null;objB=null; //假設在這行發(fā)生GC,objA和objB是否能被回收?System.gc();} }//運行結果 [Full GC(System)[Tenured:0 K->210K(10240K),0.0149142secs]4603K->210K(19456K),[Perm:2999K-> 2999K(21248K)],0.0150007 secs][Times:user=0.01 sys=0.00,real=0.02 secs] Heap def new generation total 9216K,used 82K[0x00000000055e0000,0x0000000005fe0000,0x0000000005fe0000) Eden space 8192K,1%used[0x00000000055e0000,0x00000000055f4850,0x0000000005de0000) from space 1024K,0%used[0x0000000005de0000,0x0000000005de0000,0x0000000005ee0000) to space 1024K,0%used[0x0000000005ee0000,0x0000000005ee0000,0x0000000005fe0000) tenured generation total 10240K,used 210K[0x0000000005fe0000,0x00000000069e0000,0x00000000069e0000) the space 10240K,2%used[0x0000000005fe0000,0x0000000006014a18,0x0000000006014c00,0x00000000069e0000) compacting perm gen total 21248K,used 3016K[0x00000000069e0000,0x0000000007ea0000,0x000000000bde0000) the space 21248K,14%used[0x00000000069e0000,0x0000000006cd2398,0x0000000006cd2400,0x0000000007ea0000) No shared spaces configured.

從運行結果中可以清楚看到,GC日志中包含“4603K->210K”,意味著虛擬機并沒有因為這兩個對象互相引用就不回收它們,這也從側面說明虛擬機并不是通過引用計數算法來判斷對象是否存活的。

?

2. 可達性分析算法

在主流的商用程序語言(Java、C#,甚至包括前面提到的古老的Lisp)的主流實現中,都是稱通過可達性分析(Reachability Analysis)來判定對象是否存活的。這個算法的基本思路就是通過一系列的稱為“GC Roots”的對象作為起始點,從這些節(jié)點開始向下搜索,搜索所走過的路徑稱為引用鏈(Reference ?Chain),當一個對象到GC ?Roots沒有任何引用鏈相連(用圖論的話來說,就是從GC Roots到這個對象不可達)時,則證明此對象是不可用的。如圖3-1所示,對象object 5、object 6、object 7雖然互相有關聯(lián),但是它們到GC Roots是不可達的,所以它們將會被判定為是可回收的對象。

在Java語言中,可作為GC Roots的對象包括下面幾種:

  • 虛擬機棧(棧幀中的本地變量表)中引用的對象。
  • 方法區(qū)中類靜態(tài)屬性引用的對象。
  • 方法區(qū)中常量引用的對象。
  • 本地方法棧中JNI(即一般說的Native方法)引用的對象。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的【深入Java虚拟机JVM 07】JVM如何判断对象已死的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。