最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于JVM垃圾回收的java.lang.ref.Finalizer問題

 更新時間:2024年05月16日 09:05:35   作者:影??  
這篇文章主要介紹了關(guān)于JVM垃圾回收的java.lang.ref.Finalizer問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

JVM垃圾回收的java.lang.ref.Finalizer

基礎(chǔ)知識

Shallow Size

  • 對象自身占用的內(nèi)存大小,不包括它引用的對象

Retained Size

  • Retained Size=當(dāng)前對象大小+當(dāng)前對象可直接或間接引用到的對象的大小總和

可達性分析算法:

基本思路是通過一系列成為GC ROOTS 的對象作為起點,當(dāng)一個對象到 GC ROOTS 沒有任何相連,證明此對象是不可達,即被判斷為可回收的對象。

之后的過程是:

被標(biāo)記不可達的對象以后,進行第一次標(biāo)記,和第一次篩選,條件是該對象 有沒有必要執(zhí)行finalize方法

沒有必要執(zhí)行finalize方法的情況是

1.finalize已經(jīng)執(zhí)行過(finalize 方法只會被執(zhí)行一次)

2.該對象沒有重寫finalize方法

如果要執(zhí)行finalize方法,該對象進入一個F-Queue隊列,稍后有 一個優(yōu)先級為8的 finalizer線程來執(zhí)行(注意:如果一個對象在 finalize 方法中運行緩慢,將會導(dǎo)致隊列后的其他對象永遠等待,嚴(yán)重時將會導(dǎo)致系統(tǒng)崩潰)

GC對隊列中進行第二次標(biāo)記,如果在執(zhí)行finalize方法的時候?qū)⒆约汉虶C ROOTS關(guān)聯(lián)上,該對象即可逃離回收,否則,被回收掉

重要

對象是在已經(jīng)被GC識別為是垃圾后才丟到Queue中的,在queue中依然占用內(nèi)存

引用對象的類型

引用對象的類型第一篇已說過,分為以下類型

強引用>軟引用>弱引用>虛引用,

涉及到的相關(guān)類:

  • 軟引用:softReference 
  • 弱引用:weekRefernce
  • 虛引用:pathomReference

但還有一個特殊的引用:FinalReference類,該類也是JVM調(diào)優(yōu)的常見的調(diào)優(yōu)場景之一。

要了解FinalReference,先了解final()

final,finally和finalize()的區(qū)別?

前兩者我相信大多數(shù)人都能答出,但finalize()雖然也有人答出,但可能只是硬搬面試題答案。

1.final:修飾詞,作用于成員變量,方法和類。

  • 成員變量,基本數(shù)據(jù)類型表示該成員變量不可變更數(shù)值,對象表示該對象引用地址不可改變。
  • 方法,表示該方法不可重載
  • 類,表示該類不可被繼承

2.finally:是異常處理機制的一部分,表示總是執(zhí)行這段代碼,先執(zhí)行異常,后執(zhí)行finally

@Slf4j
public class FinallyDemo {
 
    public static void main(String[] args) {
        try {
            int i = 1 / 0;
            log.info("1/0");
        } catch (Exception e) {
            log.info("執(zhí)行異常");
        } finally {
            log.info("執(zhí)行finally片段");
        }
    }
}

// 打印結(jié)果:

// 10:36:09.777 [main] INFO com.gc.demo.finalize.finlly.FinallyDemo - 執(zhí)行異常

// 10:36:09.780 [main] INFO com.gc.demo.finalize.finlly.FinallyDemo - 執(zhí)行finally片段

3.finalize():是object的一個方法。簡簡單單的一句話,我想大多數(shù)人懂得,但其實我們應(yīng)該繼續(xù)深入。

Finalize()

Object源碼

public class Object {
    private static native void registerNatives();
    static {
        registerNatives();
    }
    .......
    @Deprecated(since="9")
    protected void finalize() throws Throwable { }
}

上述代碼可以看出:finalize()已被棄用,不建議使用

為什么finalize()已被棄用,不建議使用?

原因:容易導(dǎo)致堆內(nèi)存溢出。

為什么不直接刪除呢?

1. 兼容老舊項目

2. 是GC回收對象前,對該對象生前(被回收前)必須執(zhí)行的邏輯業(yè)務(wù),保證程序正常運行。例如:FileInputStream,源碼如下

public class FileInputStream extends InputStream{
    ......
    static class AltFinalizer {
    private final FileInputStream fis;
    AltFinalizer(FileInputStream fis) {
        this.fis = fis;
    }
    @Override
    @SuppressWarnings("deprecation")
    protected final void finalize() {
        try {
            if ((fis.fd != null) && (fis.fd != FileDescriptor.in)) {
                /* if fd is shared, the references in FileDescriptor
                 * will ensure that finalizer is only called when
                 * safe to do so. All references using the fd have
                 * become unreachable. We can call close()
                 */
                fis.close();
            }
        } catch (IOException ioe) {
            // ignore
        }
    }
}

FileInputStream類的close()方法大家都不陌生,用于關(guān)閉流輸入,但他被寫到finalize()方法內(nèi)。

原理:

JVM啟動時,檢測所有對象,是否實現(xiàn)了finalize()方法,如果實現(xiàn)了,就會該對象標(biāo)記為finalizer類,且交由finalizerThread線程管理,當(dāng)GC回收時,finalizerThread線程就會處理finalizer類,檢測是否有執(zhí)行finalize()方法,如果有,則可以把finalizer從線程中去除,對應(yīng)的對象就可以被回收;如果沒有,則一直交由finalizerThread線程管理。

詳細流程

JVM啟動時,檢測對象是否實現(xiàn)了finalize()方法,檢測方法:判斷has_finalizer_flag和registerfinalizerrsaltInit字段

A對象實現(xiàn)了finalize()方法,就會把A對象的finalize()函數(shù)注冊到finalizerthread線程和referencequeue隊列中,注冊完畢后,且稱該函數(shù)注冊的B對象稱為Finalizer類,指向原有的A對象。

GC回收垃圾時,啟動FinalizerThread線程,檢測Finalizer類對應(yīng)的A對象的finalize()方法是否已執(zhí)行,已調(diào)用,則可以把Finalizer類去除,回收Finalizer類,從而回收A對象;如果沒有調(diào)用,則繼續(xù)交由FinalizerThread線程管理,不回收。

從上面原因引申出:為什么堆內(nèi)存溢出?

GC回收時,用戶線程、GC回收線程和FinalizerThread線程都在運行,但由于FinalizerThread線程優(yōu)先度比GC回收線程和用戶線程低,所以導(dǎo)致回收速度比對象創(chuàng)建速度慢,最終導(dǎo)致堆內(nèi)存溢出。

示例程序:

JDK11、G1垃圾收集器

JVM設(shè)置

-Xms10m
-Xmx10m
-Xlog:ref*=debug
-Xlog:gc:gc.log
-Xlog:gc+heap=trace
-verbose:gc
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=E:\mycode\gc-demo\a.dump
public class FinalizeGcDemo {
 
    private static class GcDemo {
        private byte[] content = new byte[1024 * 1024];
 
        @Override
        protected void finalize() throws Throwable {
            System.out.println("執(zhí)行了finalize方法");
        }
    }
 
    public static void main(String[] args) {
        for (int i = 0; i < 10000; i++) {
            GcDemo gcDemo = new GcDemo();
        }
    }
 
}

日志如下:


[0.453s][debug][gc,heap       ] GC(23) Heap after GC invocations=21 (full 13): garbage-first heap   total 10240K, used 10123K [0x00000000ff600000, 0x0000000100000000)
[0.453s][debug][gc,heap       ] GC(23)   region size 1024K, 0 young (0K), 0 survivors (0K)
[0.453s][debug][gc,heap       ] GC(23)  Metaspace       used 6220K, capacity 6395K, committed 6528K, reserved 1056768K
[0.453s][debug][gc,heap       ] GC(23)   class space    used 538K, capacity 606K, committed 640K, reserved 1048576K
[0.453s][info ][gc            ] GC(23) Pause Full (G1 Evacuation Pause) 9M->9M(10M) 5.420ms
[0.455s][debug][gc,heap       ] GC(24) Heap before GC invocations=21 (full 13): garbage-first heap   total 10240K, used 10123K [0x00000000ff600000, 0x0000000100000000)
[0.455s][debug][gc,heap       ] GC(24)   region size 1024K, 0 young (0K), 0 survivors (0K)
[0.455s][debug][gc,heap       ] GC(24)  Metaspace       used 6220K, capacity 6395K, committed 6528K, reserved 1056768K
[0.455s][debug][gc,heap       ] GC(24)   class space    used 538K, capacity 606K, committed 640K, reserved 1048576K
[0.455s][debug][gc,ref        ] GC(24) Skipped phase1 of Reference Processing due to unavailable references
[0.455s][debug][gc,ref        ] GC(24) Skipped phase2 of Reference Processing due to unavailable references
[0.455s][debug][gc,ref        ] GC(24) Skipped phase3 of Reference Processing due to unavailable references
[0.455s][debug][gc,ref        ] GC(24) Skipped phase4 of Reference Processing due to unavailable references
[0.455s][debug][gc,phases,ref ] GC(24)     Reference Processing: 0.0ms
[0.455s][debug][gc,phases,ref ] GC(24)       Reconsider SoftReferences: 0.0ms
[0.455s][debug][gc,phases,ref ] GC(24)         SoftRef (ms):             skipped
[0.455s][debug][gc,phases,ref ] GC(24)       Notify Soft/WeakReferences: 0.0ms
[0.455s][debug][gc,phases,ref ] GC(24)         SoftRef (ms):             skipped
[0.455s][debug][gc,phases,ref ] GC(24)         WeakRef (ms):             skipped
[0.455s][debug][gc,phases,ref ] GC(24)         FinalRef (ms):            skipped
[0.455s][debug][gc,phases,ref ] GC(24)         Total (ms):               skipped
[0.455s][debug][gc,phases,ref ] GC(24)       Notify and keep alive finalizable: 0.0ms
[0.455s][debug][gc,phases,ref ] GC(24)         FinalRef (ms):            skipped
[0.455s][debug][gc,phases,ref ] GC(24)       Notify PhantomReferences: 0.0ms
[0.455s][debug][gc,phases,ref ] GC(24)         PhantomRef (ms):          skipped
[0.455s][debug][gc,phases,ref ] GC(24)       SoftReference:
[0.455s][debug][gc,phases,ref ] GC(24)         Discovered: 0
[0.455s][debug][gc,phases,ref ] GC(24)         Cleared: 0
[0.455s][debug][gc,phases,ref ] GC(24)       WeakReference:
[0.455s][debug][gc,phases,ref ] GC(24)         Discovered: 0
[0.455s][debug][gc,phases,ref ] GC(24)         Cleared: 0
[0.455s][debug][gc,phases,ref ] GC(24)       FinalReference:
[0.455s][debug][gc,phases,ref ] GC(24)         Discovered: 0
[0.455s][debug][gc,phases,ref ] GC(24)         Cleared: 0
[0.455s][debug][gc,phases,ref ] GC(24)       PhantomReference:
[0.455s][debug][gc,phases,ref ] GC(24)         Discovered: 0
[0.455s][debug][gc,phases,ref ] GC(24)         Cleared: 0
[0.455s][info ][gc,heap       ] GC(24) Eden regions: 0->0(1)
[0.455s][trace][gc,heap       ] GC(24)  Used: 0K, Waste: 0K
[0.455s][info ][gc,heap       ] GC(24) Survivor regions: 0->0(1)
[0.455s][trace][gc,heap       ] GC(24)  Used: 0K, Waste: 0K
[0.455s][info ][gc,heap       ] GC(24) Old regions: 2->2
[0.455s][trace][gc,heap       ] GC(24)  Used: 1931K, Waste: 116K
[0.455s][info ][gc,heap       ] GC(24) Humongous regions: 8->8
[0.455s][trace][gc,heap       ] GC(24)  Used: 8192K, Waste: 0K
[0.455s][debug][gc,heap       ] GC(24) Heap after GC invocations=22 (full 13): garbage-first heap   total 10240K, used 10123K [0x00000000ff600000, 0x0000000100000000)
[0.455s][debug][gc,heap       ] GC(24)   region size 1024K, 0 young (0K), 0 survivors (0K)
[0.455s][debug][gc,heap       ] GC(24)  Metaspace       used 6220K, capacity 6395K, committed 6528K, reserved 1056768K
[0.455s][debug][gc,heap       ] GC(24)   class space    used 538K, capacity 606K, committed 640K, reserved 1048576K
[0.455s][info ][gc            ] GC(24) Pause Young (Concurrent Start) (G1 Evacuation Pause) 9M->9M(10M) 0.585ms
[0.455s][debug][gc,heap       ] GC(25) Heap before GC invocations=22 (full 13): garbage-first heap   total 10240K, used 10123K [0x00000000ff600000, 0x0000000100000000)
[0.455s][debug][gc,heap       ] GC(25)   region size 1024K, 0 young (0K), 0 survivors (0K)
[0.455s][debug][gc,heap       ] GC(25)  Metaspace       used 6220K, capacity 6395K, committed 6528K, reserved 1056768K
[0.455s][debug][gc,heap       ] GC(25)   class space    used 538K, capacity 606K, committed 640K, reserved 1048576K
[0.455s][info ][gc            ] GC(26) Concurrent Cycle
[0.457s][debug][gc,ref        ] GC(25) Skipped phase3 of Reference Processing due to unavailable references
[0.457s][debug][gc,phases,ref ] GC(25) Reference Processing: 0.0ms
[0.457s][debug][gc,phases,ref ] GC(25)   Reconsider SoftReferences: 0.0ms
[0.457s][debug][gc,phases,ref ] GC(25)     SoftRef (ms):             Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.457s][debug][gc,phases,ref ] GC(25)   Notify Soft/WeakReferences: 0.0ms
[0.457s][debug][gc,phases,ref ] GC(25)     SoftRef (ms):             Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.457s][debug][gc,phases,ref ] GC(25)     WeakRef (ms):             Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.457s][debug][gc,phases,ref ] GC(25)     FinalRef (ms):            Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.457s][debug][gc,phases,ref ] GC(25)     Total (ms):               Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.457s][debug][gc,phases,ref ] GC(25)   Notify and keep alive finalizable: 0.0ms
[0.457s][debug][gc,phases,ref ] GC(25)     FinalRef (ms):            skipped
[0.457s][debug][gc,phases,ref ] GC(25)   Notify PhantomReferences: 0.0ms
[0.457s][debug][gc,phases,ref ] GC(25)     PhantomRef (ms):          Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.457s][debug][gc,phases,ref ] GC(25)   SoftReference:
[0.457s][debug][gc,phases,ref ] GC(25)     Discovered: 6
[0.457s][debug][gc,phases,ref ] GC(25)     Cleared: 6
[0.457s][debug][gc,phases,ref ] GC(25)   WeakReference:
[0.457s][debug][gc,phases,ref ] GC(25)     Discovered: 5
[0.457s][debug][gc,phases,ref ] GC(25)     Cleared: 5
[0.457s][debug][gc,phases,ref ] GC(25)   FinalReference:
[0.457s][debug][gc,phases,ref ] GC(25)     Discovered: 0
[0.457s][debug][gc,phases,ref ] GC(25)     Cleared: 0
[0.457s][debug][gc,phases,ref ] GC(25)   PhantomReference:
[0.457s][debug][gc,phases,ref ] GC(25)     Discovered: 66
[0.457s][debug][gc,phases,ref ] GC(25)     Cleared: 66
[0.460s][info ][gc,heap       ] GC(25) Eden regions: 0->0(1)
[0.460s][trace][gc,heap       ] GC(25)  Used: 0K, Waste: 0K
[0.460s][info ][gc,heap       ] GC(25) Survivor regions: 0->0(1)
[0.460s][trace][gc,heap       ] GC(25)  Used: 0K, Waste: 0K
[0.460s][info ][gc,heap       ] GC(25) Old regions: 2->2
[0.460s][trace][gc,heap       ] GC(25)  Used: 1931K, Waste: 116K
[0.460s][info ][gc,heap       ] GC(25) Humongous regions: 8->6
[0.460s][trace][gc,heap       ] GC(25)  Used: 6144K, Waste: 0K
[0.460s][debug][gc,heap       ] GC(25) Heap after GC invocations=23 (full 14): garbage-first heap   total 10240K, used 8075K [0x00000000ff600000, 0x0000000100000000)
[0.460s][debug][gc,heap       ] GC(25)   region size 1024K, 0 young (0K), 0 survivors (0K)
[0.460s][debug][gc,heap       ] GC(25)  Metaspace       used 6220K, capacity 6395K, committed 6528K, reserved 1056768K
[0.460s][debug][gc,heap       ] GC(25)   class space    used 538K, capacity 606K, committed 640K, reserved 1048576K
[0.460s][info ][gc            ] GC(25) Pause Full (G1 Evacuation Pause) 9M->7M(10M) 5.032ms
[0.461s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f28c8
執(zhí)行了finalize方法
執(zhí)行了finalize方法
執(zhí)行了finalize方法
[0.461s][info ][gc            ] GC(26) Concurrent Cycle 5.981ms
[0.462s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f28d0
[0.462s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f28d8
[0.462s][info ][oopstorage,ref] JNI Weak: allocated 0x00000187729f44b8
[0.462s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b710
[0.462s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b718
[0.462s][info ][oopstorage,ref] JNI Weak: allocated 0x00000187729f29c0
[0.462s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b720
[0.462s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b728
[0.462s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f28e0
[0.462s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f28e8
[0.463s][info ][oopstorage,ref] JNI Weak: allocated 0x00000187729f29c8
[0.463s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b730
[0.463s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b740
[0.463s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f28f0
[0.463s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f28f8
[0.463s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f2900
[0.463s][info ][oopstorage,ref] StringTable weak: allocated 0x00000187729f2908
[0.463s][info ][oopstorage,ref] JNI Weak: allocated 0x00000187729f29d0
[0.463s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b748
[0.463s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b750
[0.463s][info ][oopstorage,ref] JNI Weak: allocated 0x00000187729f29d8
[0.463s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b758
[0.463s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b760
[0.463s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b768
[0.463s][info ][oopstorage,ref] JNI Global: released 0x000001877265b670
[0.464s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b670
[0.464s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b770
[0.464s][info ][oopstorage,ref] JNI Weak: allocated 0x00000187729f29e0
[0.464s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b778
[0.464s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b780
[0.464s][info ][oopstorage,ref] JNI Weak: allocated 0x00000187729f29e8
[0.464s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b788
[0.464s][info ][oopstorage,ref] JNI Global: allocated 0x000001877265b790
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at com.gc.demo.finalize.FinalizeGcDemo.main(FinalizeGcDemo.java:26)

日志最后拋出堆內(nèi)存溢出(java.lang.OutOfMemoryError: Java heap space)異常。

通過MAT工具分析剛才程序運行的dump文件

上面的分析報告,明確指出了Finalizer類已經(jīng)占用堆內(nèi)存的51.88%以上,且主要因為GcDemo類下finalize()方法。

打印Reference類的JVM參數(shù)設(shè)置

  • JDK1.9之前 -XX:+PrintReferenceGC
  • JDK1.9(含1.9)以后 -Xlog:ref*=debug

日志打印

[0.323s][info ][gc            ] GC(3) Pause Full (G1 Humongous Allocation) 8M->7M(10M) 5.099ms
[0.324s][debug][gc,ref        ] GC(4) Skipped phase3 of Reference Processing due to unavailable references
[0.324s][debug][gc,phases,ref ] GC(4) Reference Processing: 0.0ms
[0.324s][debug][gc,phases,ref ] GC(4)   Reconsider SoftReferences: 0.0ms
[0.324s][debug][gc,phases,ref ] GC(4)     SoftRef (ms):             Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.324s][debug][gc,phases,ref ] GC(4)   Notify Soft/WeakReferences: 0.0ms
[0.324s][debug][gc,phases,ref ] GC(4)     SoftRef (ms):             Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.324s][debug][gc,phases,ref ] GC(4)     WeakRef (ms):             Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.324s][debug][gc,phases,ref ] GC(4)     FinalRef (ms):            Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.324s][debug][gc,phases,ref ] GC(4)     Total (ms):               Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.324s][debug][gc,phases,ref ] GC(4)   Notify and keep alive finalizable: 0.0ms
[0.324s][debug][gc,phases,ref ] GC(4)     FinalRef (ms):            skipped
[0.324s][debug][gc,phases,ref ] GC(4)   Notify PhantomReferences: 0.0ms
[0.324s][debug][gc,phases,ref ] GC(4)     PhantomRef (ms):          Min:  0.0, Avg:  0.0, Max:  0.0, Diff:  0.0, Sum:  0.0, Workers: 1
[0.324s][debug][gc,phases,ref ] GC(4)   SoftReference:
[0.324s][debug][gc,phases,ref ] GC(4)     Discovered: 34
[0.324s][debug][gc,phases,ref ] GC(4)     Cleared: 5
[0.324s][debug][gc,phases,ref ] GC(4)   WeakReference:
[0.324s][debug][gc,phases,ref ] GC(4)     Discovered: 5
[0.324s][debug][gc,phases,ref ] GC(4)     Cleared: 5
[0.324s][debug][gc,phases,ref ] GC(4)   FinalReference:
[0.324s][debug][gc,phases,ref ] GC(4)     Discovered: 0
[0.324s][debug][gc,phases,ref ] GC(4)     Cleared: 0
[0.324s][debug][gc,phases,ref ] GC(4)   PhantomReference:
[0.324s][debug][gc,phases,ref ] GC(4)     Discovered: 62
[0.324s][debug][gc,phases,ref ] GC(4)     Cleared: 62
[0.324s][info ][oopstorage,ref] VM Weak Oop Handles: released 0x0000018bb1d48748
[0.324s][info ][oopstorage,ref] VM Weak Oop Handles: released 0x0000018bb1d487b0
[0.324s][info ][oopstorage,ref] VM Weak Oop Handles: released 0x0000018bb1d48660

總結(jié)

1. finalize占用內(nèi)存搞這和GC的機制有關(guān)

實現(xiàn)了object的finalize()的類在創(chuàng)建時會新建一個FinalizerReference,這個對象是強引用類型,封裝了override  finalize()的對象,下面直接叫原對象。

原對象沒有被其他對象引用時(FinalizeReference除外),執(zhí)行GC不會馬上被清除掉,而是放入一個靜態(tài)鏈表中(ReferenceQueue),有一個守護線程專門去維護這個鏈表,如何維護呢?

就是輪到該線程執(zhí)行時就彈出里面的對象,執(zhí)行它們的finalize(),對應(yīng)的FinalizerReference對象在下次執(zhí)行GC時就會被清理掉。

一個堆的FinalizerReference會組成一條雙向鏈表,垃圾回收器應(yīng)該會持有鏈表頭(鏈表頭在FinalizerReference中為一個靜態(tài)成員)。

2. 為什么會泄漏

直接原因就是守護線程優(yōu)先級比較低,運行的時間比較少。

如果較短時間內(nèi)創(chuàng)建較多的原對象,就會因為守護線程來不及彈出原對象而使FinalizerReference和原對象都得不到回收。

無論怎樣調(diào)用GC都沒有用的,因為只要原對象沒有被守護線程彈出執(zhí)行其finalize()方法,F(xiàn)inalizerReference對象就不會被GC回收。

3. 知道這些機制后,應(yīng)該注意以下幾點

(1)緊缺資源不要依賴finalize()來釋放。

(2)盡量不要重載finalize()。

(3)如果必須重載finalize(),一定要記得調(diào)用super.finalize,也建議把類實現(xiàn)成單例模式(減少FinalizerReference占用)。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java中stream去重的幾種方式舉例

    java中stream去重的幾種方式舉例

    Stream流是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組等)所生成的元素序列,這篇文章主要給大家介紹了關(guān)于java中stream去重的幾種方式,需要的朋友可以參考下
    2023-07-07
  • SpringBoot中的錯誤處理機制源碼解析

    SpringBoot中的錯誤處理機制源碼解析

    這篇文章主要介紹了SpringBoot中的錯誤處理機制源碼解析,springboot根據(jù)訪問者的request中的Accept屬性來判斷要返回什么樣的數(shù)據(jù),SpringBoot存在一個錯誤處理機制,會根據(jù)不同請求返回不同的結(jié)果,需要的朋友可以參考下
    2023-12-12
  • Mybatis與微服務(wù)注冊的詳細過程

    Mybatis與微服務(wù)注冊的詳細過程

    這篇文章主要介紹了Mybatis與微服務(wù)注冊,主要包括SpringBoot整合MybatisPlus,SpringBoot整合Freeamarker以及SpringBoot整合微服務(wù)&gateway&nginx的案例代碼,需要的朋友可以參考下
    2023-01-01
  • spring?@Scheduled注解各參數(shù)使用以及定時任務(wù)詳解

    spring?@Scheduled注解各參數(shù)使用以及定時任務(wù)詳解

    文章詳細介紹了Spring框架中@Scheduled注解的各個參數(shù),包括cron表達式、時區(qū)、fixedDelay、fixedRate、initialDelay等,并提供了多個示例來說明這些參數(shù)的使用方法
    2024-11-11
  • Java IO流體系繼承結(jié)構(gòu)圖_動力節(jié)點Java學(xué)院整理

    Java IO流體系繼承結(jié)構(gòu)圖_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了Java IO流體系繼承結(jié)構(gòu)圖,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-05-05
  • 基于SpringBoot實現(xiàn)IP黑白名單的詳細步驟

    基于SpringBoot實現(xiàn)IP黑白名單的詳細步驟

    IP黑白名單是網(wǎng)絡(luò)安全管理中常見的策略工具,用于控制網(wǎng)絡(luò)訪問權(quán)限,根據(jù)業(yè)務(wù)場景的不同,其應(yīng)用范圍廣泛,比如比較容易被盜刷的短信接口、文件接口,都需要添加IP黑白名單加以限制,所以本文給大家介紹了基于SpringBoot實現(xiàn)IP黑白名單的詳細步驟,需要的朋友可以參考下
    2024-01-01
  • Java并發(fā)編程Semaphore計數(shù)信號量詳解

    Java并發(fā)編程Semaphore計數(shù)信號量詳解

    這篇文章主要介紹了Java并發(fā)編程Semaphore計數(shù)信號量詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • Spring3 MVC請求參數(shù)獲取的幾種方法小結(jié)

    Spring3 MVC請求參數(shù)獲取的幾種方法小結(jié)

    本篇文章主要介紹了Spring3 MVC請求參數(shù)獲取的幾種方法小結(jié),非常具有實用價值,需要的朋友可以參考下。
    2017-03-03
  • 深入解析Java NIO在高并發(fā)場景下的性能優(yōu)化實踐指南

    深入解析Java NIO在高并發(fā)場景下的性能優(yōu)化實踐指南

    隨著互聯(lián)網(wǎng)業(yè)務(wù)不斷演進,對高并發(fā)、低延時網(wǎng)絡(luò)服務(wù)的需求日益增長,本文將深入解析Java NIO在高并發(fā)場景下的性能優(yōu)化方法,希望對大家有所幫助
    2025-08-08
  • Java實現(xiàn)Http工具類的封裝操作示例

    Java實現(xiàn)Http工具類的封裝操作示例

    這篇文章主要介紹了Java實現(xiàn)Http工具類的封裝操作,涉及java針對http請求與響應(yīng)、遠程交互與字符串拼接等操作封裝技巧,需要的朋友可以參考下
    2018-01-01

最新評論

贞丰县| 双城市| 卓尼县| 岳阳市| 盐源县| 建宁县| 财经| 满洲里市| 喀什市| 威远县| 湖口县| 清水河县| 理塘县| 昌图县| 荥阳市| 樟树市| 新邵县| 衡阳市| 霸州市| 中阳县| 克什克腾旗| 新蔡县| 札达县| 久治县| 特克斯县| 嘉鱼县| 梓潼县| 乳源| 叶城县| 咸阳市| 山丹县| 石泉县| 清原| 红桥区| 徐闻县| 昌平区| 寻乌县| 内丘县| 湖口县| 资中县| 新巴尔虎右旗|