任何方法来告诉方法是否已结束或方法中的本地不再使用?

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

我需要一些解决方案来帮助我说出一些方法,例如:

void myMethod(...)
{
    MyObject obj = new MyObject();
    // do stuff
}

如果此方法已结束或obj无法访问(这将指示方法已结束)。

我正在写一个小的java代理,我希望有一些技术可以让我知道这个方法已经结束或obj无法访问...在我的情况下,“do stuff”部分根本不使用obj 。它不会将此变量传递到其他位置或将其添加到某个集合中。

我知道,使用Weak / Soft / Phantom-References,我可以部分实现这一点。如果调用GC,则通过:

void myMethod(...)
{
    MyObject obj = new MyObject();
    WeakReference objReference = new WeakReference(obj);

    // do stuff
}

我总是可以在不同的地方验证:

    if (objReference.get() == null) ...

但是,如果发生GC,情况可能也是如此。

有没有其他方法来实现这一目标?例如,标记JVM的一些标记可能会放在这个变量上,因为很明显这是一个肯定是垃圾收集的本地...

我不想依赖ASM - 并为所有这些方法添加try-finally包装器。希望有一个更微妙的,基于参考的解决方案。

java weak-references soft-references phantom-reference
1个回答
2
投票

唯一可行的方法......我能想到...就是使用回调/听众;例如

public MyClass

    void myMethod(Function<MyClass, Void> onCompletion) {
        try {
            // Do stuff
        } finally {
            onCompletion.apply(this);
        }
    }

您还可以使用MethodHandles.tryFinally为您的方法创建方法句柄,通过包装方法来实现回调。

任何基于Reference类型的东西都隐含地依赖于垃圾收集。这将是昂贵的,你几乎无法控制何时收到通知。


有没有其他方法来实现这一目标?例如,标记JVM的一些标记可能会放在这个变量上,因为很明显这是一个肯定是垃圾收集的本地...

AFAIK,没有。并且JVM / JIT没有做你所假设的事情;即,在正常的GC循环之前,它们没有标记“明显的”局部用于最终确定或收集。

他们为什么不呢?因为如果发生这种情况会使应用程序变慢。唯一的好处是最终化/参考处理可能会更快地发生,但是对于编写良好的应用程序来说,没有任何区别。一个编写良好的程序不应该关注何时进行最终化/参考处理,因为规范明确地不保证时间。

事实证明逃逸分析也无济于事:

现在我知道JIT可能会调整告诉GC仍在范围内的表格(参见@ Holger的评论;例如finalize() called on strongly reachable object in Java 8)。但这并没有改变方法的指令序列。 GC正在运行时,只有GC关注这些信息......

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