91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用finalize方法對垃圾回收有哪些影響

發布時間:2022-01-04 17:16:08 來源:億速云 閱讀:184 作者:柒染 欄目:大數據

今天就跟大家聊聊有關使用finalize方法對垃圾回收有哪些影響,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。


java提供了一個finalize方法,可以幫助我們進行資源釋放,類似于C++中的析構函數。但是目前普遍的認識是不要使用,為什么呢?就是因為對java虛擬機的垃圾回收有影響。

一、為什么有影響

我們都知道一個對象如果沒有了任何引用,java虛擬機就認為這個對象沒什么用了,就會對其進行垃圾回收,但是如果這個對象包含了finalize函數,性質就不一樣了。怎么不一樣了呢?

java虛擬機在進行垃圾回收的時候,一看到這個對象類含有finalize函數,就把這個函數交給FinalizerThread處理,而包含了這個finalize的對象就會被添加到FinalizerThread的執行隊列,并使用一個鏈表,把這些包含了finalize的對象串起來。

使用finalize方法對垃圾回收有哪些影響

他的影響在于只要finalize沒有執行,那么這些對象就會一直存在堆區,不過這里只是4個包含了finalize的對象,影響不是那么大,如果有一萬個或者是十萬個呢?這就影響大了。

finalize的原理其實很簡單,在這里簡要的梳理一下:

(1)對象在初始化的過程中會判斷是否重寫了finalize,方法是判斷兩個字段標志has_finalizer_flag和RegisterFinalizersAtInit。

(2)如果重寫了finalize,那就把當前對象注冊到FinalizerThread的ReferenceQueue隊列中。注冊之后的對象就叫做Finalizer。方法是調用register_finalizer函數。此時java虛擬機一看當前有這個對象的引用,于是就不進行垃圾回收了。

(3)對象開始被調用,FinalizerThread線程負責從ReferenceQueue隊列中獲取Finalizer對象。開始執行finalize方法,在執行之前,這個對象一直在堆中。

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

這就是整個過程。不過在這里我們主要看的是finalize方法對垃圾回收的影響,其實就是在第三步,也就是這個對象含有finalize,進入了隊列但一直沒有被調用的這段時間,會一直占用內存。

我們使用一個案例來分析一波:

 

二、案例演示

我們創建一個類

 1public 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被執行");
8        }
9    }
10    public static void main(String[] args) {   
11        for (int i = 0; i < 1000; i++) {
12            Fdd fdd = new Fdd(); 
13        }
14    }
15}
 

現在創建了類,我們設置一下參數。

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

在main方法中,創建了1000個Fdd對象,如果不執行finalize方法,那么因為沒有調用所以會進行垃圾回收,此時不斷我們創建多少個,都不會出現任何問題。但是如果存在finalize方法,就不一樣了。

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

我們看到每個對象都會執行finalize,在執行之前的這段時間一直會在堆區,執行完了就會被清理,所以你看到這里執行了不少于5次的finalize方法。但是對象一旦超出了我們設置的5M,就會出現內存溢出。一句話總結就是出現了對象堆積。現在使用MAT工具來分析一下。

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

下面這張圖就是分析的結果:

使用finalize方法對垃圾回收有哪些影響

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

看完上述內容,你們對使用finalize方法對垃圾回收有哪些影響有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新干县| 东辽县| 蒲江县| 许昌市| 萝北县| 秦皇岛市| 贵州省| 囊谦县| 南澳县| 南开区| 吉木萨尔县| 东乡县| 乃东县| 沽源县| 陆丰市| 宽甸| 丰县| 滨州市| 商南县| 昌江| 拉萨市| 延寿县| 巴彦县| 华安县| 上杭县| 涞水县| 亚东县| 洛宁县| 枣强县| 盐源县| 株洲县| 寻甸| 高唐县| 溧水县| 万盛区| 梨树县| 梁河县| 安福县| 家居| 铁力市| 金川县|