最终确定allocateInstance(Java)从对象从未调用过的方法

时间:2019-04-02 02:39:21

标签: java unsafe

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

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的终结。为什么? 我找不到关键信息。...

1 个答案:

答案 0 :(得分:1)

This OpenJDK thread注意以下几点:

  

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

此外,Java Langauge Specification (§12.6.0)特别声明:

  

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

鉴于在您的代码中您从未实际调用分配的实例的构造函数,因此必须先违反上述happens-before order (§17.4.5)才能调用Object.finalize()方法。

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