1 /* 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * The -XX:MarkSweepAlwaysCompactCount=1 argument below makes sure serial gc 26 * compacts the heap at every full gc so that the usage is correctly updated. 27 */ 28 29 /* 30 * @test 31 * @bug 4892507 32 * @summary Basic Test for MemoryPool.resetPeakUsage() 33 * @author Mandy Chung 34 * 35 * @build ResetPeakMemoryUsage MemoryUtil 36 * @run main/othervm -XX:+UseSerialGC -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage 37 * @run main/othervm -XX:+UseConcMarkSweepGC -Xmn8m ResetPeakMemoryUsage 38 * @run main/othervm -XX:+UseParallelGC -Xmn8m ResetPeakMemoryUsage 39 * @run main/othervm -XX:+UseG1GC -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage 40 */ 41 42 import java.lang.management.*; 43 import java.util.*; 44 45 public class ResetPeakMemoryUsage { 46 private static MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); 47 // make public so that it can't be optimized away easily 48 public static Object[] obj; 49 50 public static void main(String[] argv) { 51 List pools = ManagementFactory.getMemoryPoolMXBeans(); 52 ListIterator iter = pools.listIterator(); 53 boolean found = false; 54 while (iter.hasNext()) { 55 MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next(); 56 // only check heap pools that support usage threshold 57 // this is typically only the old generation space 58 // since the other spaces are expected to get filled up 59 if (p.getType() == MemoryType.HEAP && 60 p.isUsageThresholdSupported()) 61 { 62 found = true; 63 testPool(p); 64 } 65 } 66 if (!found) { 67 throw new RuntimeException("No heap pool found"); 68 } 69 } 70 71 private static void testPool(MemoryPoolMXBean mpool) { 72 System.out.println("Selected memory pool: "); 73 MemoryUtil.printMemoryPool(mpool); 74 75 MemoryUsage usage0 = mpool.getUsage(); 76 MemoryUsage peak0 = mpool.getPeakUsage(); 77 78 // use a size that is larger than the young generation and G1 regions 79 // to force the array into the old gen 80 int largeArraySize = 9 * 1000 * 1000; 81 82 System.out.println("Before big object array (of size "+largeArraySize+") is allocated: "); 83 printMemoryUsage(usage0, peak0); 84 85 obj = new Object[largeArraySize]; 86 87 MemoryUsage usage1 = mpool.getUsage(); 88 MemoryUsage peak1 = mpool.getPeakUsage(); 89 System.out.println("After the object is allocated: "); 90 printMemoryUsage(usage1, peak1); 91 92 if (usage1.getUsed() <= usage0.getUsed()) { 93 throw new RuntimeException( 94 formatSize("Before allocation: used", usage0.getUsed()) + 95 " expected to be < " + 96 formatSize("After allocation: used", usage1.getUsed())); 97 } 98 99 if (peak1.getUsed() <= peak0.getUsed()) { 100 throw new RuntimeException( 101 formatSize("Before allocation: peak", peak0.getUsed()) + 102 " expected to be < " + 103 formatSize("After allocation: peak", peak1.getUsed())); 104 } 105 106 107 // The object is now garbage and do a GC 108 // memory usage should drop 109 obj = null; 110 mbean.gc(); 111 112 MemoryUsage usage2 = mpool.getUsage(); 113 MemoryUsage peak2 = mpool.getPeakUsage(); 114 System.out.println("After GC: "); 115 printMemoryUsage(usage2, peak2); 116 117 if (usage2.getUsed() >= usage1.getUsed()) { 118 throw new RuntimeException( 119 formatSize("Before GC: used", usage1.getUsed()) + " " + 120 " expected to be > " + 121 formatSize("After GC: used", usage2.getUsed())); 122 } 123 124 mpool.resetPeakUsage(); 125 126 MemoryUsage usage3 = mpool.getUsage(); 127 MemoryUsage peak3 = mpool.getPeakUsage(); 128 System.out.println("After resetPeakUsage: "); 129 printMemoryUsage(usage3, peak3); 130 131 if (peak3.getUsed() != usage3.getUsed()) { 132 throw new RuntimeException( 133 formatSize("After resetting peak: peak", peak3.getUsed()) + " " + 134 " expected to be equal to " + 135 formatSize("current used", usage3.getUsed())); 136 } 137 138 if (peak3.getUsed() >= peak2.getUsed()) { 139 throw new RuntimeException( 140 formatSize("After resetting peak: peak", peak3.getUsed()) + " " + 141 " expected to be < " + 142 formatSize("previous peak", peak2.getUsed())); 143 } 144 145 System.out.println("Test passed."); 146 } 147 148 private static String INDENT = " "; 149 private static void printMemoryUsage(MemoryUsage current, MemoryUsage peak) { 150 System.out.println("Current Usage: "); 151 MemoryUtil.printMemoryUsage(current); 152 System.out.println("Peak Usage: "); 153 MemoryUtil.printMemoryUsage(peak); 154 155 } 156 private static String formatSize(String name, long value) { 157 StringBuffer buf = new StringBuffer(name + " = " + value); 158 if (value > 0) { 159 buf.append(" (" + (value >> 10) + "K)"); 160 } 161 return buf.toString(); 162 } 163 }