finalize从未通过allocateInstance(Java)从对象调用

问题描述 投票:0回答:1

请参考以下代码,我只是想做一些不安全的事情。

import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.util.*;

public class A {

    public static void main(String[] args) throws Exception {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe u = (Unsafe) f.get(null);
        System.out.println("the while start at:" + new Date());
        long total = 0;
        while (true) {
            u.allocateInstance(B.class);
            total++;
            if (total % 100000000 == 0) {
                System.out.println(total);
                System.gc();
            }
        }
    }
}

class B {

    private int a;
    private int b;
    private double d;
    private float e;

    @Override
    protected void finalize() {
        try {
            super.finalize();
        } catch (Throwable e) {
            System.out.println("catch excep");
        }
        System.out.println("class B finalize, the a:" + a);
    }
}

代码永远不会是oom,但B类的最终定型从未被调用过。为什么?我找不到关键信息....

java unsafe
1个回答
1
投票

This OpenJDK thread注意到以下内容:

Unsafe.allocateInstance()通过直接调用JNI的AllocObject()函数[1]在HotSpot VM中实现。在Java堆中分配了一个对象实例,但是没有为该实例调用构造函数。

此外,Java Langauge Specification (§12.6.0)明确指出:

对象的构造函数的完成发生在之前(§17.4.5)执行其finalize方法(在之前发生的形式意义上)。

鉴于在您的代码中您实际上从未实际调用已分配实例的构造函数,因此如果不首先违反上述Object.finalize(),则无法调用happens-before order (§17.4.5)方法。

因此,永远不会调用Object.finalize()方法。

© www.soinside.com 2019 - 2024. All rights reserved.