zoukankan      html  css  js  c++  java
  • java finalize及实践

    https://www.cnblogs.com/Smina/p/7189427.html 

     

    1. finalize的作用

     

    • finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。
    • finalize()与C++中的析构函数不是对应的。C++中的析构函数调用的时机是确定的(对象离开作用域或delete掉),但Java中的finalize的调用具有不确定性
    • 不建议用finalize方法完成“非内存资源”的清理工作,但建议用于:① 清理本地对象(通过JNI创建的对象);② 作为确保某些非内存资源(如Socket、文件等)释放的一个补充:在finalize方法中显式调用其他资源释放方法。其原因可见下文[finalize的问题]

    2. finalize的问题

    • 一些与finalize相关的方法,由于一些致命的缺陷,已经被废弃了,如System.runFinalizersOnExit()方法、Runtime.runFinalizersOnExit()方法
    • System.gc()与System.runFinalization()方法增加了finalize方法执行的机会,但不可盲目依赖它们
    • Java语言规范并不保证finalize方法会被及时地执行、而且根本不会保证它们会被执行 由于gc是守护线程,可能不会调用finalize
    • finalize方法可能会带来性能问题。因为JVM通常在单独的低优先级线程中完成finalize的执行(可能达400倍)
    • 超类中的finalize()方法需要显示的调用,super.finalize(),会忘记
    • 任何有finalize()方法抛出的异常都会被GC线程忽略(优先级低)而且不会被进一步传播,事实上也不会在日志文件上记录下来http://blog.csdn.net/maoyeqiu/article/details/49562093
    • 对象再生问题:finalize方法中,可将待回收对象赋值给GC Roots可达的对象引用,从而达到对象再生的目的
    • finalize方法至多由GC执行一次(用户当然可以手动调用对象的finalize方法,但并不影响GC对finalize的行为)
    • 造成gc卡顿

    3. finalize的执行过程(生命周期)

     

    (1) 首先,大致描述一下finalize流程:当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。所以覆盖fanalize函数会造成对象被延迟回收,在流量大的时候应注意

     证明:

    public class TestGcFinalize {
    
        public static void main(String []f) throws InterruptedException {
    
            NoFinalize noFinalize = new NoFinalize();
            WithFinalize withFinalize = new WithFinalize();
            noFinalize = null;
            withFinalize = null;
            System.gc();
            System.out.println("1d");
            Thread.sleep(20000);  // jmap -dump:format=b,file=dump1.dump <pid> nolive
            System.out.println("s2");
            System.gc();
            System.out.println("2d");
            Thread.sleep(20000);  // jmap -dump:format=b,file=dump1.dump <pid> nolive
            System.out.println("d");
        }
    
        private static class NoFinalize {
    
        }
    
        private static class WithFinalize {
    
            @Override
            public void finalize() {
                System.out.println("finalize");
            }
        }
    }
    

          NoFinalize    WithFinalize

    第一次gc  直接回收    调用finalize,下次回收

    第二次gc       /        回收

     可以看到第一次gc,虽然调用了WithFinalize的finazlize方法,但没有直接回收掉,直到第二次gc才回收掉

    finalizedump.zip

    https://www.cnblogs.com/QG-whz/p/6557333.html

    java的finalize()方法与C++的析构函数

     一旦C++的对象要被回收了,在回收该对象之前对象的析构函数将被调用,然后释放对象占用的内存;而java中

    一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法, 并且在下一次垃圾回收动作发生时,才会真正的回收对象占用的内存(《java 编程思想》)

    可见在java中,调用GC不等于真正地回收内存资源,而且在垃圾回收中对象存在状态的变化。


  • 相关阅读:
    项目常用组建摘记
    How do I resolve the CodeSign error: CSSMERR_TP_NOT_TRUSTED?
    使用wkwebview后,页面返回不刷新的问题
    前端性能监控方案window.performance 调研(转)
    UC浏览器中,设置了position: fixed 的元素会遮挡z-index值更高的同辈元素
    zepto中给不存在的元素设置样式并绑定事件的坑
    js中的路由匹配
    input光标高度问题
    javascript创建css、js,onload触发callback兼容主流浏览器的实现
    js input输入事件兼容性问题
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106669.html
Copyright © 2011-2022 走看看