JVM都崩溃了,那到底执行finalize方法时发生了什么.Jvm会给每个实现了finalize方法的实例创建一个监听,这个称为Finalizer,每次调用对象的finalize方法时,JVM会创建一个java.lang.ref.Finalizer...对象,这个Finalizer对象会持有这个对象的引用,由于这些对象被Finilizer对象引用了,当对象数量较多时,就会导致Eden区空间满了,经历多次youngGC后可能对象就进入到老年代了. java.lang.ref.Finalizer...force = new Finalizer(); } //让线程阻塞住,方便分析内存使用情况 System.in.read(); } } 执行main方法后使用jmap命令查看内存使用情况,可以看到java.lang.ref.Finalizer...和Finalizer对象依然存在,不过这一java.lang.ref.Finalizer 不再引用Finalizer对象,下一次GC周期时两者都属于垃圾对象: 11$ jmap -histo:live...8700|head -n 10 num #instances #bytes class name ———————————————- 1: 10175 407000 java.lang.ref.Finalizer
java.lang.ref.ReferenceQueue.remove(Unknown Source) java.lang.ref.ReferenceQueue.remove(Unknown Source) java.lang.ref.Finalizer
: 532 17024 java.io.File 9: 225 14400 java.net.URL 10: 334 13360 java.lang.ref.Finalizer...: 532 17024 java.io.File 9: 225 14400 java.net.URL 10: 334 13360 java.lang.ref.Finalizer
java.io.File 9: 225 14400 java.net.URL 10: 334 13360 java.lang.ref.Finalizer...java.io.File 9: 225 14400 java.net.URL 10: 334 13360 java.lang.ref.Finalizer
0x00000249b7bbe000 nid=0x3088 runnable [0x000000c783cff000] java.lang.Thread.State: RUNNABLE at java.lang.ref.Finalizer...总结,Finalizable 对象的生命周期和普通对象的行为是完全不同的,基本的执行顺序如下: JVM 创建 Finalizable 对象 JVM 创建 java.lang.ref.Finalizer...实例,指向刚创建的对象 java.lang.ref.Finalizer 类持有(锁)新创建的 java.lang.ref.Finalizer 的实例。
主要原因是 finalize 会掩盖资源回收时的出错信息 看 java.lang.ref.Finalizer 源码 private void runFinalizer(JavaLangAccess
看到第三个问题是否眼前一亮,小时候我们学java的时候就知道java.lang.ref.Finalizer是干嘛的,有兴趣的可自行Google,也可看一下:JVM finalize实现原理与由此引发的血案...java.lang.ref.Finalizer基本确定回收阶段出现问题,进入搜索待回收的对象。此时我们不是纠结有多少对象没有被回收,为什么没有回收。而是这些没有回收的对象是否由指向堆外内存。 ?
Final Reference 当前类是否是finalizer类,注意这里finalizer是由JVM来标志的( 后面简称f类 ),并不是指java.lang.ref.Finalizer类。...但是f类是会被JVM注册到java.lang.ref.Finalizer类中的。 ① 当前类或父类中含有一个参数为空,返回值为void的名为finalize的方法。
java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:) at java.lang.ref.Finalizer
new Thread(() -> Parent.test(), "T-2").start(); } 二、FinalReference堆积 现象:用jmap命令分析查看占用内存最多的对象时, 发现java.lang.ref.Finalizer
java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer
,我们分析dump内存的时候,经常能看到 java.lang.ref.Finalizer占用的内存大小远远排在前面,就是因为系统里构造了大量的实现了finalize方法的对象。
java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer
java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) at java.lang.ref.Finalizer
0x00007fcacc4a5233 * java.lang.ref.ReferenceQueue.remove() bci:2 line:151 (Interpreted frame) 0x00007fcacc4a5233 * java.lang.ref.Finalizer...java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) at java.lang.ref.Finalizer
finalize 还会掩盖资源回收时的出错信息,我们看下面一段 JDK 的源代码,截取自 java.lang.ref.Finalizer: private void runFinalizer(JavaLangAccess
> cls = Class.forName("java.lang.ref.Finalizer"); Field[] fields = cls.getDeclaredFields();
java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer...java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer
领取专属 10元无门槛券
手把手带您无忧上云