动态编译的函数是指程序执行时编译和链接的函数。 收集器中并没有有关用 C 或 C++ 编写的动态编译函数的信息,除非用户使用收集器 API 函数 collector_func_load() 提供所需的信息。由 "Function"(函数)视图、"Source"(源)视图和 "Disassembly"(反汇编)视图显示的信息取决于传递给 collector_func_load() 的信息,如下所示:
如果未提供信息,则不会调用 collector_func_load()。在函数列表中,动态编译和装入的函数会显示为 <Unknown>。性能分析器中既看不到函数源代码,也看不到反汇编代码。
如果没有提供源文件名和行号表,但提供了函数的名称、大小以及地址,则函数列表中将显示动态编译和装入的函数的名称及度量。带注释的源代码是可用的,并且反汇编指令是可见的,只是行号被指定为 [?],这表示行号未知。
如果提供了源文件名,但未提供行号表,性能分析器显示的信息将与不提供源文件名所显示的信息类似,只是带注释的源代码开头将显示一个特殊索引行,以指示该函数由不带行号的指令组成。 例如:
1.121 1.121 <Function func0, instructions without line numbers> 1. #include <stdio.h>
如果提供了源文件名和行号表,将按照与常规编译函数相同的方式在 "Function"(函数)视图、"Source"(源)视图和 "Disassembly"(反汇编)视图中显示函数及其度量。
有关收集器 API 函数的更多信息,请参见动态函数和模块。
对于 Java 程序,大部分方法由 JVM 软件解释。在解释执行期间,在单独的线程上运行的 Java HotSpot 虚拟机会监视性能。在监视过程中,虚拟机可能决定使用已解释的一个或多个方法,生成相应的计算机代码,并执行更有效的计算机代码版本,而不是解释原始代码。
对于 Java 程序,无需使用收集器 API 函数。性能分析器通过在该方法的索引行下方使用一个特殊行,表明在带注释的反汇编代码列表中存在 JavaHotSpot 编译的代码,如以下示例所示。
11. public int add_int () { 12. int x = 0; 2.832 2.832 <Function: Routine.add_int: HotSpot-compiled leaf instructions> 0. 0. [ 12] 00000000: iconst_0 0. 0. [ 12] 00000001: istore_1
反汇编代码列表仅显示已解释的字节代码,而不显示编译的指令。缺省情况下,在该特殊行的旁边显示已编译代码的度量。该独占和非独占 CPU 时间与各行已解释字节代码的所有独占和非独占 CPU 时间总和不同。通常,如果多次调用该方法,已编译指令的 CPU 时间将大于已解释字节代码的 CPU 时间总和,这种差异之所以出现,是因为已解释代码只是在最初调用该方法时执行一次,而已编译代码则在其后执行。
带注释的源代码不显示 Java HotSpot 编译的函数。而是显示一个特殊索引行,以指示不带行号的指令。例如,下面显示了与上例显示的反汇编提取对应的带注释的源代码:
11. public int add_int () { 2.832 2.832 <Function: Routine.add_int(), instructions without line numbers> 0. 0. 12. int x = 0; <Function: Routine.add_int()>