Fel*_*lix 3 java performance profiling jvmti
当通过Thread#getStackTrace()or从另一个线程请求堆栈跟踪时ThreadMXBean#getThreadInfo(long[], int),是否所有线程都必须进入安全点,从而必须等到所有其他线程都进入安全点?
这个博客似乎表明情况是这样的:
无论您是对单个线程还是所有线程进行采样,您都达到了全局安全点(至少在 OpenJDK 上,Zing 略有不同,但作为分析器供应商 OpenJDK 是您的假设。)
这意味着从单个线程获取堆栈跟踪与获取所有堆栈跟踪一样具有侵入性(就高开销而言,由于全局安全点命中的频率增加)。
但是对于 OpenJDK 来说,这实际上/仍然如此吗?您是否有任何指示为什么会这样或相关源代码?
在 OpenJDK 中(直到当前的 JDK 13)Thread.getStackTrace()仍然在全局停止世界安全点运行:
public StackTraceElement[] getStackTrace() {
if (this != Thread.currentThread()) {
....
StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
Run Code Online (Sandbox Code Playgroud)
这归结为ThreadService::dump_stack_traces,它VM_ThreadDump在 VM 线程中执行操作。所有VM_*操作过去都在全局安全点运行。
JEP 312: JDK 10 中引入的线程本地握手,提供了每线程安全点机制。现在VM_Handshake及其所有后代都不需要全局安全点:
class VM_Handshake: public VM_Operation {
const jlong _handshake_timeout;
public:
bool evaluate_at_safepoint() const { return false; }
Run Code Online (Sandbox Code Playgroud)
然而,VM_ThreadDump并不是这样的操作。两者都不VM_GetStackTrace用于实现 JVM TI GetStackTrace 函数。
有一个未解决的问题JDK-8201641使用线程本地握手在未来某个时间获取单个线程的堆栈跟踪。
| 归档时间: |
|
| 查看次数: |
208 次 |
| 最近记录: |