Java 没有显式调用的方法的堆栈帧(调用站点)
Java stack frames for methods without explicit invocations (call sites)
我对 Java 程序执行时出现在堆栈上的方法有疑问。我已经对代码进行了检测,以在方法执行开始时以及方法退出时进行记录(考虑之前和之后的 AOP)。我为每个线程创建一个日志。结果大部分符合预期,但存在一些细微差异。
- 遇到反射调用时,不仅会记录
java.lang.reflect.Method#invoke
,还会显示 sun.reflect.DelegatingMethodAccessorImpl#invoke
等其他调用。我假设这与 StackWalker 文档中讨论的隐藏框架有关。
- 还有其他调用,主要是
java.lang.ClassLoader.loadClass
,还有 sun.instrument.InstrumentationImpl.transform
(记住,我检测了代码!)。这些是具有堆栈帧的方法,但应用程序中没有调用站点 类。
我有两个问题:
- 是否有所有方法的列表,或定义将隐藏调用的方法的标准(例如“在以
sun.
开头的包中 类 中定义的所有方法)?
- 是否有所有方法的列表,或定义由 JVM 在用户代码中没有调用点的情况下调用的方法的标准?
谢谢
sun.reflect.DelegatingMethodAccessorImpl#invoke
和朋友没什么特别的。这些是在 Java 代码中具有常规 call site 的普通 Java 方法。
确实有些 Java 方法是直接从 VM 代码调用的。这样的电话很多,要拿到完整的名单不容易。
在 HotSpot 源代码中查找 JavaCalls::call_virtual
、JavaCalls::call_static
、JavaCalls::call_special
等。例如,here 是对提到的 ClassLoader.loadClass
.
的调用
实际上,任何方法都可以这样调用。即使您设法获得完整列表,它也不会很有用,因为它可能会在任何次要 JDK 更新中发生变化。
此外,用户代码和代理库也可以使用 JNI 调用任何 Java 方法,并且这些调用也不会有可见的 Java 调用站点。
我对 Java 程序执行时出现在堆栈上的方法有疑问。我已经对代码进行了检测,以在方法执行开始时以及方法退出时进行记录(考虑之前和之后的 AOP)。我为每个线程创建一个日志。结果大部分符合预期,但存在一些细微差异。
- 遇到反射调用时,不仅会记录
java.lang.reflect.Method#invoke
,还会显示sun.reflect.DelegatingMethodAccessorImpl#invoke
等其他调用。我假设这与 StackWalker 文档中讨论的隐藏框架有关。 - 还有其他调用,主要是
java.lang.ClassLoader.loadClass
,还有sun.instrument.InstrumentationImpl.transform
(记住,我检测了代码!)。这些是具有堆栈帧的方法,但应用程序中没有调用站点 类。
我有两个问题:
- 是否有所有方法的列表,或定义将隐藏调用的方法的标准(例如“在以
sun.
开头的包中 类 中定义的所有方法)? - 是否有所有方法的列表,或定义由 JVM 在用户代码中没有调用点的情况下调用的方法的标准?
谢谢
sun.reflect.DelegatingMethodAccessorImpl#invoke
和朋友没什么特别的。这些是在 Java 代码中具有常规 call site 的普通 Java 方法。确实有些 Java 方法是直接从 VM 代码调用的。这样的电话很多,要拿到完整的名单不容易。
在 HotSpot 源代码中查找
的调用JavaCalls::call_virtual
、JavaCalls::call_static
、JavaCalls::call_special
等。例如,here 是对提到的ClassLoader.loadClass
.实际上,任何方法都可以这样调用。即使您设法获得完整列表,它也不会很有用,因为它可能会在任何次要 JDK 更新中发生变化。
此外,用户代码和代理库也可以使用 JNI 调用任何 Java 方法,并且这些调用也不会有可见的 Java 调用站点。