File: ResetPeakMemoryUsage.java

package info (click to toggle)
openjdk-11 11.0.4%2B11-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 757,028 kB
  • sloc: java: 5,016,041; xml: 1,191,974; cpp: 934,731; ansic: 555,697; sh: 24,299; objc: 12,703; python: 3,602; asm: 3,415; makefile: 2,772; awk: 351; sed: 172; perl: 114; jsp: 24; csh: 3
file content (195 lines) | stat: -rw-r--r-- 7,513 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * The -XX:MarkSweepAlwaysCompactCount=1 argument below makes sure serial gc
 * compacts the heap at every full gc so that the usage is correctly updated.
 */

/*
 * @test
 * @bug     4892507
 * @summary Basic Test for MemoryPool.resetPeakUsage()
 * @author  Mandy Chung
 *
 * @requires vm.opt.ExplicitGCInvokesConcurrent != "true"
 * @requires vm.opt.DisableExplicitGC != "true"
 * @library /lib/testlibrary/ /test/lib
 * @modules jdk.management
 *
 * @build jdk.testlibrary.* ResetPeakMemoryUsage MemoryUtil RunUtil
 * @build sun.hotspot.WhiteBox
 * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
 * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. ResetPeakMemoryUsage
 */

import java.lang.management.*;
import java.lang.ref.WeakReference;
import java.util.*;

import sun.hotspot.code.Compiler;

public class ResetPeakMemoryUsage {
    private static MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
    // make public so that it can't be optimized away easily
    public static Object[] obj;

    /**
     * Run the test multiple times with different GC versions.
     * First with default command line specified by the framework.
     * Then with all GC versions specified by the test.
     */
    public static void main(String a[]) throws Throwable {
        final String main = "ResetPeakMemoryUsage$TestMain";
        final String ms = "-Xms256m";
        final String mn = "-Xmn8m";
        if (!Compiler.isGraalEnabled()) { // Graal does not support CMS
            RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseConcMarkSweepGC");
        }
        RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseParallelGC");
        RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseG1GC", "-XX:G1HeapRegionSize=1m");
        RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseSerialGC",
                "-XX:MarkSweepAlwaysCompactCount=1");
    }

    private static class TestMain {
        public static void main(String[] argv) {
            List pools = ManagementFactory.getMemoryPoolMXBeans();
            ListIterator iter = pools.listIterator();
            boolean found = false;
            while (iter.hasNext()) {
                MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
                // only check heap pools that support usage threshold
                // this is typically only the old generation space
                // since the other spaces are expected to get filled up
                if (p.getType() == MemoryType.HEAP &&
                    p.isUsageThresholdSupported())
                {
                    found = true;
                    testPool(p);
                }
            }
            if (!found) {
                throw new RuntimeException("No heap pool found");
            }
        }
    }

    private static void testPool(MemoryPoolMXBean mpool) {
        System.out.println("Selected memory pool: ");
        MemoryUtil.printMemoryPool(mpool);

        MemoryUsage usage0 = mpool.getUsage();
        MemoryUsage peak0 = mpool.getPeakUsage();

        // use a size that is larger than the young generation and G1 regions
        // to force the array into the old gen
        int largeArraySize = 9 * 1000 * 1000;

        System.out.println("Before big object array (of size "+largeArraySize+") is allocated: ");
        printMemoryUsage(usage0, peak0);

        obj = new Object[largeArraySize];
        WeakReference<Object> weakRef = new WeakReference<>(obj);

        MemoryUsage usage1 = mpool.getUsage();
        MemoryUsage peak1 = mpool.getPeakUsage();
        System.out.println("After the object is allocated: ");
        printMemoryUsage(usage1, peak1);

        if (usage1.getUsed() <= usage0.getUsed()) {
            throw new RuntimeException(
                formatSize("Before allocation: used", usage0.getUsed()) +
                " expected to be < " +
                formatSize("After allocation: used", usage1.getUsed()));
        }

        if (peak1.getUsed() <= peak0.getUsed()) {
            throw new RuntimeException(
                formatSize("Before allocation: peak", peak0.getUsed()) +
                " expected to be < " +
                formatSize("After allocation: peak", peak1.getUsed()));
        }


        // The object is now garbage and do a GC
        // memory usage should drop
        obj = null;

        //This will cause sure shot GC unlike Runtime.gc() invoked by mbean.gc()
        while(weakRef.get() != null) {
            mbean.gc();
        }

        MemoryUsage usage2 = mpool.getUsage();
        MemoryUsage peak2 = mpool.getPeakUsage();
        System.out.println("After GC: ");
        printMemoryUsage(usage2, peak2);

        if (usage2.getUsed() >= usage1.getUsed()) {
            throw new RuntimeException(
                formatSize("Before GC: used", usage1.getUsed()) + " " +
                " expected to be > " +
                formatSize("After GC: used", usage2.getUsed()));
        }

        mpool.resetPeakUsage();

        MemoryUsage usage3 = mpool.getUsage();
        MemoryUsage peak3 = mpool.getPeakUsage();
        System.out.println("After resetPeakUsage: ");
        printMemoryUsage(usage3, peak3);

        if (peak3.getUsed() != usage3.getUsed()) {
            throw new RuntimeException(
                formatSize("After resetting peak: peak", peak3.getUsed()) + " " +
                " expected to be equal to " +
                formatSize("current used", usage3.getUsed()));
        }

        if (peak3.getUsed() >= peak2.getUsed()) {
            throw new RuntimeException(
                formatSize("After resetting peak: peak", peak3.getUsed()) + " " +
                " expected to be < " +
                formatSize("previous peak", peak2.getUsed()));
        }

        System.out.println(RunUtil.successMessage);
    }

    private static String INDENT = "    ";
    private static void printMemoryUsage(MemoryUsage current, MemoryUsage peak) {
        System.out.println("Current Usage: ");
        MemoryUtil.printMemoryUsage(current);
        System.out.println("Peak Usage: ");
        MemoryUtil.printMemoryUsage(peak);

    }
    private static String formatSize(String name, long value) {
        StringBuffer buf = new StringBuffer(name + " = " + value);
        if (value > 0) {
            buf.append(" (" + (value >> 10) + "K)");
        }
        return buf.toString();
    }
}