// Timeout in minutes. Make it larger than the run-test timeout to get a native thread dump by // ART on timeout when running on the host. privatefinalstaticlong TIMEOUT_VALUE = 7;
privatefinalstaticlong MAX_SIZE = 1000; // Maximum size of array-list to allocate.
privatefinalstaticint THREAD_COUNT = 16;
// Use a couple of different forms of synchronizing to test some of these... privatefinalstatic AtomicInteger counter = new AtomicInteger(-1); privatefinalstatic Object gate = new Object(); privatevolatilestaticint waitCount = 0;
static { // If we're using the interpreter for the boot class path, the VarHandle implementation of // AtomicInteger.incrementAndGet() needs to resolve a MethodType which is then cached for // subsequent uses. Make sure the MethodType is resolved early, otherwise the // counter.incrementAndGet() call in work(), after we have tried to allocate all memory, // could throw OOME.
counter.incrementAndGet();
}
// This barrier is used to synchronize the threads starting to allocate. // Note: Even though a barrier is not allocation-free, this one is fine, as it will be used // before filling the heap.
CyclicBarrier startBarrier = new CyclicBarrier(threads.length);
for (int i = 0; i < threads.length; i++) {
threads[i] = newThread(new Main(startBarrier));
threads[i].start();
}
// Wait for the threads to finish. for (Threadthread : threads) { thread.join();
}
// Allocate objects to definitely run GC before quitting.
allocateObjectsToRunGc();
new ArrayList<Object>(50);
}
privatestaticvoid allocateObjectsToRunGc() {
ArrayList<Object> l = new ArrayList<Object>(); try { for (int i = 0; i < 100000; i++) {
l.add(new ArrayList<Object>(i));
}
} catch (OutOfMemoryError oom) {
}
}
publicvoid run() { try {
work();
} catch (Throwable t) { // Any exception or error getting here is bad. try { // May need allocations...
t.printStackTrace(System.out);
} catch (Throwable tInner) {
}
System.exit(1);
}
}
privatevoid work() throws Exception { // Any exceptions except an OOME in the allocation loop are bad and handed off to the // caller which should abort the whole runtime.
ArrayList<Object> l = new ArrayList<Object>();
store = l; // Keep it alive.
// Wait for the start signal.
startBarrier.await(TIMEOUT_VALUE, java.util.concurrent.TimeUnit.MINUTES);
// Allocate. try { for (int i = 0; i < MAX_SIZE; i++) {
l.add(new ArrayList<Object>(i));
}
} catch (OutOfMemoryError oome) { // Fine, we're done.
}
// Atomically increment the counter and check whether we were last. int number = counter.incrementAndGet();
if (number < THREAD_COUNT) { // Not last. synchronized (gate) { // Increment the wait counter.
waitCount++;
gate.wait(TIMEOUT_VALUE * 1000 * 60);
}
} else { // Last. Wait until waitCount == THREAD_COUNT - 1. for (int loops = 0; ; loops++) { synchronized (gate) { if (waitCount == THREAD_COUNT - 1) { // OK, everyone's waiting. Notify and break out.
gate.notifyAll(); break;
} elseif (loops > 40) { // 1s wait, too many tries.
System.out.println("Waited too long for the last thread.");
System.exit(1);
}
} // Wait a bit. Thread.sleep(25);
}
}
store = null; // Allow GC to reclaim it.
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 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.