publicclass Main implements Runnable { staticfinalint NUMBER_OF_THREADS = 5; staticvolatileint ops_per_thread = 1000; static AtomicInteger operations_completed = new AtomicInteger(0); staticint[] progress = newint[NUMBER_OF_THREADS]; static AtomicInteger totalStackFrames = new AtomicInteger(0); staticfinalboolean printStats = false; // True causes test to fail. int index;
Main(int i) {
index = i;
}
publicstaticvoid main(String[] args) throws Exception { finalThread[] threads = newThread[NUMBER_OF_THREADS]; Thread watchdog = newThread() { publicvoid run() { try { if (printStats) {
System.out.println("ops_per_thread = " + ops_per_thread);
} Thread.sleep(10_000); if (printStats) {
System.out.println("Ops completed after 10 seconds: " +
operations_completed.get());
} if (operations_completed.get() < NUMBER_OF_THREADS * ops_per_thread / 2) { // We're in some sort of "go slow" mode, probably gcstress. Finish early.
ops_per_thread /= 10;
} if (printStats) {
System.out.println("ops_per_thread = " + ops_per_thread);
} Thread.sleep(200_000);
System.out.print("Watchdog timed out: "); for (int i = 0; i < NUMBER_OF_THREADS; ++i) {
System.out.print(progress[i] + ", ");
}
System.out.println("");
System.err.println("Watchdog thread timed out");
System.exit(1);
} catch (InterruptedException e) {}
}
};
watchdog.start(); long start_millis = System.currentTimeMillis(); for (int t = 0; t < threads.length; t++) {
threads[t] = newThread(new Main(t));
threads[t].start();
} for (Thread t : threads) {
t.join();
} if (printStats) { long elapsed_millis = System.currentTimeMillis() - start_millis;
System.out.println("Captured " + totalStackFrames + " stack frames in " +
elapsed_millis + "msecs");
}
System.out.println("All joined"); // Do this test after the other part to leave some time for the heap task daemon to start // up.
test_getStackTraces();
watchdog.interrupt();
System.out.println("Finishing");
}
staticThread getHeapTaskDaemon() throws Exception {
Field f = ThreadGroup.class.getDeclaredField("systemThreadGroup");
f.setAccessible(true);
ThreadGroup systemThreadGroup = (ThreadGroup) f.get(null);
while (true) { int activeCount = systemThreadGroup.activeCount(); Thread[] array = newThread[activeCount];
systemThreadGroup.enumerate(array); for (Threadthread : array) { if (thread.getName().equals("HeapTaskDaemon") && thread.getState() != Thread.State.NEW) { returnthread;
}
} // Yield to eventually get the daemon started. Thread.sleep(10);
}
}
// Force a GC to ensure the daemon truly started.
Runtime.getRuntime().gc(); // Check all the current threads for positive IDs.
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces(); for (Map.Entry<Thread, StackTraceElement[]> pair : map.entrySet()) { Threadthread = pair.getKey(); // Expect empty stack trace since we do not support suspending the GC thread for // obtaining stack traces. See b/28261069. if (thread == heapDaemon) {
System.out.println(thread.getName() + " depth " + pair.getValue().length);
}
}
}
publicvoid test_getId() { if (Thread.currentThread().getId() <= 0) {
System.out.println("current thread's ID is not positive");
} // Check all the current threads for positive IDs.
Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces(); for (Threadthread : stMap.keySet()) { if (thread.getId() <= 0) {
System.out.println("thread's ID is not positive: " + thread.getName());
}
totalStackFrames.addAndGet(stMap.get(thread).length);
}
}
publicvoid run() { for (int i = 1; i <= ops_per_thread; ++i) {
test_getId();
operations_completed.addAndGet(1);
progress[index] = i;
}
System.out.println("Thread finished");
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.