对于 Linux 特定的解决方案,您可能想分别查看进程和线程统计信息/proc/<pid>/stat
。/proc/<pid>/task/<tid>/stat
查看proc(5)
手册页以获取那里所有字段的完整描述(在线http://man7.org/linux/man-pages/man5/proc.5.html - 搜索/proc/[pid]/stat
)。cutime
具体来说,至少stime
是您感兴趣的领域。这些是单调递增的时间,因此您需要记住先前测量的值,以便能够生成在给定时间片内进程/线程中花费的时间,以便为您的图表生成数据。(这就是top(1)
工作原理。)
然而,对于分析器来说,区分不同的状态会使问题变得更加复杂。分析器如何区分被分析的程序处于哪个状态?在我看来,被分析的程序线程需要以某种方式向分析器发出信号。您需要为这种状态共享提供某种量身定制的解决方案(除非您可以在不同的线程中运行不同的状态并以这种方式进行区分,我对此表示怀疑)。
如果状态转换是在一个地方完成的(例如,在您的示例中进入 GC并离开 GC),那么一种方法如下:
- 被监视的线程将通过使用 POSIX 函数获得特殊状态的开始和结束时间
clock_gettime()
-clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp)
您可以获得进程时间,并且clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)
可以获得线程时间(两者都是单调递增的)。
- 线程可以使用某种 IPC 将这些时间传递给分析器程序。
- 如果 profiler 应用程序知道进入和离开状态的线程时间,那么由于它知道测量切片变化时的线程时间值,它可以确定在报告时间片内报告的状态中花费了多少线程时间(当然,这里我们需要调整一个状态的开始时间,使其等于下一个报告时间片的开始)。
- 整个进程在特定状态上花费的时间可以通过对该状态的线程时间求和来计算。
请注意,通过/proc/<pid>/stat
or /proc/<pid>/task/<tid>/stat
,测量精度不是很好(时钟滴答,通常以 10ms 为单位),但我不知道从进程/线程外部获取计时信息的其他方式。该函数clock_gettime()
给出了非常准确的时间(名义上为纳秒精度,但请注意,至少在某些 MIPS 和 ARM 系统中,由于 Linux 内核中这些字段的准确计时器读取不存在实现,因此至少在某些 MIPS 和 ARM 系统中,精度与下面的stat
文件一样差)。/proc
您还需要进行一些实验以确保这两个计时源确实会给出相同的结果(通过从同一线程读取两个值)。你当然可以使用这些/proc/.../stat
线程内部的文件,但是除非您在一个状态中花费大量时间,否则准确性不是很好。