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

Haa*_*ang 2 java debugging jvm reference

java.lang.ref.Reference每次调用时,我都修补了类调用自定义本机方法get().修补后的类被添加到引导类路径中.

当我开始一个示例程序时,我看到很多打印输出来自我的本机方法(正如预期的那样),因为ReferenceJDK内部使用了很多s.

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

如果我在调试模式下启动程序,一切都按预期工作,即调用本机方法.

如果我将其更改WeakReference为a SoftReference它始终有效,也可以在正常运行模式下运行.

我甚至尝试添加其他代码(如System.out.printlnget()),但也没有工作.WeakReference在非调试模式下运行时,打印以某种方式停止.在调试中它始终有效.

有时我甚至会Finalizer在关闭期间从我的主要事件中获得很多事件/打印输出.所以看起来这个Reference类看起来有点不同.

apa*_*gin 5

java.lang.ref.Reference.get()是一种JVM内在方法.

这意味着一旦该方法被JIT编译,其Java实现就不再被调用.HotSpot编译器使用在HotSpot源中硬编码Reference.get的特殊手动优化序列替换调用.

在JVM启动时,该方法尚未进行JIT编译,即其Java实现被解释,而内部函数不起作用.

SoftReference 覆盖该方法,因此Reference.get内在也不适用于它.

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

-XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_Reference_get
Run Code Online (Sandbox Code Playgroud)

以下是 JDK中其他内部方法的列表.