1 /* 2 * Copyright (c) 2018, 2019, 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 package gc.g1; 25 26 /** 27 * @test TestPeriodicCollection 28 * @requires vm.gc.G1 29 * @requires vm.compMode != "Xcomp" 30 * @summary Verify that heap shrinks when the application is idle. 31 * @library /test/lib / 32 * @modules java.base/jdk.internal.misc 33 * @modules java.management/sun.management 34 * @run main/othervm -XX:MaxNewSize=32M -XX:InitialHeapSize=48M -Xmx128M -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=25 -XX:+UseG1GC -XX:G1PeriodicGCInterval=3000 -XX:+G1PeriodicGCInvokesConcurrent -Xlog:gc,gc+periodic=debug,gc+ergo+heap=debug gc.g1.TestPeriodicCollection 35 * @run main/othervm -XX:MaxNewSize=32M -XX:InitialHeapSize=48M -Xmx128M -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=25 -XX:+UseG1GC -XX:G1PeriodicGCInterval=3000 -XX:-G1PeriodicGCInvokesConcurrent -Xlog:gc,gc+periodic=debug,gc+ergo+heap=debug gc.g1.TestPeriodicCollection 36 */ 37 38 import com.sun.management.HotSpotDiagnosticMXBean; 39 40 import gc.testlibrary.Helpers; 41 42 import java.lang.management.GarbageCollectorMXBean; 43 import java.lang.management.ManagementFactory; 44 import java.lang.management.MemoryUsage; 45 import java.text.NumberFormat; 46 import static jdk.test.lib.Asserts.*; 47 48 public class TestPeriodicCollection { 49 50 public static final String MIN_FREE_RATIO_FLAG_NAME = "MinHeapFreeRatio"; 51 public static final String MAX_FREE_RATIO_FLAG_NAME = "MaxHeapFreeRatio"; 52 53 private static final int IDLE_TIME = 7 * 1000; 54 gcOccurred()55 private static boolean gcOccurred() { 56 for (GarbageCollectorMXBean b : ManagementFactory.getGarbageCollectorMXBeans()) { 57 if (b.getCollectionCount() != 0) { 58 return true; 59 } 60 } 61 return false; 62 } 63 main(String[] args)64 public static void main(String[] args) { 65 MemoryUsage muInitial = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); 66 printMemoryUsage("initial", muInitial); 67 68 if (gcOccurred()) { 69 System.out.println("At least one garbage collection occurred. Exiting as this may have already shrunk the heap."); 70 return; 71 } 72 73 try { 74 Thread.sleep(IDLE_TIME); 75 } catch (InterruptedException ie) { 76 System.err.println("Skipped. Failed to wait for idle collection"); 77 } 78 79 MemoryUsage muAfter = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); 80 printMemoryUsage("after", muAfter); 81 82 assertLessThan(muAfter.getCommitted(), muInitial.getCommitted(), String.format( 83 "committed free heap size is not less than committed full heap size, heap hasn't been shrunk?%n" 84 + "%s = %s%n%s = %s", 85 MIN_FREE_RATIO_FLAG_NAME, 86 ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class) 87 .getVMOption(MIN_FREE_RATIO_FLAG_NAME).getValue(), 88 MAX_FREE_RATIO_FLAG_NAME, 89 ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class) 90 .getVMOption(MAX_FREE_RATIO_FLAG_NAME).getValue() 91 )); 92 } 93 94 public static final NumberFormat NF = Helpers.numberFormatter(); 95 printMemoryUsage(String label, MemoryUsage memusage)96 public static void printMemoryUsage(String label, MemoryUsage memusage) { 97 float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted(); 98 System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n", 99 label, 100 NF.format(memusage.getInit()), 101 NF.format(memusage.getUsed()), 102 NF.format(memusage.getCommitted()), 103 freeratio * 100 104 ); 105 } 106 } 107