finalize никогда не вызывается из объекта allocateInstance (Java) - PullRequest
0 голосов
/ 02 апреля 2019

Просьбы относятся к следующему коду, я просто хочу сделать что-нибудь с небезопасным.

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 Ответ

1 голос
/ 02 апреля 2019

Этот поток OpenJDK отмечает следующее:

Unsafe.allocateInstance () реализуется в виртуальной машине HotSpot путем непосредственного вызова функции JNI AllocObject() [1] . Экземпляр объекта выделяется в куче Java, но для этого экземпляра не вызываются конструкторы.

Более того, Java Langauge Specification (§12.6.0) конкретно заявляет, что:

Завершение конструктора объекта происходит до ( §17.4.5 ) выполнения его метода финализации (вв формальном смысле происходит раньше).

Учитывая, что в вашем коде вы никогда не вызываете конструкторы для выделенных экземпляров, метод Object.finalize() нельзя вызвать без предварительного нарушения вышеупомянутого порядок «происходит до» (§17.4.5) .

Следовательно, метод Object.finalize() никогда не будет вызван.

...