mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8309406: Change jdk.trackAllThreads to default to true
Reviewed-by: rpressler, mchung, cjplummer
This commit is contained in:
parent
6d155a47f1
commit
2e9eff5641
6 changed files with 243 additions and 141 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -29,7 +29,6 @@ import java.lang.invoke.VarHandle;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.internal.access.JavaLangAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
@ -50,16 +49,13 @@ public class SharedThreadContainer extends ThreadContainer implements AutoClosea
|
|||
VIRTUAL_THREADS = l.findVarHandle(SharedThreadContainer.class,
|
||||
"virtualThreads", Set.class);
|
||||
} catch (Exception e) {
|
||||
throw new InternalError(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// name of container, used by toString
|
||||
private final String name;
|
||||
|
||||
// the number of threads in the container
|
||||
private final LongAdder threadCount;
|
||||
|
||||
// the virtual threads in the container, created lazily
|
||||
private volatile Set<Thread> virtualThreads;
|
||||
|
||||
|
@ -76,7 +72,6 @@ public class SharedThreadContainer extends ThreadContainer implements AutoClosea
|
|||
private SharedThreadContainer(String name) {
|
||||
super(/*shared*/ true);
|
||||
this.name = name;
|
||||
this.threadCount = new LongAdder();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,21 +114,14 @@ public class SharedThreadContainer extends ThreadContainer implements AutoClosea
|
|||
}
|
||||
vthreads.add(thread);
|
||||
}
|
||||
threadCount.add(1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(Thread thread) {
|
||||
threadCount.add(-1L);
|
||||
if (thread.isVirtual())
|
||||
virtualThreads.remove(thread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long threadCount() {
|
||||
return threadCount.sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Thread> threads() {
|
||||
// live platform threads in this container
|
||||
|
|
|
@ -33,20 +33,35 @@ import java.util.concurrent.atomic.LongAdder;
|
|||
import java.util.stream.Stream;
|
||||
import jdk.internal.access.JavaLangAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.Poller;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* This class consists exclusively of static methods to support debugging and
|
||||
* monitoring of threads.
|
||||
* This class consists exclusively of static methods to support groupings of threads.
|
||||
*/
|
||||
public class ThreadContainers {
|
||||
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
// true if all threads are tracked
|
||||
private static final boolean TRACK_ALL_THREADS;
|
||||
|
||||
// the root container
|
||||
private static final RootContainer ROOT_CONTAINER;
|
||||
|
||||
// the set of thread containers registered with this class
|
||||
private static final Set<WeakReference<ThreadContainer>> CONTAINER_REGISTRY = ConcurrentHashMap.newKeySet();
|
||||
private static final ReferenceQueue<Object> QUEUE = new ReferenceQueue<>();
|
||||
|
||||
static {
|
||||
String s = GetPropertyAction.privilegedGetProperty("jdk.trackAllThreads");
|
||||
if (s == null || s.isEmpty() || Boolean.parseBoolean(s)) {
|
||||
TRACK_ALL_THREADS = true;
|
||||
ROOT_CONTAINER = new RootContainer.TrackingRootContainer();
|
||||
} else {
|
||||
TRACK_ALL_THREADS = false;
|
||||
ROOT_CONTAINER = new RootContainer.CountingRootContainer();
|
||||
}
|
||||
}
|
||||
|
||||
private ThreadContainers() { }
|
||||
|
||||
/**
|
||||
|
@ -59,6 +74,13 @@ public class ThreadContainers {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all threads are tracked.
|
||||
*/
|
||||
public static boolean trackAllThreads() {
|
||||
return TRACK_ALL_THREADS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a thread container to be tracked this class, returning a key
|
||||
* that is used to remove it from the registry.
|
||||
|
@ -83,7 +105,7 @@ public class ThreadContainers {
|
|||
* Returns the root thread container.
|
||||
*/
|
||||
public static ThreadContainer root() {
|
||||
return RootContainer.INSTANCE;
|
||||
return ROOT_CONTAINER;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,20 +205,10 @@ public class ThreadContainers {
|
|||
}
|
||||
|
||||
/**
|
||||
* Root container that "contains" all platform threads not started in a
|
||||
* container plus some (or all) virtual threads that are started directly
|
||||
* with the Thread API.
|
||||
* Root container that "contains" all platform threads not started in a container.
|
||||
* It may include all virtual threads started directly with the Thread API.
|
||||
*/
|
||||
private static abstract class RootContainer extends ThreadContainer {
|
||||
static final RootContainer INSTANCE;
|
||||
static {
|
||||
String s = GetPropertyAction.privilegedGetProperty("jdk.trackAllThreads");
|
||||
if (s != null && (s.isEmpty() || Boolean.parseBoolean(s))) {
|
||||
INSTANCE = new TrackingRootContainer();
|
||||
} else {
|
||||
INSTANCE = new CountingRootContainer();
|
||||
}
|
||||
}
|
||||
protected RootContainer() {
|
||||
super(true);
|
||||
}
|
||||
|
@ -270,11 +282,7 @@ public class ThreadContainers {
|
|||
}
|
||||
@Override
|
||||
public Stream<Thread> threads() {
|
||||
// virtual threads in this container that are those blocked on I/O.
|
||||
Stream<Thread> blockedVirtualThreads = Poller.blockedThreads()
|
||||
.filter(t -> t.isVirtual()
|
||||
&& JLA.threadContainer(t) == this);
|
||||
return Stream.concat(platformThreads(), blockedVirtualThreads);
|
||||
return platformThreads();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -240,7 +240,9 @@ public class ThreadDumper {
|
|||
out.println(" ],"); // end of threads
|
||||
|
||||
// thread count
|
||||
threadCount = Long.max(threadCount, container.threadCount());
|
||||
if (!ThreadContainers.trackAllThreads()) {
|
||||
threadCount = Long.max(threadCount, container.threadCount());
|
||||
}
|
||||
out.format(" \"threadCount\": \"%d\"%n", threadCount);
|
||||
|
||||
if (more) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue