没有明确调用的方法的Java堆栈框架(调用站点)

时间:2019-04-14 10:59:21

标签: java reflection jvm invoke

我对执行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 个答案:

答案 0 :(得分:1)

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

  2. 的确,某些Java方法是直接从VM代码中调用的。这样的电话很多,要获得完整的清单并不容易。

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

    实际上,任何方法都可以用这种方式有效地调用。即使您设法获得完整列表,它也不会很有用,因为在任何较小的JDK更新中它都可能会更改。

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