1 /*
  2  * Copyright (c) 2003, 2023, 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  * @test
 26  * @bug     4530538
 27  * @summary Basic unit test of MemoryMXBean.getMemoryPools() and
 28  *          MemoryMXBean.getMemoryManager().
 29  * @requires vm.gc != "Z" & vm.gc != "Shenandoah" & !vm.gc.G1
 30  * @author  Mandy Chung
 31  *
 32  * @modules jdk.management
 33  * @run main MemoryTest 2 3
 34  */
 35 
 36 /*
 37  * @test id=ZSinglegen
 38  * @bug     4530538
 39  * @summary Basic unit test of MemoryMXBean.getMemoryPools() and
 40  *          MemoryMXBean.getMemoryManager().
 41  * @requires vm.gc.ZSinglegen
 42  * @author  Mandy Chung
 43  *
 44  * @modules jdk.management
 45  * @run main/othervm -XX:+UseZGC -XX:-ZGenerational MemoryTest 2 1
 46  */
 47 
 48 /*
 49  * @test id=ZGenerational
 50  * @bug     4530538
 51  * @summary Basic unit test of MemoryMXBean.getMemoryPools() and
 52  *          MemoryMXBean.getMemoryManager().
 53  * @requires vm.gc.ZGenerational
 54  * @author  Mandy Chung
 55  *
 56  * @modules jdk.management
 57  * @run main/othervm -XX:+UseZGC -XX:+ZGenerational MemoryTest 4 2
 58  */
 59 
 60 /*
 61  * @test
 62  * @bug     4530538
 63  * @summary Basic unit test of MemoryMXBean.getMemoryPools() and
 64  *          MemoryMXBean.getMemoryManager().
 65  * @requires vm.gc == "Shenandoah"
 66  * @author  Mandy Chung
 67  *
 68  * @modules jdk.management
 69  * @run main MemoryTest 2 1
 70  */
 71 
 72 /*
 73  * @test
 74  * @bug     4530538
 75  * @summary Basic unit test of MemoryMXBean.getMemoryPools() and
 76  *          MemoryMXBean.getMemoryManager().
 77  * @requires vm.gc.G1
 78  * @author  Mandy Chung
 79  *
 80  * @modules jdk.management
 81  * @run main/othervm -XX:+UseG1GC MemoryTest 3 3
 82  */
 83 
 84 /*
 85  * NOTE: This expected result is hardcoded in this test and this test
 86  *       will be affected if the heap memory layout is changed in
 87  *       the future implementation.
 88  */
 89 
 90 import java.lang.management.*;
 91 import java.util.*;
 92 
 93 public class MemoryTest {
 94     private static boolean testFailed = false;
 95     private static MemoryMXBean mm = ManagementFactory.getMemoryMXBean();
 96     private static final int HEAP = 0;
 97     private static final int NONHEAP = 1;
 98     private static final int NUM_TYPES = 2;
 99 
100     // WARNING: if the number of pools changes in the future,
101     // this test needs to be modified to handle different version of VMs.
102 
103     // Hotspot VM 1.5 expected to have
104     //   heap memory pools     = 3 (Eden, Survivor spaces, Old gen)
105     //   non-heap memory pools = 2 (Perm gen, Code cache)
106     //                           or 4 if Class Sharing is enabled.
107     // Number of memory managers = 3
108     // They are: Copy/Scavenger + MSC + CodeCache manager
109     // (or equivalent for other collectors)
110     // Number of GC memory managers = 2
111 
112     // Hotspot VM 1.8+ after perm gen removal is expected to have between two
113     // or five non-heap memory pools:
114     // - Code cache (between one and three depending on the -XX:SegmentedCodeCache option)
115     // - Metaspace
116     // - Compressed Class Space (if compressed class pointers are used)
117 
118     private static int[] expectedMinNumPools = new int[2];
119     private static int[] expectedMaxNumPools = new int[2];
120     private static int expectedNumGCMgrs;
121     private static int expectedNumMgrs;
122     private static String[] types = { "heap", "non-heap" };
123 
124     public static void main(String args[]) throws Exception {
125         expectedNumGCMgrs = Integer.valueOf(args[0]);
126         expectedNumMgrs = expectedNumGCMgrs + 2;
127 
128         int expectedNumPools = Integer.valueOf(args[1]);
129         expectedMinNumPools[HEAP] = expectedNumPools;
130         expectedMaxNumPools[HEAP] = expectedNumPools;
131 
132         expectedMinNumPools[NONHEAP] = 2;
133         expectedMaxNumPools[NONHEAP] = 5;
134 
135         checkMemoryPools();
136         checkMemoryManagers();
137         if (testFailed)
138             throw new RuntimeException("TEST FAILED.");
139 
140         System.out.println("Test passed.");
141 
142     }
143 
144     private static void checkMemoryPools() throws Exception {
145         List pools = ManagementFactory.getMemoryPoolMXBeans();
146         boolean hasPerm = false;
147 
148         int[] numPools = new int[NUM_TYPES];
149         for (ListIterator iter = pools.listIterator(); iter.hasNext();) {
150             MemoryPoolMXBean pool = (MemoryPoolMXBean) iter.next();
151             if (pool.getType() == MemoryType.HEAP) {
152                 numPools[HEAP]++;
153             }
154             if (pool.getType() == MemoryType.NON_HEAP) {
155                 numPools[NONHEAP]++;
156             }
157             if (pool.getName().toLowerCase().contains("perm")) {
158                 hasPerm = true;
159             }
160         }
161 
162         if (hasPerm) {
163             // If the VM has perm gen there will be between 2 and 4 non heap
164             // pools (4 if class data sharing is used)
165             expectedMinNumPools[NONHEAP] = 2;
166             expectedMaxNumPools[NONHEAP] = 4;
167         }
168 
169         // Check the number of Memory pools
170         for (int i = 0; i < NUM_TYPES; i++) {
171             if (numPools[i] < expectedMinNumPools[i] ||
172                     numPools[i] > expectedMaxNumPools[i]) {
173                 throw new RuntimeException("TEST FAILED: " +
174                     "Number of " + types[i] + " pools = " + numPools[i] +
175                     " but expected <= " + expectedMaxNumPools[i] +
176                     " and >= " + expectedMinNumPools[i]);
177             }
178         }
179     }
180 
181     private static void checkMemoryManagers() throws Exception {
182         List mgrs = ManagementFactory.getMemoryManagerMXBeans();
183 
184         int numGCMgr = 0;
185 
186         // Check the number of Memory Managers
187         for (ListIterator iter = mgrs.listIterator(); iter.hasNext();) {
188             MemoryManagerMXBean mgr = (MemoryManagerMXBean) iter.next();
189             String[] poolNames = mgr.getMemoryPoolNames();
190             if (poolNames == null || poolNames.length == 0) {
191                 throw new RuntimeException("TEST FAILED: " +
192                     "Expected to have one or more pools for " +
193                     mgr.getName() + "manager.");
194             }
195 
196             if (mgr instanceof GarbageCollectorMXBean) {
197                 numGCMgr++;
198             } else {
199                 for (int i = 0; i < poolNames.length; i++) {
200                     checkPoolType(poolNames[i], MemoryType.NON_HEAP);
201                 }
202             }
203         }
204 
205         if (mgrs.size() != expectedNumMgrs) {
206             throw new RuntimeException("TEST FAILED: " +
207                 "Number of memory managers = " + mgrs.size() +
208                 " but expected = " + expectedNumMgrs);
209         }
210         if (numGCMgr != expectedNumGCMgrs) {
211             throw new RuntimeException("TEST FAILED: " +
212                 "Number of GC managers = " + numGCMgr + " but expected = " +
213                 expectedNumGCMgrs);
214         }
215     }
216     private static List pools = ManagementFactory.getMemoryPoolMXBeans();
217     private static void checkPoolType(String name, MemoryType type)
218         throws Exception {
219         for (ListIterator iter = pools.listIterator(); iter.hasNext(); ) {
220             MemoryPoolMXBean pool = (MemoryPoolMXBean) iter.next();
221             if (pool.getName().equals(name)) {
222                 if (pool.getType() != type) {
223                     throw new RuntimeException("TEST FAILED: " +
224                         "Pool " + pool.getName() + " is of type " +
225                         pool.getType() + " but expected to be " + type);
226                 } else {
227                     return;
228                 }
229             }
230         }
231         throw new RuntimeException("TEST FAILED: " +
232             "Pool " + name + " is of type " + type +
233             " not found");
234     }
235 }