Java 没有显式调用的方法的堆栈帧(调用站点)

Java stack frames for methods without explicit invocations (call sites)

我对 Java 程序执行时出现在堆栈上的方法有疑问。我已经对代码进行了检测,以在方法执行开始时以及方法退出时进行记录(考虑之前和之后的 AOP)。我为每个线程创建一个日志。结果大部分符合预期,但存在一些细微差异。

  1. 遇到反射调用时,不仅会记录 java.lang.reflect.Method#invoke,还会显示 sun.reflect.DelegatingMethodAccessorImpl#invoke 等其他调用。我假设这与 StackWalker 文档中讨论的隐藏框架有关。
  2. 还有其他调用,主要是 java.lang.ClassLoader.loadClass,还有 sun.instrument.InstrumentationImpl.transform(记住,我检测了代码!)。这些是具有堆栈帧的方法,但应用程序中没有调用站点 类。

我有两个问题:

  1. 是否有所有方法的列表,或定义将隐藏调用的方法的标准(例如“在以 sun. 开头的包中 类 中定义的所有方法)?
  2. 是否有所有方法的列表,或定义由 JVM 在用户代码中没有调用点的情况下调用的方法的标准?

谢谢

  1. sun.reflect.DelegatingMethodAccessorImpl#invoke和朋友没什么特别的。这些是在 Java 代码中具有常规 call site 的普通 Java 方法。

  2. 确实有些 Java 方法是直接从 VM 代码调用的。这样的电话很多,要拿到完整的名单不容易。

    在 HotSpot 源代码中查找 JavaCalls::call_virtualJavaCalls::call_staticJavaCalls::call_special 等。例如,here 是对提到的 ClassLoader.loadClass.

    的调用

    实际上,任何方法都可以这样调用。即使您设法获得完整列表,它也不会很有用,因为它可能会在任何次要 JDK 更新中发生变化。

    此外,用户代码和代理库也可以使用 JNI 调用任何 Java 方法,并且这些调用也不会有可见的 Java 调用站点。