/* * Copyright (c) 2014, 2022, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
publicclass MallocStressTest { privatestaticint K = 1024;
// The stress test runs in three phases: // 1. alloc: A lot of malloc with fewer free, which simulates a burst memory allocation // that is usually seen during startup or class loading. // 2. pause: Pause the test to check accuracy of native memory tracking // 3. release: Release all malloc'd memory and check native memory tracking result. publicenum TestPhase {
alloc,
pause,
release
};
// Grab my own PID
String pid = Long.toString(ProcessTools.getProcessId());
ProcessBuilder pb = new ProcessBuilder();
AllocThread[] alloc_threads = new AllocThread[40];
ReleaseThread[] release_threads = new ReleaseThread[10];
int index; // Create many allocation threads for (index = 0; index < alloc_threads.length; index ++) {
alloc_threads[index] = new AllocThread();
}
// Fewer release threads for (index = 0; index < release_threads.length; index ++) {
release_threads[index] = new ReleaseThread();
}
// pause the stress test
phase = TestPhase.pause; while (pause_count.intValue() < alloc_threads.length + release_threads.length) {
sleep_wait(10);
}
long mallocd_total_in_KB = (mallocd_total + K / 2) / K;
// Now check if the result from NMT matches the total memory allocated.
String expected_test_summary = "Test (reserved=" + mallocd_total_in_KB +"KB, committed=" + mallocd_total_in_KB + "KB)"; // Run 'jcmd <pid> VM.native_memory summary'
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
output = new OutputAnalyzer(pb.start());
output.shouldContain(expected_test_summary);
// Join all threads for (index = 0; index < alloc_threads.length; index ++) { try {
alloc_threads[index].join();
} catch (InterruptedException e) {
}
}
for (index = 0; index < release_threads.length; index ++) { try {
release_threads[index].join();
} catch (InterruptedException e) {
}
}
// All test memory allocated should be released
output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Test (reserved=");
// Verify that tracking level has not been downgraded
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Tracking level has been downgraded due to lack of resources");
}
long addr() { returnthis.addr; } int size() { returnthis.size; }
}
staticclass AllocThread extendsThread { privatefinal Random random = new Random(Utils.getRandomInstance().nextLong());
AllocThread() { this.setName("MallocThread"); this.start();
}
// AllocThread only runs "Alloc" phase publicvoid run() { // MallocStressTest.phase == TestPhase.alloc for (int loops = 0; loops < 100; loops++) { int r = random.nextInt(Integer.MAX_VALUE); // Only malloc small amount to avoid OOM int size = r % 32; if (is_64_bit_system()) {
r = r % 32 * K;
} else {
r = r % 64;
} if (size == 0) size = 1; long addr = MallocStressTest.whiteBox.NMTMallocWithPseudoStack(size, r); if (addr != 0) { try {
MallocMemory mem = new MallocMemory(addr, size); synchronized(MallocStressTest.mallocd_memory) {
MallocStressTest.mallocd_memory.add(mem);
MallocStressTest.mallocd_total += size;
}
} catch (OutOfMemoryError e) { // Don't include this malloc memory because it didn't // get recorded in mallocd_memory list.
MallocStressTest.whiteBox.NMTFree(addr); break;
}
} else { break;
}
}
MallocStressTest.pause_count.incrementAndGet();
}
}
staticclass ReleaseThread extendsThread { privatefinal Random random = new Random(Utils.getRandomInstance().nextLong());
ReleaseThread() { this.setName("ReleaseThread"); this.start();
}
publicvoid run() { while(true) { switch(MallocStressTest.phase) { case alloc:
slow_release(); break; case pause:
enter_pause(); break; case release:
quick_release(); return;
}
}
}
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.