test/gc/g1/TestHumongousShrinkHeap.java

Wed, 03 Sep 2014 09:25:44 +0200

author
tschatzl
date
Wed, 03 Sep 2014 09:25:44 +0200
changeset 7097
14b8221771dc
parent 7096
b1266b08b994
child 7175
9b8bd21b6823
permissions
-rw-r--r--

Merge

jwilhelm@7095 1 /*
jwilhelm@7095 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
jwilhelm@7095 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jwilhelm@7095 4 *
jwilhelm@7095 5 * This code is free software; you can redistribute it and/or modify it
jwilhelm@7095 6 * under the terms of the GNU General Public License version 2 only, as
jwilhelm@7095 7 * published by the Free Software Foundation.
jwilhelm@7095 8 *
jwilhelm@7095 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jwilhelm@7095 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jwilhelm@7095 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jwilhelm@7095 12 * version 2 for more details (a copy is included in the LICENSE file that
jwilhelm@7095 13 * accompanied this code).
jwilhelm@7095 14 *
jwilhelm@7095 15 * You should have received a copy of the GNU General Public License version
jwilhelm@7095 16 * 2 along with this work; if not, write to the Free Software Foundation,
jwilhelm@7095 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jwilhelm@7095 18 *
jwilhelm@7095 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jwilhelm@7095 20 * or visit www.oracle.com if you need additional information or have any
jwilhelm@7095 21 * questions.
jwilhelm@7095 22 */
jwilhelm@7095 23
jwilhelm@7095 24 /**
jwilhelm@7095 25 * @test TestHumongousShrinkHeap
tschatzl@7096 26 * @bug 8036025 8056043
jwilhelm@7095 27 * @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects
jwilhelm@7095 28 * @library /testlibrary
jwilhelm@7095 29 * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc TestHumongousShrinkHeap
jwilhelm@7095 30 */
jwilhelm@7095 31
jwilhelm@7095 32 import java.lang.management.ManagementFactory;
jwilhelm@7095 33 import java.lang.management.MemoryUsage;
jwilhelm@7095 34 import java.util.ArrayList;
jwilhelm@7095 35 import java.util.List;
jwilhelm@7095 36 import sun.management.ManagementFactoryHelper;
jwilhelm@7095 37 import static com.oracle.java.testlibrary.Asserts.*;
jwilhelm@7095 38
jwilhelm@7095 39 public class TestHumongousShrinkHeap {
jwilhelm@7095 40
jwilhelm@7095 41 public static final String MIN_FREE_RATIO_FLAG_NAME = "MinHeapFreeRatio";
jwilhelm@7095 42 public static final String MAX_FREE_RATIO_FLAG_NAME = "MaxHeapFreeRatio";
jwilhelm@7095 43
jwilhelm@7095 44 private static final ArrayList<ArrayList<byte[]>> garbage = new ArrayList<>();
jwilhelm@7095 45 private static final int PAGE_SIZE = 1024 * 1024; // 1M
jwilhelm@7095 46 private static final int PAGES_NUM = 5;
jwilhelm@7095 47
jwilhelm@7095 48
jwilhelm@7095 49 public static void main(String[] args) {
jwilhelm@7095 50 new TestHumongousShrinkHeap().test();
jwilhelm@7095 51 }
jwilhelm@7095 52
jwilhelm@7095 53 private final void test() {
jwilhelm@7095 54 System.gc();
jwilhelm@7095 55 MemoryUsagePrinter.printMemoryUsage("init");
jwilhelm@7095 56
jwilhelm@7095 57 eat();
jwilhelm@7095 58 MemoryUsagePrinter.printMemoryUsage("eaten");
jwilhelm@7095 59 MemoryUsage muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
jwilhelm@7095 60
jwilhelm@7095 61 free();
jwilhelm@7095 62 MemoryUsagePrinter.printMemoryUsage("free");
jwilhelm@7095 63 MemoryUsage muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
jwilhelm@7095 64
jwilhelm@7095 65 assertLessThan(muFree.getCommitted(), muFull.getCommitted(), String.format(
jwilhelm@7095 66 "committed free heap size is not less than committed full heap size, heap hasn't been shrunk?%n"
jwilhelm@7095 67 + "%s = %s%n%s = %s",
jwilhelm@7095 68 MIN_FREE_RATIO_FLAG_NAME,
jwilhelm@7095 69 ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MIN_FREE_RATIO_FLAG_NAME).getValue(),
jwilhelm@7095 70 MAX_FREE_RATIO_FLAG_NAME,
jwilhelm@7095 71 ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MAX_FREE_RATIO_FLAG_NAME).getValue()
jwilhelm@7095 72 ));
jwilhelm@7095 73 }
jwilhelm@7095 74
jwilhelm@7095 75 private void eat() {
jwilhelm@7095 76 int HumongousObjectSize = Math.round(.9f * PAGE_SIZE);
jwilhelm@7095 77 System.out.println("Will allocate objects of size=" +
jwilhelm@7095 78 MemoryUsagePrinter.humanReadableByteCount(HumongousObjectSize, true));
jwilhelm@7095 79
jwilhelm@7095 80 for (int i = 0; i < PAGES_NUM; i++) {
jwilhelm@7095 81 ArrayList<byte[]> stuff = new ArrayList<>();
jwilhelm@7095 82 eatList(stuff, 100, HumongousObjectSize);
jwilhelm@7095 83 MemoryUsagePrinter.printMemoryUsage("eat #" + i);
jwilhelm@7095 84 garbage.add(stuff);
jwilhelm@7095 85 }
jwilhelm@7095 86 }
jwilhelm@7095 87
jwilhelm@7095 88 private void free() {
jwilhelm@7095 89 // do not free last one list
jwilhelm@7095 90 garbage.subList(0, garbage.size() - 1).clear();
jwilhelm@7095 91
jwilhelm@7095 92 // do not free last one element from last list
jwilhelm@7095 93 ArrayList stuff = garbage.get(garbage.size() - 1);
jwilhelm@7095 94 stuff.subList(0, stuff.size() - 1).clear();
jwilhelm@7095 95 System.gc();
jwilhelm@7095 96 }
jwilhelm@7095 97
jwilhelm@7095 98 private static void eatList(List garbage, int count, int size) {
jwilhelm@7095 99 for (int i = 0; i < count; i++) {
jwilhelm@7095 100 garbage.add(new byte[size]);
jwilhelm@7095 101 }
jwilhelm@7095 102 }
jwilhelm@7095 103 }
jwilhelm@7095 104
jwilhelm@7095 105 /**
jwilhelm@7095 106 * Prints memory usage to standard output
jwilhelm@7095 107 */
jwilhelm@7095 108 class MemoryUsagePrinter {
jwilhelm@7095 109
jwilhelm@7095 110 public static String humanReadableByteCount(long bytes, boolean si) {
jwilhelm@7095 111 int unit = si ? 1000 : 1024;
jwilhelm@7095 112 if (bytes < unit) {
jwilhelm@7095 113 return bytes + " B";
jwilhelm@7095 114 }
jwilhelm@7095 115 int exp = (int) (Math.log(bytes) / Math.log(unit));
jwilhelm@7095 116 String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
jwilhelm@7095 117 return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
jwilhelm@7095 118 }
jwilhelm@7095 119
jwilhelm@7095 120 public static void printMemoryUsage(String label) {
jwilhelm@7095 121 MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
jwilhelm@7095 122 float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
jwilhelm@7095 123 System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n",
jwilhelm@7095 124 label,
jwilhelm@7095 125 humanReadableByteCount(memusage.getInit(), true),
jwilhelm@7095 126 humanReadableByteCount(memusage.getUsed(), true),
jwilhelm@7095 127 humanReadableByteCount(memusage.getCommitted(), true),
jwilhelm@7095 128 freeratio * 100
jwilhelm@7095 129 );
jwilhelm@7095 130 }
jwilhelm@7095 131 }

mercurial