Path: blob/master/test/jdk/java/lang/management/MemoryMXBean/MemoryManagement.java
41155 views
/*1* Copyright (c) 2003, 2016, 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* @test25* @bug 4530538 698098426* @summary Basic unit test of memory management testing:27* 1) setUsageThreshold() and getUsageThreshold()28* 2) test low memory detection on the old generation.29*30* @author Mandy Chung31*32* @modules jdk.management33* @build MemoryManagement MemoryUtil34* @run main/othervm/timeout=600 -Xmn8m -XX:+IgnoreUnrecognizedVMOptions -XX:G1HeapRegionSize=1 -XX:-UseLargePages MemoryManagement35*/3637import java.lang.management.*;38import java.util.*;39import javax.management.*;40import javax.management.openmbean.CompositeData;4142public class MemoryManagement {43private static final MemoryMXBean mm = ManagementFactory.getMemoryMXBean();44private static final List pools =45Collections.synchronizedList(ManagementFactory.getMemoryPoolMXBeans());46private static final List managers =47Collections.synchronizedList(ManagementFactory.getMemoryManagerMXBeans());48private static volatile MemoryPoolMXBean mpool = null;49private static volatile boolean trace = false;50private static volatile boolean testFailed = false;51private static final int NUM_CHUNKS = 2;52// Must match -Xmn set on the @run line53private static final int YOUNG_GEN_SIZE = 8 * 1024 * 1024;54private static volatile long chunkSize;55private static volatile int listenerInvoked = 0;5657static class SensorListener implements NotificationListener {58public void handleNotification(Notification notif, Object handback) {59String type = notif.getType();60if (type.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED) ||61type.equals(MemoryNotificationInfo.62MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) {6364MemoryNotificationInfo minfo = MemoryNotificationInfo.65from((CompositeData) notif.getUserData());6667MemoryUtil.printMemoryNotificationInfo(minfo, type);68listenerInvoked++;69}70}71}7273private static long newThreshold;74public static void main(String args[]) throws Exception {75if (args.length > 0 && args[0].equals("trace")) {76trace = true;77}7879if (trace) {80MemoryUtil.printMemoryPools(pools);81MemoryUtil.printMemoryManagers(managers);82}8384// Find the Old generation which supports low memory detection85ListIterator iter = pools.listIterator();86while (iter.hasNext()) {87MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();88if (p.getType() == MemoryType.HEAP &&89p.isUsageThresholdSupported()) {90mpool = p;91if (trace) {92System.out.println("Selected memory pool for low memory " +93"detection.");94MemoryUtil.printMemoryPool(mpool);95}96break;97}98}99100SensorListener listener = new SensorListener();101NotificationEmitter emitter = (NotificationEmitter) mm;102emitter.addNotificationListener(listener, null, null);103104Thread allocator = new AllocatorThread();105106// The chunk size needs to be larger than YOUNG_GEN_SIZE,107// otherwise we will get intermittent failures when objects108// end up in the young gen instead of the old gen.109final long epsilon = 1024;110chunkSize = YOUNG_GEN_SIZE + epsilon;111112// Now set threshold113MemoryUsage mu = mpool.getUsage();114newThreshold = mu.getUsed() + (chunkSize * NUM_CHUNKS);115116// Sanity check. Make sure the new threshold isn't too large.117// Tweak the test if this fails.118final long headRoom = chunkSize * 2;119final long max = mu.getMax();120if (max != -1 && newThreshold > max - headRoom) {121throw new RuntimeException("TEST FAILED: newThreshold: " + newThreshold +122" is too near the maximum old gen size: " + max +123" used: " + mu.getUsed() + " headRoom: " + headRoom);124}125126System.out.println("Setting threshold for " + mpool.getName() +127" from " + mpool.getUsageThreshold() + " to " + newThreshold +128". Current used = " + mu.getUsed());129mpool.setUsageThreshold(newThreshold);130131if (mpool.getUsageThreshold() != newThreshold) {132throw new RuntimeException("TEST FAILED: " +133"Threshold for Memory pool " + mpool.getName() +134"is " + mpool.getUsageThreshold() + " but expected to be" +135newThreshold);136}137138// Start the AllocatorThread to continously allocate memory139System.out.println("Starting an AllocatorThread to allocate memory.");140allocator.start();141142try {143allocator.join();144} catch (InterruptedException e) {145e.printStackTrace();146System.out.println("Unexpected exception.");147testFailed = true;148}149150if (listenerInvoked == 0) {151throw new RuntimeException("No listener is invoked");152}153154if (testFailed)155throw new RuntimeException("TEST FAILED.");156157System.out.println("Test passed.");158159}160161static class AllocatorThread extends Thread {162private List objectPool = new ArrayList();163public void run() {164int iterations = 0;165int numElements = (int) (chunkSize / 4); // minimal object size166while (listenerInvoked == 0) {167iterations++;168if (trace) {169System.out.println(" Iteration " + iterations +170": before allocation " +171mpool.getUsage().getUsed());172}173174Object[] o = new Object[numElements];175if (iterations <= NUM_CHUNKS) {176// only hold a reference to the first NUM_CHUNKS177// allocated objects178objectPool.add(o);179}180181if (trace) {182System.out.println(" " +183" after allocation " +184mpool.getUsage().getUsed());185}186try {187Thread.sleep(100);188} catch (InterruptedException e) {189e.printStackTrace();190System.out.println("Unexpected exception.");191testFailed = true;192}193}194195System.out.println("AllocatedThread finished memory allocation " +196" num_iteration = " + iterations);197}198}199200}201202203