调试模式和正常执行模式之间的行为不同-弱引用处理

时间:2018-07-18 23:16:18

标签: java debugging reference jvm

我修补了java.lang.ref.Reference类,以便在每次调用get()时调用自定义本机方法。修补的类放在引导类路径的前面。

启动示例程序时,由于JDK内部使用了许多Reference,因此我看到了很多打印输出来自本机方法(正如预期的那样)。

奇怪的行为始于我的main方法。我要做的就是为对象创建WeakReference,删除强对象并调用get()。无论出于何种原因,我添加的本机方法似乎都不会在运行模式下被调用,并且我没有得到任何打印输出或本机内部发生的其他事件。

如果我以调试模式启动程序,那么一切都会按预期工作,即调用本机方法。

如果我将WeakReference更改为SoftReference,则它始终可以正常运行模式下运行。

我什至尝试添加其他代码(例如将System.out.println添加到get()),但这也没有用。在非调试模式下运行时,我的WeakReference的打印会以某种方式停止。在调试中,它始终有效。

有时候,在关闭主机后的Finalizer中,我什至会收到很多事件/打印输出。因此,看来Reference类的行为似乎有所不同。

1 个答案:

答案 0 :(得分:5)

java.lang.ref.Reference.get()JVM intrinsic method

这意味着,一旦对方法进行了JIT编译,就不再调用其Java实现。 HotSpot编译器使用特殊的手动优化序列hardcoded in HotSpot sources替换了对Reference.get的调用。

在JVM启动时,该方法尚未进行JIT编译,即该方法的Java实现已被解释,并且固有方法不起作用。

SoftReference overrides该方法,因此Reference.get内在函数也不适用。

您可以使用以下JVM标志禁用此内在函数,即使方法是JIT编译的,修改后的版本也将始终有效:

-XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_Reference_get

Here is the list在JDK中的其他内部方法。