Skip to content

Commit 71f4839

Browse files
committed
fix: disable lockedSynchronizers in dumpAllThreads to avoid safepoint heap scan (#16194)
`ThreadMXBean.dumpAllThreads(true, true)` with lockedSynchronizers=true forces the JVM to scan the entire heap at a safepoint to find all AbstractOwnableSynchronizer instances. On ZGC with large heaps (65GB+), this causes ~37-second safepoint pauses that freeze all application threads, leading to cascading thread pool exhaustion. Change lockedSynchronizers from true to false. This retains locked monitor information (derived from thread stacks, cheap) but skips the expensive heap scan. Only java.util.concurrent.locks ownership info is lost from the thread dump output. Fixes #16194
1 parent 69084bd commit 71f4839

1 file changed

Lines changed: 6 additions & 1 deletion

File tree

  • dubbo-common/src/main/java/org/apache/dubbo/common/utils

dubbo-common/src/main/java/org/apache/dubbo/common/utils/JVMUtil.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@
3333
public class JVMUtil {
3434
public static void jstack(OutputStream stream) throws Exception {
3535
ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
36-
for (ThreadInfo threadInfo : threadMxBean.dumpAllThreads(true, true)) {
36+
// Pass lockedSynchronizers=false to avoid a full heap scan at safepoint.
37+
// With lockedSynchronizers=true, the JVM iterates the entire heap to find all
38+
// AbstractOwnableSynchronizer instances. On ZGC with large heaps, this causes
39+
// tens-of-seconds safepoint pauses due to load barrier overhead on every reference.
40+
// See: https://github.com/apache/dubbo/issues/16194
41+
for (ThreadInfo threadInfo : threadMxBean.dumpAllThreads(true, false)) {
3742
stream.write(getThreadDumpString(threadInfo).getBytes(StandardCharsets.UTF_8));
3843
}
3944
}

0 commit comments

Comments
 (0)