0

这是此问题的后续问题。

具体来说,我正在尝试验证 API 的正确使用,该 API 涉及close()通过 JNI 调用持有大量本机资源的 Java 对象。重申一下这个问题,在测试和生产中都需要这样做,因为资源从一个测试用例泄漏到另一个测试用例和生产中,因为本地资源应该以受控方式处理。

代码(我想要处理的所有此类 Java 对象都将扩展 JPeer):

public class JPeer implements AutoCloseable {

    private final long nativeHandle_ = ....

    private final Verifier closeVerifier_;
    private static final Cleaner cleaner_ = Cleaner.create();

    protected JPeer() {
        closeVerifier_ = new Verifier();
        cleaner_.register(this, closeVerifier_);
    }

    @SuppressWarnings("unchecked")
    @Override
    public final void close() {
        if (closed())
            throw new AssertionError("JPeer already closed");

        ..... // doing dispose over JNI

        closeVerifier_.markDone();
    }



//    @SuppressWarnings("deprecation")
//    @Override
//    protected final void finalize() {
//        if (!closed()) {
//            // due to threading considerations with JNI, we shouldn't destroy here, we rely on user to destroy from construction thread
//                // TODO finalize() never called, how to assert closure?
//            throw new AssertionError("JPeer was not closed, native object leaking");
//        }
//    }

    private static final class Verifier implements Runnable {

        volatile boolean done_ = false;

        public void markDone() {
            done_ = true;
        }

        @Override
        public void run() {
            if (!done_) {
                // due to threading considerations with JNI, we shouldn't destroy here, we rely on user to destroy from construction thread
                System.err.println("Verifier: JPeer was not closed, native object leaking");
                throw new AssertionError("Verifier: JPeer was not closed, native object leaking");
            }
            else {
                System.out.println("Verifier: JPeer was closed");
            }
        }
    }
}

为什么不调用清洁器操作?我在控制台中既没有看到“JPeer 已关闭”,也没有看到“JPeer 未关闭”。无法从更清洁的操作中打印某些内容是个问题吗?(我知道从那里抛出的异常会被忽略,所以AssertionError没用)如果是这样,我如何通知我的验证结果?

4

0 回答 0