在浏览https://www.oracle.com/technetwork/java/javaseproducts/mission-control/java-mission-control-wp-2008279.pdf时,我遇到了以下引用:
目前用于监视、管理和分析Java运行时的大多数技术都使用了相当具有侵入性的技术,如字节代码检测和JVMTI。
这让我想知道JFR做堆栈跟踪采样的方式。
我能在网上找到的最接近答案的就是这个博客文章:http://psy-lob-saw.blogspot.com/2016/06/the-pros-and-cons-of-agct.html,它提到了像诚实的分析器和异步分析器这样的分析器使用了没有这么多文档的AsyncGetCallTrace,但事实是它没有提到JFR进行堆栈跟踪采样/记录的具体方式。
这里有人对JFR关于这个话题的内部结构有任何深入的了解吗?
发布于 2019-11-05 03:35:34
JFR维护一个定期唤醒(即每10毫秒一次)的线程,并通过发送信号来挂起少量正在运行的Java线程。然后,它将遍历挂起的线程的堆栈,以查看正在执行的方法。它计算堆栈帧的散列,然后检查之前是否找到堆栈跟踪。
如果不是这种情况,则将堆栈帧添加到哈希表中,并转储一个计数器,该计数器将成为堆栈跟踪的id。然后,它以执行样例事件的形式发出id,该事件在另一个线程周期性地刷新到磁盘的缓冲区(锁空闲)中结束。如果id是新的,它还会写入与id对应的完整堆栈跟踪,因此堆栈跟踪可以稍后由解析器解析。
如果您想深入挖掘,可以查看源代码。
http://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/jfr/periodic/sampling
线程如何挂起取决于平台。在下面的文件中,您可以找到Linux实现。
http://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/os/linux/os_linux.cpp
https://stackoverflow.com/questions/58663531
复制相似问题