163 /**
164 * Generate a thread dump in plain text format to the given text stream.
165 * @throws UncheckedIOException if an I/O error occurs
166 */
167 private static void dumpThreads(TextWriter writer) {
168 writer.println(processId());
169 writer.println(Instant.now());
170 writer.println(Runtime.version());
171 writer.println();
172 dumpThreads(ThreadContainers.root(), writer);
173 }
174
175 private static void dumpThreads(ThreadContainer container, TextWriter writer) {
176 container.threads().forEach(t -> dumpThread(t, writer));
177 container.children().forEach(c -> dumpThreads(c, writer));
178 }
179
180 private static boolean dumpThread(Thread thread, TextWriter writer) {
181 ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
182 if (snapshot == null) {
183 return false; // thread terminated
184 }
185 Instant now = Instant.now();
186 Thread.State state = snapshot.threadState();
187 writer.println("#" + thread.threadId() + " \"" + snapshot.threadName()
188 + "\" " + (thread.isVirtual() ? "virtual " : "") + state + " " + now);
189
190 StackTraceElement[] stackTrace = snapshot.stackTrace();
191 int depth = 0;
192 while (depth < stackTrace.length) {
193 writer.print(" at ");
194 writer.println(stackTrace[depth]);
195 snapshot.ownedMonitorsAt(depth).forEach(o -> {
196 if (o != null) {
197 writer.println(" - locked " + decorateObject(o));
198 } else {
199 writer.println(" - lock is eliminated");
200 }
201 });
202
203 // if parkBlocker set, or blocked/waiting on monitor, then print after top frame
301 if (!ThreadContainers.trackAllThreads()) {
302 threadCount = Long.max(threadCount, container.threadCount());
303 }
304 jsonWriter.writeProperty("threadCount", threadCount);
305
306 jsonWriter.endObject();
307
308 // the children of the thread container follow
309 container.children().forEach(c -> dumpThreads(c, jsonWriter));
310 }
311
312 /**
313 * Write a thread to the given JSON writer.
314 * @return true if the thread dump was written, false otherwise
315 * @throws UncheckedIOException if an I/O error occurs
316 */
317 private static boolean dumpThread(Thread thread, JsonWriter jsonWriter) {
318 Instant now = Instant.now();
319 ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
320 if (snapshot == null) {
321 return false; // thread terminated
322 }
323 Thread.State state = snapshot.threadState();
324 StackTraceElement[] stackTrace = snapshot.stackTrace();
325
326 jsonWriter.startObject();
327 jsonWriter.writeProperty("tid", thread.threadId());
328 jsonWriter.writeProperty("time", now);
329 if (thread.isVirtual()) {
330 jsonWriter.writeProperty("virtual", Boolean.TRUE);
331 }
332 jsonWriter.writeProperty("name", snapshot.threadName());
333 jsonWriter.writeProperty("state", state);
334
335 // park blocker
336 Object parkBlocker = snapshot.parkBlocker();
337 if (parkBlocker != null) {
338 // parkBlocker is an object to allow for exclusiveOwnerThread in the future
339 jsonWriter.startObject("parkBlocker");
340 jsonWriter.writeProperty("object", Objects.toIdentityString(parkBlocker));
341 if (snapshot.parkBlockerOwner() instanceof Thread owner) {
|
163 /**
164 * Generate a thread dump in plain text format to the given text stream.
165 * @throws UncheckedIOException if an I/O error occurs
166 */
167 private static void dumpThreads(TextWriter writer) {
168 writer.println(processId());
169 writer.println(Instant.now());
170 writer.println(Runtime.version());
171 writer.println();
172 dumpThreads(ThreadContainers.root(), writer);
173 }
174
175 private static void dumpThreads(ThreadContainer container, TextWriter writer) {
176 container.threads().forEach(t -> dumpThread(t, writer));
177 container.children().forEach(c -> dumpThreads(c, writer));
178 }
179
180 private static boolean dumpThread(Thread thread, TextWriter writer) {
181 ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
182 if (snapshot == null) {
183 return false; // thread not alive
184 }
185 Instant now = Instant.now();
186 Thread.State state = snapshot.threadState();
187 writer.println("#" + thread.threadId() + " \"" + snapshot.threadName()
188 + "\" " + (thread.isVirtual() ? "virtual " : "") + state + " " + now);
189
190 StackTraceElement[] stackTrace = snapshot.stackTrace();
191 int depth = 0;
192 while (depth < stackTrace.length) {
193 writer.print(" at ");
194 writer.println(stackTrace[depth]);
195 snapshot.ownedMonitorsAt(depth).forEach(o -> {
196 if (o != null) {
197 writer.println(" - locked " + decorateObject(o));
198 } else {
199 writer.println(" - lock is eliminated");
200 }
201 });
202
203 // if parkBlocker set, or blocked/waiting on monitor, then print after top frame
301 if (!ThreadContainers.trackAllThreads()) {
302 threadCount = Long.max(threadCount, container.threadCount());
303 }
304 jsonWriter.writeProperty("threadCount", threadCount);
305
306 jsonWriter.endObject();
307
308 // the children of the thread container follow
309 container.children().forEach(c -> dumpThreads(c, jsonWriter));
310 }
311
312 /**
313 * Write a thread to the given JSON writer.
314 * @return true if the thread dump was written, false otherwise
315 * @throws UncheckedIOException if an I/O error occurs
316 */
317 private static boolean dumpThread(Thread thread, JsonWriter jsonWriter) {
318 Instant now = Instant.now();
319 ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
320 if (snapshot == null) {
321 return false; // thread not alive
322 }
323 Thread.State state = snapshot.threadState();
324 StackTraceElement[] stackTrace = snapshot.stackTrace();
325
326 jsonWriter.startObject();
327 jsonWriter.writeProperty("tid", thread.threadId());
328 jsonWriter.writeProperty("time", now);
329 if (thread.isVirtual()) {
330 jsonWriter.writeProperty("virtual", Boolean.TRUE);
331 }
332 jsonWriter.writeProperty("name", snapshot.threadName());
333 jsonWriter.writeProperty("state", state);
334
335 // park blocker
336 Object parkBlocker = snapshot.parkBlocker();
337 if (parkBlocker != null) {
338 // parkBlocker is an object to allow for exclusiveOwnerThread in the future
339 jsonWriter.startObject("parkBlocker");
340 jsonWriter.writeProperty("object", Objects.toIdentityString(parkBlocker));
341 if (snapshot.parkBlockerOwner() instanceof Thread owner) {
|