zoukankan      html  css  js  c++  java
  • finalize理论基础

    参考:

    https://blog.csdn.net/aitangyong/article/details/39450341

    https://www.infoq.cn/article/jvm-source-code-analysis-finalreference

    finalize()方法,这里实际使用了FinalReference,真正的实现是Finalizer
    大体的过程是jvm将实现了Object.finalize方法的实例标识为finalizer类型,注册为一个Finalizer对象,并加到到对象链中,有一个FinalizerThread线程负责从对象链获取Finalizer对象,执行runFinalizer函数,最终调用Object.finalize

    总结:

    1、如果一个类A实现了finalize()方法,那么每次创建A类对象的时候,都会多创建一个Finalizer对象(指向刚刚新建的对象);如果类没有实现finalize()方法,那么不会创建额外的Finalizer对象;

    2、Finalizer内部维护了一个unfinalized链表,每次创建的Finalizer对象都会插入到该链表中;

    3、如果类没有实现finalize方法,那么进行垃圾回收的时候,可以直接从堆内存中释放该对象。这是速度最快,效率最高的方式(不用创建额外Finalizer对象,不用进行二次筛选)

    4、如果类实现了finalize方法,进行GC的时候,如果发现某个对象只被java.lang.ref.Finalizer对象引用,那么会将该Finalizer对象加入到Finalizer类的引用队列(F-Queue)中,并从unfinalized链表中删除该结点。这个过程是JVM在GC的时候自动完成的。

    5、含有finalize()的对象从内存中释放,至少需要两次GC。
    第一次GC, 检测到对象只有被Finalizer引用,将这个对象放入 java.lang.ref.Finalizer.ReferenceQueue 此时,因为Finalizer的引用,对象还无法被GC。java.lang.ref.Finalizer$FinalizerThread 会不停的清理Queue的对象,remove掉当前元素,并执行对象的finalize方法。清理后对象没有任何引用,在下一次GC被回收。

    6、Finalizer是JVM内部的守护线程,优先级为8。Finalizer线程是个单一职责的线程。这个线程会不停的循环等待java.lang.ref.Finalizer.ReferenceQueue中的新增对象。一旦Finalizer线程发现队列中出现了新的对象,它会弹出该对象,调用它的finalize()方法,将该引用从Finalizer类中移除,因此下次GC再执行的时候,这个Finalizer实例以及它引用的那个对象就可以回垃圾回收掉了。
    7、使用finalize容易导致OOM,因为如果创建对象的速度很快,那么Finalizer线程的回收速度赶不上创建速度,就会导致内存垃圾越来越多。

  • 相关阅读:
    OpenStack功能简介
    Openstack(七)keystone
    Openstack(六)RabbitMQ集群
    Openstack(五)Memcache- repcached集群
    Openstack(四)Mysql主从
    Openstack(三)Haproxy+Keepalived双机
    Openstack(二)基本环境准备--网络、时间、yum源等
    Openstack架构简介(一)
    运维监控系统之Open-Falcon
    python高级之Flask框架
  • 原文地址:https://www.cnblogs.com/kancy/p/10411109.html
Copyright © 2011-2022 走看看