# HG changeset patch # User mtobiass # Date 1393922154 -3600 # Node ID 788f0ea9a703bb6fb569323cd0f123d5036e13ea # Parent 241885315119c5c22b9782a06fd8ede18a751afd 8031065: java/lang/management/MemoryMXBean/LowMemoryTest2.sh fails: OutOfMemoryError: Metaspace Summary: Load classes until getUsageThresholdCount() > 0 instead of isUsageThresholdExceeded(). Reviewed-by: dfuchs, sjiang, sla diff -r 241885315119 -r 788f0ea9a703 jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest2.java --- a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest2.java Wed Mar 05 07:24:34 2014 +0000 +++ b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest2.java Tue Mar 04 09:35:54 2014 +0100 @@ -67,7 +67,7 @@ static int count = 100000; - Class loadNext() throws ClassNotFoundException { + Class loadNext() { // public class TestNNNNNN extends java.lang.Object{ // public TestNNNNNN(); @@ -135,63 +135,49 @@ } /* - * Run method for thread that continuously loads classes. - * - * Note: Once the usage threshold has been exceeded the low memory - * detector thread will attempt to deliver its notification - this can - * potentially create a race condition with this thread contining to - * fill up metaspace. To avoid the low memory detector getting an - * OutOfMemory we throttle this thread once the threshold has been - * exceeded. + * Load classes until MemoryPoolMXBean.getUsageThresholdCount() > 0. + * Then wait for the memory threshold notification to be received. */ public void run() { - List pools = ManagementFactory.getMemoryPoolMXBeans(); + List pools = ManagementFactory.getMemoryPoolMXBeans(); boolean thresholdExceeded = false; - for (;;) { - try { - // the classes are small so we load 10 at a time - for (int i=0; i<10; i++) { - loadNext(); - } - } catch (ClassNotFoundException x) { - return; - } - if (listenerInvoked) { - return; + // Load classes until MemoryPoolMXBean.getUsageThresholdCount() > 0 + while (!thresholdExceeded) { + // the classes are small so we load 10 at a time + for (int i=0; i<10; i++) { + loadNext(); } - // if threshold has been exceeded we put in a delay to allow - // the low memory detector do its job. - if (thresholdExceeded) { - try { - Thread.currentThread().sleep(100); - } catch (InterruptedException x) { } - } else { - // check if the threshold has been exceeded - ListIterator i = pools.listIterator(); - while (i.hasNext()) { - MemoryPoolMXBean p = (MemoryPoolMXBean) i.next(); - if (p.getType() == MemoryType.NON_HEAP && - p.isUsageThresholdSupported()) - { - thresholdExceeded = p.isUsageThresholdExceeded(); - } + // check if the threshold has been exceeded + for (MemoryPoolMXBean p : pools) { + if (p.getType() == MemoryType.NON_HEAP && + p.isUsageThresholdSupported() && + p.getUsageThresholdCount() > 0) + { + thresholdExceeded = true; + break; } } } + + System.out.println("thresholdExceeded. Waiting for notification"); + while (!listenerInvoked) { + try { + Thread.currentThread().sleep(10); + } catch (InterruptedException x) {} + } } } public static void main(String args[]) { - ListIterator iter = ManagementFactory.getMemoryPoolMXBeans().listIterator(); + List pools = ManagementFactory.getMemoryPoolMXBeans(); // Set threshold of 80% of all NON_HEAP memory pools // In the Hotspot implementation this means we should get a notification // if the CodeCache or metaspace fills up. - while (iter.hasNext()) { - MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next(); + for (MemoryPoolMXBean p : pools) { if (p.getType() == MemoryType.NON_HEAP && p.isUsageThresholdSupported()) { // set threshold