Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest2.java
38821 views
/*1* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* Test low memory detection of non-heap memory pool.25*26* The test set a listener to be notified when any of the non-heap pools27* exceed 80%. It then starts a thread that continuously loads classes.28* In the HotSpot implementation this causes metaspace to be consumed.29* Test completes when we the notification is received or an OutOfMemory30* is generated.31*/3233import java.lang.management.*;34import javax.management.*;35import javax.management.openmbean.CompositeData;36import java.util.*;3738public class LowMemoryTest2 {3940private static volatile boolean listenerInvoked = false;4142private static String INDENT = " ";4344static class SensorListener implements NotificationListener {45public void handleNotification(Notification notif, Object handback) {46String type = notif.getType();47if (type.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED) ||48type.equals(MemoryNotificationInfo.49MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) {50listenerInvoked = true;51MemoryNotificationInfo minfo = MemoryNotificationInfo.52from((CompositeData) notif.getUserData());5354System.out.print("Notification for " + minfo.getPoolName());55System.out.print(" [type = " + type);56System.out.println(" count = " + minfo.getCount() + "]");57System.out.println(INDENT + "usage = " + minfo.getUsage());58}59}60}6162// Loads classes Test100001, Test100002, .... until OutOfMemoryErrror or63// low memory notification6465static class BoundlessLoaderThread extends ClassLoader implements Runnable {6667static int count = 100000;6869Class loadNext() throws ClassNotFoundException {7071// public class TestNNNNNN extends java.lang.Object{72// public TestNNNNNN();73// Code:74// 0: aload_075// 1: invokespecial #1; //Method java/lang/Object."<init>":()V76// 4: return77// }7879int begin[] = {800xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,810x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,820x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,830x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,840x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,850x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,860x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };8788int end [] = {890x01, 0x00, 0x10,900x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,910x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,920x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,930x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,940x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,950x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,960x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,970x00, 0x00, 0x00, 0x00, 0x00 };9899100// TestNNNNNN101102int load_count = count++;103if (load_count > 999999) {104// The test will create a corrupt class file if the count105// exceeds 999999. Fix the test if this exception is thrown.106throw new RuntimeException("Load count exceeded");107}108109String name = "Test" + Integer.toString(load_count);110111byte value[];112try {113value = name.substring(4).getBytes("UTF-8");114} catch (java.io.UnsupportedEncodingException x) {115throw new Error();116}117118// construct class file119120int len = begin.length + value.length + end.length;121byte b[] = new byte[len];122int i, pos=0;123for (i=0; i<begin.length; i++) {124b[pos++] = (byte)begin[i];125}126for (i=0; i<value.length; i++) {127b[pos++] = value[i];128}129for (i=0; i<end.length; i++) {130b[pos++] = (byte)end[i];131}132133return defineClass(name, b, 0, b.length);134}135136/*137* Run method for thread that continuously loads classes.138*139* Note: Once the usage threshold has been exceeded the low memory140* detector thread will attempt to deliver its notification - this can141* potentially create a race condition with this thread contining to142* fill up metaspace. To avoid the low memory detector getting an143* OutOfMemory we throttle this thread once the threshold has been144* exceeded.145*/146public void run() {147List pools = ManagementFactory.getMemoryPoolMXBeans();148boolean thresholdExceeded = false;149150for (;;) {151try {152// the classes are small so we load 10 at a time153for (int i=0; i<10; i++) {154loadNext();155}156} catch (ClassNotFoundException x) {157return;158}159if (listenerInvoked) {160return;161}162163// if threshold has been exceeded we put in a delay to allow164// the low memory detector do its job.165if (thresholdExceeded) {166try {167Thread.currentThread().sleep(100);168} catch (InterruptedException x) { }169} else {170// check if the threshold has been exceeded171ListIterator i = pools.listIterator();172while (i.hasNext()) {173MemoryPoolMXBean p = (MemoryPoolMXBean) i.next();174if (p.getType() == MemoryType.NON_HEAP &&175p.isUsageThresholdSupported())176{177thresholdExceeded = p.isUsageThresholdExceeded();178}179}180}181}182}183}184185public static void main(String args[]) {186ListIterator iter = ManagementFactory.getMemoryPoolMXBeans().listIterator();187188// Set threshold of 80% of all NON_HEAP memory pools189// In the Hotspot implementation this means we should get a notification190// if the CodeCache or metaspace fills up.191192while (iter.hasNext()) {193MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();194if (p.getType() == MemoryType.NON_HEAP && p.isUsageThresholdSupported()) {195196// set threshold197MemoryUsage mu = p.getUsage();198long max = mu.getMax();199if (max < 0) {200throw new RuntimeException("There is no maximum set for "201+ p.getName() + " memory pool so the test is invalid");202}203long threshold = (max * 80) / 100;204205p.setUsageThreshold(threshold);206207System.out.println("Selected memory pool for low memory " +208"detection.");209MemoryUtil.printMemoryPool(p);210211}212}213214215// Install the listener216217MemoryMXBean mm = ManagementFactory.getMemoryMXBean();218SensorListener l2 = new SensorListener();219220NotificationEmitter emitter = (NotificationEmitter) mm;221emitter.addNotificationListener(l2, null, null);222223// Start the thread loading classes224225Thread thr = new Thread(new BoundlessLoaderThread());226thr.start();227228// Wait for the thread to terminate229try {230thr.join();231} catch (InterruptedException x) {232throw new RuntimeException(x);233}234235if (listenerInvoked) {236System.out.println("Notification received - test passed.");237} else {238throw new RuntimeException("Test failed - notification not received!");239}240}241242}243244245