日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
一個(gè)GCRoot不可達(dá)的對(duì)象,會(huì)立刻被垃圾回收嗎?

 這個(gè)問題是我在刷??兔娼?jīng)的時(shí)候遇到的,還特地整理在了我的常規(guī)面試題文檔中,所以這道題主要考察的就是finalize方法的影響。

臺(tái)州ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!

java提供了一個(gè)finalize方法,可以幫助我們進(jìn)行資源釋放,類似于C++中的析構(gòu)函數(shù)。這篇文章對(duì)其進(jìn)行一個(gè)說(shuō)明。

一、為什么有影響

我們都知道一個(gè)對(duì)象GCRoot不可達(dá),java虛擬機(jī)就認(rèn)為是垃圾對(duì)象,就會(huì)進(jìn)行垃圾回收,但是如果這個(gè)對(duì)象包含了finalize函數(shù),性質(zhì)就不一樣了。怎么不一樣了呢?

java虛擬機(jī)在進(jìn)行垃圾回收的時(shí)候,一看到這個(gè)對(duì)象類含有finalize函數(shù),就把這個(gè)函數(shù)交給FinalizerThread處理,而包含了這個(gè)finalize的對(duì)象就會(huì)被添加到FinalizerThread的執(zhí)行隊(duì)列,并使用一個(gè)鏈表,把這些包含了finalize的對(duì)象串起來(lái)。

他的影響在于只要finalize沒有執(zhí)行,那么這些對(duì)象就會(huì)一直存在堆區(qū),不過(guò)這里只是4個(gè)包含了finalize的對(duì)象,影響不是那么大,如果有一萬(wàn)個(gè)或者是十萬(wàn)個(gè)呢?這就影響大了。

finalize的原理其實(shí)很簡(jiǎn)單,在這里簡(jiǎn)要的梳理一下:

(1)對(duì)象在初始化的過(guò)程中會(huì)判斷是否重寫了finalize,方法是判斷兩個(gè)字段標(biāo)志has_finalizer_flag和RegisterFinalizersAtInit。

(2)如果重寫了finalize,那就把當(dāng)前對(duì)象注冊(cè)到FinalizerThread的ReferenceQueue隊(duì)列中。注冊(cè)之后的對(duì)象就叫做Finalizer。方法是調(diào)用register_finalizer函數(shù)。此時(shí)java虛擬機(jī)一看當(dāng)前有這個(gè)對(duì)象的引用,于是就不進(jìn)行垃圾回收了。

(3)對(duì)象開始被調(diào)用,F(xiàn)inalizerThread線程負(fù)責(zé)從ReferenceQueue隊(duì)列中獲取Finalizer對(duì)象。開始執(zhí)行finalize方法,在執(zhí)行之前,這個(gè)對(duì)象一直在堆中。

(4)對(duì)象執(zhí)行完畢之后,將這個(gè)Finalizer對(duì)象從隊(duì)列中移除,java虛擬機(jī)一看對(duì)象沒有引用了,就進(jìn)行垃圾回收了。

這就是整個(gè)過(guò)程。不過(guò)在這里我們主要看的是finalize方法對(duì)垃圾回收的影響,其實(shí)就是在第三步,也就是這個(gè)對(duì)象含有finalize,進(jìn)入了隊(duì)列但一直沒有被調(diào)用的這段時(shí)間,會(huì)一直占用內(nèi)存。

注意:這里其實(shí)就是一道面試題,我在看??途W(wǎng)上的面經(jīng)時(shí),看到有人被問到過(guò)。也就是GCRoot不可達(dá)的對(duì)象,會(huì)立刻被垃圾回收嗎?

我們使用一個(gè)案例來(lái)分析一波:

二、案例演示

我們創(chuàng)建一個(gè)類

 
 
 
 
  1. public class TestFinalizer { 
  2.     public static class Fdd { 
  3.      //分配1M 
  4.         private byte[] content = new byte[1024*1024]; 
  5.         @Override 
  6.         protected void finalize() { 
  7.             System.out.println("finalize被執(zhí)行"); 
  8.         } 
  9.     } 
  10.     public static void main(String[] args) {    
  11.         for (int i = 0; i < 1000; i++) { 
  12.          Fdd fdd = new Fdd();  
  13.         } 
  14.     } 

現(xiàn)在創(chuàng)建了類,我們?cè)O(shè)置一下參數(shù)。

 
 
 
 
  1. # 最大堆內(nèi)存 
  2. -Xmx5m  
  3. # 最小堆內(nèi)存 
  4. -Xms5m   
  5. # 堆內(nèi)存溢出錯(cuò)誤打印 
  6. -XX:+HeapDumpOnOutOfMemoryError  
  7. # 把堆相關(guān)信息保存在下列路徑 
  8. -XX:HeapDumpPath=F:/a.dump 

在main方法中,創(chuàng)建了1000個(gè)Fdd對(duì)象,如果不執(zhí)行finalize方法,那么因?yàn)闆]有調(diào)用所以會(huì)進(jìn)行垃圾回收,此時(shí)不斷我們創(chuàng)建多少個(gè),都不會(huì)出現(xiàn)任何問題。但是如果存在finalize方法,就不一樣了。

 
 
 
 
  1. java.lang.OutOfMemoryError: Java heap space 
  2. Dumping heap to F:/a.dump ... 
  3. finalize被執(zhí)行 
  4. finalize被執(zhí)行 
  5. finalize被執(zhí)行 
  6. finalize被執(zhí)行 
  7. finalize被執(zhí)行 
  8. finalize被執(zhí)行 
  9. finalize被執(zhí)行 
  10. Unable to create F:/a.dump: File exists 
  11. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
  12.     at com.fdd.chapter2.TestFinalizer$Fdd.(TestFinalizer.java:6) 
  13.     at com.fdd.chapter2.TestFinalizer.main(TestFinalizer.java:14) 

我們看到每個(gè)對(duì)象都會(huì)執(zhí)行finalize,在執(zhí)行之前的這段時(shí)間一直會(huì)在堆區(qū),執(zhí)行完了就會(huì)被清理,所以你看到這里執(zhí)行了不少于5次的finalize方法。但是對(duì)象一旦超出了我們?cè)O(shè)置的5M,就會(huì)出現(xiàn)內(nèi)存溢出。一句話總結(jié)就是出現(xiàn)了對(duì)象堆積?,F(xiàn)在使用MAT工具來(lái)分析一下。

Mat工具是一個(gè)插件,也可以自己下載一個(gè)。下載完成之后打開我們剛剛生成的a.dump即可。

下面這張圖就是分析的結(jié)果:

a這塊的內(nèi)容就是Finalizer,也就是我們的Fdd對(duì)象,b包含的比較多,亂七八糟的剩余信息。當(dāng)然你也可以查看一些其他的信息。都在MAT工具上。還有一些正在執(zhí)行的finalizer和準(zhǔn)備執(zhí)行的。

OK,一些其他的信息就不再展示了。

結(jié)論

一個(gè)GCRoot不可達(dá)的對(duì)象,不會(huì)立刻被垃圾回收,首先還會(huì)判斷是否包含了finalize方法,如果有那就先執(zhí)行finalize方法,如果這樣的對(duì)象比較多,那么這部分對(duì)象及時(shí)GCRoot不可達(dá),變得沒用了,也會(huì)留在內(nèi)存中,影響程序的效率。

本文轉(zhuǎn)載自微信公眾號(hào)「愚公要移山」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系愚公要移山公眾號(hào)。


分享題目:一個(gè)GCRoot不可達(dá)的對(duì)象,會(huì)立刻被垃圾回收嗎?
本文來(lái)源:http://www.5511xx.com/article/copoejg.html