美文网首页
覆写finalize()引起的ygc问题

覆写finalize()引起的ygc问题

作者: Asiazj | 来源:发表于2020-02-13 20:14 被阅读0次

    服务性能优化,发现有个服务的ygc次数和单次ygc耗时明显比同类型服务高。 

    通过jstat(jstat -gcutil pid 100 1000)发现,每次ygc之后,surivor中都有20-30%被占用,而同类型服务ygc之后,surivor只有3-5%的被占用,说明eden中有不少的对象熬过了本次ygc,每次ygc都有几百兆的对象能挺进surivor,确实有点可疑。

    只好dump下机器内存,看下能否发现明显的异常之处,看了dump内存吓了一跳,一半左右的对象都来自java.lang.ref.Finalizer

内存中的对象 Finalizer中对象信息

而Finalizer对象中持有的都是FileInputStream和FileOutputStream。这两个类都是重写了Object的finalize()方式的,看代码,重写只是为了确认释放资源(gc只能回收jvm中的资源,对于jvm之外的无能为力,FileInputStream需要通过jni获取系统资源,这部分资源需要显式回收)。

FileInputStream的finalize()方法

创建覆写了finalize方法的类对象(O1)时,同时会创建一个Finalizer对象(F1),F1会引用O1。在发生GC时,O1不会被直接回收,而是会被JVM识别出,JVM会将F1放入Finalizer的static的Queue中。所以,一次ygc并不能回收O1,只能转移到survivor。

    那O1什么时候才能被回收呢?原来JVM在加载Finalizer对象的时候,会启动一个名为“Finalizer”的线程,负责清理Finalizer的Queue中的对象。清理的过程,就是执行O1的finalize方法,并同时从队列中移除。被清理之后,再没有引用指向实现了finalize方法对象了,那么在下一次GC的时候,此对象就可以被回收了 。 

    原因查到了,至于怎么修复

        1、升级jdk,高版本jdk中的FileInputStream类已经删除了finalize()方法

        2、避免使用覆写了finalize()的类

相关文章

  • 覆写finalize()引起的ygc问题

    服务性能优化,发现有个服务的ygc次数和单次ygc耗时明显比同类型服务高。 通过jstat(jstat -gc...

  • 【Java技术专题】「原理专题」深入分析Java中finaliz

    finalize方法是什么 finalize方法是Object的protected方法,Object的子类们可以覆...

  • Android Studio安装【模拟器运行,真机很可能也有;不

    问题A: Failed to finalize session : INSTALL_FAILED_INVALID_...

  • Android Studio运行报错INSTALL_FAILED

    问题 Installation failed with message Failed to finalize se...

  • GC

    面试题 请写一段程序,让其运行时的表现为触发5次ygc,然后3次fgc,然后3次ygc,然后1次fgc,请给出代码...

  • java finalize方法总结、GC执行finalize的过

    注:本文的目的并不是鼓励使用finalize方法,而是大致理清其作用、问题以及GC执行finalize的过程。 1...

  • 覆写

    概念:如果子类重写了父类:属性的覆盖与方法的覆写 方法的复写:子类定义了与父类方法名称,参数类型以及个数完全相同的...

  • 覆写

  • 覆写

    现在已经清楚了继承的基本概念,那么此时就有可能出现这样的一种情况,如果子类现在定义了与父类相同的方法或者是属性的时...

  • 覆写

    方法覆写 子类和父类一旦产生了继承关系,子类就会继承父类中的全部定义,但是这里面也有可能出现不合适的场景,子类如果...

网友评论

      本文标题:覆写finalize()引起的ygc问题

      本文链接:https://www.haomeiwen.com/subject/mqwnrftx.html