本节描述了数据收集的限制,这些限制是由硬件、操作系统、程序的运行方式或收集器本身造成的。
对同时收集不同类型的数据来说,没有任何限制:您可以在收集某种数据类型的同时收集任何其他数据类型。
用于分析的分析间隔最小值和时钟精度取决于特定的操作环境。最大值设置为 1 秒。分析间隔值将向下舍入到最接近的时钟精度的整数倍。可以通过键入不带参数的 collect 命令来查找最小值和最大值以及时钟精度。
基于时钟的分析记录当 SIGPROF 信号传递到目标时的数据。这将导致在处理该信号和展开调用栈时产生扩大。调用栈越深,信号越频繁,扩大越显著。在一定程度上,基于时钟的分析表现出一些失真,这是由程序中那些执行最深栈部分的显著扩大而导致的。
请尽可能不要将缺省值设置为一个精确的毫秒数,而是将其设置为稍大于或稍小于某个精确数(例如,10.007 毫秒或 0.997 毫秒),以免与系统时钟关联,从而避免数据失真。在 SPARC 平台上,可以按照同样的方式来设置定制值(在 Linux 平台上不能设置定制值)。
只有在已预装入收集器库 libcollector.so 的情况下,才可以从已在运行的程序中收集任何种类的跟踪数据。有关更多信息,请参见从正在运行的程序中收集跟踪数据。
跟踪数据使运行与被跟踪事件的数量成比例地扩大。如果完成了基于时钟的分析,则跟踪事件所引起的扩大将导致时钟数据失真。
硬件计数器溢出分析存在多种限制:
只能在具有硬件计数器且支持溢出分析的处理器上收集硬件计数器溢出数据。在其他系统中,硬件计数器溢出分析功能处于禁用状态。UltraSPARC® III 处理器系列之前的 UltraSPARC 处理器不支持硬件计数器溢出分析。
在 cpustat(1) 运行过程中无法收集系统的硬件计数器溢出数据,原因是 cpustat 控制了这些计数器,不允许用户进程使用它们。如果 cpustat 是在数据收集过程中启动的,则硬件计数器溢出分析将终止,而且会在实验中记录一条错误。
如果正在执行硬件计数器溢出分析, 则无法将自己代码中的硬件计数器与 libcpc(3) API 同时使用。如果调用不是来自收集器,则收集器将插入 libcpc 库函数并返回一个返回值 -1。您应当对程序进行适当编码,使其在无法访问硬件计数器时能够正常工作。如果未进行这样的编码,或者如果根调用了同样使用计数器的系统范围的工具,程序将在硬件计数器分析过程中失败。
如果您试图通过向进程附加 dbx 来在使用硬件计数器库的运行的程序上收集硬件计数器数据,则实验可能会被破坏。
要查看所有可用计数器的列表,请运行不带参数的 collect 命令。
硬件计数器溢出分析功能记录当 SIGEMT 传递到目标时的数据。这将导致在处理该信号和展开调用栈时产生扩大。与基于时钟的分析不同的是,对于某些硬件计数器,程序的不同部分可能会比其他部分更快速地生成事件并显示在该部分代码中的扩大。程序中快速生成这类事件的任何部分都可能会显著失真。类似地,某些事件可能会在一个线程中与其他线程不成比例地生成。
如果要在收集器所跟踪的所有后续进程中收集数据,就必须使用带有下列选项之一的 collect 命令:
-F all 选项导致收集器跟踪所有后续进程(包括那些因调用 system、popen 和 sh 而产生的进程)。
-F '=regexp' 选项允许在其名称或沿袭与指定的正则表达式相匹配的所有后续进程上收集数据。
有关 -F 选项的更多信息,请参 实验控制选项。
应当使用版本不低于 1.5.0_03 的 Java 2 Platform, Standard Edition (J2SE)。缺省情况下,collect 命令使用 Sun Studio 安装程序安装 J2SE 的路径(如果有)。可以通过设置 JDK_HOME 环境变量或 JAVA_PATH 环境变量来覆盖此缺省路径。收集器会验证它在这些环境变量中找到的 java 版本是否为 ELF 可执行文件,如果不是,则列显一条错误消息,指出所使用的环境变量以及已尝试使用的全路径名。
必须使用 collect 命令来收集数据,而不能使用 dbx collector 子命令或 IDE 的数据收集功能。
如果应用程序所创建的后续进程运行 JVM 软件,则不能对这些应用程序进行分析。
如果要使用 64 位 JVM 软件,则必须使用 -j on 标志并将 64 位 JVM 软件指定为目标。请不要使用 java -d64 在 64 位 JVM 软件中收集数据,否则收集不到任何数据。
Java 分析功能使用的 Java 虚拟机工具接口 (Java Virtual Machine Tool Interface, JVMTI) 可能会导致运行的失真和扩大。
对于基于时钟的分析和硬件计数器溢出分析,数据收集进程会对 JVM 软件进行各种调用,并使用信号处理程序处理分析事件。这些例程的开销和将实验写入磁盘的代价将扩大 Java 程序的运行时。这种扩大通常小于 10%。
对于同步跟踪,数据收集功能使用其他 JVMTI 事件,这将导致扩大(与应用程序中监视争用数量成比例)。