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 TestOldGenCollectionUsage.java 26 * @bug 8195115 27 * @summary G1 Old Gen's CollectionUsage.used is zero after mixed GC which is incorrect 28 * @key gc 29 * @requires vm.gc.G1 30 * @requires vm.opt.MaxGCPauseMillis == "null" 31 * @library /test/lib 32 * @modules java.base/jdk.internal.misc 33 * @modules java.management 34 * @build sun.hotspot.WhiteBox 35 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 36 * @run main/othervm -Xbootclasspath/a:. -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -verbose:gc -XX:SurvivorRatio=1 -Xmx14m -Xms14m -XX:MaxTenuringThreshold=1 -XX:InitiatingHeapOccupancyPercent=100 -XX:-G1UseAdaptiveIHOP -XX:G1MixedGCCountTarget=4 -XX:MaxGCPauseMillis=30000 -XX:G1HeapRegionSize=1m -XX:G1HeapWastePercent=0 -XX:G1MixedGCLiveThresholdPercent=100 TestOldGenCollectionUsage 37 */ 38 39 import jdk.test.lib.Asserts; 40 import sun.hotspot.WhiteBox; 41 42 import java.util.ArrayList; 43 import java.util.List; 44 import java.util.Collections; 45 46 import java.lang.management.*; 47 48 // 8195115 says that for the "G1 Old Gen" MemoryPool, CollectionUsage.used 49 // is zero for G1 after a mixed collection, which is incorrect. 50 51 public class TestOldGenCollectionUsage { 52 53 private String poolName = "G1 Old Gen"; 54 private String collectorName = "G1 Young Generation"; 55 56 public static void main(String [] args) throws Exception { 57 TestOldGenCollectionUsage t = new TestOldGenCollectionUsage(); 58 t.run(); 59 } 60 61 public TestOldGenCollectionUsage() { 62 System.out.println("Monitor G1 Old Gen pool with G1 Young Generation collector."); 63 } 64 65 public void run() { 66 // Find memory pool and collector 67 List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); 68 MemoryPoolMXBean pool = null; 69 boolean foundPool = false; 70 for (int i = 0; i < pools.size(); i++) { 71 pool = pools.get(i); 72 String name = pool.getName(); 73 if (name.contains(poolName)) { 74 System.out.println("Found pool: " + name); 75 foundPool = true; 76 break; 77 } 78 } 79 if (!foundPool) { 80 throw new RuntimeException(poolName + " not found, test with -XX:+UseG1GC"); 81 } 82 83 List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans(); 84 GarbageCollectorMXBean collector = null; 85 boolean foundCollector = false; 86 for (int i = 0; i < collectors.size(); i++) { 87 collector = collectors.get(i); 88 String name = collector.getName(); 89 if (name.contains(collectorName)) { 90 System.out.println("Found collector: " + name); 91 foundCollector = true; 92 break; 93 } 94 } 95 if (!foundCollector) { 96 throw new RuntimeException(collectorName + " not found, test with -XX:+UseG1GC"); 97 } 98 99 MixedGCProvoker gcProvoker = new MixedGCProvoker(); 100 gcProvoker.allocateOldObjects(); 101 102 // Verify no non-zero result was stored 103 long usage = pool.getCollectionUsage().getUsed(); 104 System.out.println(poolName + ": usage after GC = " + usage); 105 if (usage > 0) { 106 throw new RuntimeException("Premature mixed collections(s)"); 107 } 108 109 // Verify that collections were done 110 long collectionCount = collector.getCollectionCount(); 111 System.out.println(collectorName + ": collection count = " 112 + collectionCount); 113 long collectionTime = collector.getCollectionTime(); 114 System.out.println(collectorName + ": collection time = " 115 + collectionTime); 116 if (collectionCount <= 0) { 117 throw new RuntimeException("Collection count <= 0"); 118 } 119 if (collectionTime <= 0) { 120 throw new RuntimeException("Collector has not run"); 121 } 122 123 gcProvoker.provokeMixedGC(); 124 125 usage = pool.getCollectionUsage().getUsed(); 126 System.out.println(poolName + ": usage after GC = " + usage); 127 if (usage <= 0) { 128 throw new RuntimeException(poolName + " found with zero usage"); 129 } 130 131 long newCollectionCount = collector.getCollectionCount(); 132 System.out.println(collectorName + ": collection count = " 133 + newCollectionCount); 134 long newCollectionTime = collector.getCollectionTime(); 135 System.out.println(collectorName + ": collection time = " 136 + newCollectionTime); 137 if (newCollectionCount <= collectionCount) { 138 throw new RuntimeException("No new collection"); 139 } 140 if (newCollectionTime <= collectionTime) { 141 throw new RuntimeException("Collector has not run some more"); 142 } 143 144 System.out.println("Test passed."); 145 } 146 147 /** 148 * Utility class to guarantee a mixed GC. The class allocates several arrays and 149 * promotes them to the oldgen. After that it tries to provoke mixed GC by 150 * allocating new objects. 151 * 152 * The necessary condition for guaranteed mixed GC is running MixedGCProvoker is 153 * running in VM with the following flags: -XX:MaxTenuringThreshold=1 -Xms12M 154 * -Xmx12M -XX:G1MixedGCLiveThresholdPercent=100 -XX:G1HeapWastePercent=0 155 * -XX:G1HeapRegionSize=1m 156 */ 157 public class MixedGCProvoker { 158 private final WhiteBox WB = WhiteBox.getWhiteBox(); 159 private final List<byte[]> liveOldObjects = new ArrayList<>(); 160 private final List<byte[]> newObjects = new ArrayList<>(); 161 | 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 TestOldGenCollectionUsage.java 26 * @bug 8195115 27 * @summary G1 Old Gen's CollectionUsage.used is zero after mixed GC which is incorrect 28 * @key gc 29 * @requires vm.gc.G1 30 * @requires vm.opt.MaxGCPauseMillis == "null" 31 * @library /test/lib 32 * @modules java.base/jdk.internal.misc 33 * @modules java.management 34 * @build sun.hotspot.WhiteBox 35 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 36 * @run main/othervm -Xbootclasspath/a:. -XX:+UseG1GC -XX:-G1UseLegacyMonitoring -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -verbose:gc -XX:SurvivorRatio=1 -Xmx12m -Xms12m -XX:MaxTenuringThreshold=1 -XX:InitiatingHeapOccupancyPercent=100 -XX:-G1UseAdaptiveIHOP -XX:G1MixedGCCountTarget=4 -XX:MaxGCPauseMillis=30000 -XX:G1HeapRegionSize=1m -XX:G1HeapWastePercent=0 -XX:G1MixedGCLiveThresholdPercent=100 TestOldGenCollectionUsage 37 * @run main/othervm -Xbootclasspath/a:. -XX:+UseG1GC -XX:+G1UseLegacyMonitoring -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -verbose:gc -XX:SurvivorRatio=1 -Xmx12m -Xms12m -XX:MaxTenuringThreshold=1 -XX:InitiatingHeapOccupancyPercent=100 -XX:-G1UseAdaptiveIHOP -XX:G1MixedGCCountTarget=4 -XX:MaxGCPauseMillis=30000 -XX:G1HeapRegionSize=1m -XX:G1HeapWastePercent=0 -XX:G1MixedGCLiveThresholdPercent=100 TestOldGenCollectionUsage 38 */ 39 40 import jdk.test.lib.Asserts; 41 import sun.hotspot.WhiteBox; 42 43 import java.util.ArrayList; 44 import java.util.List; 45 import java.util.Collections; 46 47 import java.lang.management.*; 48 49 // 8195115 says that for the "G1 Old Gen" MemoryPool, CollectionUsage.used 50 // is zero for G1 after a mixed collection, which is incorrect. 51 52 public class TestOldGenCollectionUsage { 53 54 private String poolName; 55 private String youngCollectorName; 56 private String mixedCollectorName; 57 private boolean useLegacyMonitoring; 58 59 public static void main(String [] args) throws Exception { 60 TestOldGenCollectionUsage t = new TestOldGenCollectionUsage(); 61 t.run(); 62 } 63 64 public TestOldGenCollectionUsage() { 65 useLegacyMonitoring = LegacyMonitoring.use(); 66 poolName = useLegacyMonitoring ? "G1 Old Gen" : "G1 Old Space"; 67 youngCollectorName = useLegacyMonitoring ? "G1 Young Generation" : "G1 Young"; 68 mixedCollectorName = useLegacyMonitoring ? "G1 Young Generation" : "G1 Mixed"; 69 System.out.println("Monitor G1 Old Gen pool with " + mixedCollectorName + " collector."); 70 } 71 72 public static class LegacyMonitoring { 73 private static final boolean useLegacyMonitoring = getUseLegacyMonitoring(); 74 private static boolean getUseLegacyMonitoring() { 75 return ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-XX:+G1UseLegacyMonitoring"); 76 } 77 public static boolean use() { return useLegacyMonitoring; } 78 } 79 80 public void run() { 81 // Find old space memory pool and collectors 82 List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); 83 MemoryPoolMXBean pool = null; 84 boolean foundPool = false; 85 for (int i = 0; i < pools.size(); i++) { 86 pool = pools.get(i); 87 String name = pool.getName(); 88 if (name.contains(poolName)) { 89 System.out.println("Found pool: " + name); 90 foundPool = true; 91 break; 92 } 93 } 94 if (!foundPool) { 95 throw new RuntimeException(poolName + " not found, test with -XX:+UseG1GC"); 96 } 97 98 List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans(); 99 GarbageCollectorMXBean youngCollector = null; 100 GarbageCollectorMXBean mixedCollector = null; 101 for (int i = 0; i < collectors.size(); i++) { 102 GarbageCollectorMXBean collector = collectors.get(i); 103 String name = collector.getName(); 104 if (name.equals(youngCollectorName)) { 105 System.out.println("Found young collector: " + name); 106 youngCollector = collector; 107 } 108 if (name.equals(mixedCollectorName)) { 109 System.out.println("Found mixed collector: " + name); 110 mixedCollector = collector; 111 } 112 } 113 if (youngCollector == null) { 114 throw new RuntimeException(youngCollectorName + " not found, test with -XX:+UseG1GC"); 115 } 116 if (mixedCollector == null) { 117 throw new RuntimeException(mixedCollectorName + " not found, test with -XX:+UseG1GC"); 118 } 119 120 MixedGCProvoker gcProvoker = new MixedGCProvoker(); 121 gcProvoker.allocateOldObjects(); 122 123 // Verify no non-zero result was stored for the pool 124 long usage = pool.getCollectionUsage().getUsed(); 125 System.out.println(poolName + ": usage after GC = " + usage); 126 if (usage > 0) { 127 throw new RuntimeException("Premature mixed collections(s)"); 128 } 129 130 // Verify that young collections were done 131 long youngCollectionCount = youngCollector.getCollectionCount(); 132 System.out.println(youngCollectorName + ": collection count = " 133 + youngCollectionCount); 134 long youngCollectionTime = youngCollector.getCollectionTime(); 135 System.out.println(youngCollectorName + ": collection time = " 136 + youngCollectionTime); 137 if (youngCollectionCount <= 0) { 138 throw new RuntimeException("Young collection count <= 0"); 139 } 140 if (youngCollectionTime <= 0) { 141 throw new RuntimeException("Young collector did not run"); 142 } 143 144 // Force promotion 145 gcProvoker.provokeMixedGC(); 146 147 usage = pool.getCollectionUsage().getUsed(); 148 System.out.println(poolName + ": usage after GC = " + usage); 149 if (usage <= 0) { 150 throw new RuntimeException(poolName + " found with zero usage"); 151 } 152 153 long newCollectionCount = mixedCollector.getCollectionCount(); 154 System.out.println(mixedCollectorName + ": collection count = " 155 + newCollectionCount); 156 long newCollectionTime = mixedCollector.getCollectionTime(); 157 System.out.println(mixedCollectorName + ": collection time = " 158 + newCollectionTime); 159 if (useLegacyMonitoring) { 160 if (newCollectionCount <= youngCollectionCount) { 161 throw new RuntimeException("No new collection"); 162 } 163 } else { 164 if (newCollectionCount <= 0) { 165 throw new RuntimeException("Mixed collection count <= 0"); 166 } 167 if (newCollectionTime <= 0) { 168 throw new RuntimeException("Mixed collector did not run"); 169 } 170 } 171 172 System.out.println("Test passed."); 173 } 174 175 /** 176 * Utility class to guarantee a mixed GC. The class allocates several arrays and 177 * promotes them to the oldgen. After that it tries to provoke mixed GC by 178 * allocating new objects. 179 * 180 * The necessary condition for guaranteed mixed GC is running MixedGCProvoker is 181 * running in VM with the following flags: -XX:MaxTenuringThreshold=1 -Xms12M 182 * -Xmx12M -XX:G1MixedGCLiveThresholdPercent=100 -XX:G1HeapWastePercent=0 183 * -XX:G1HeapRegionSize=1m 184 */ 185 public class MixedGCProvoker { 186 private final WhiteBox WB = WhiteBox.getWhiteBox(); 187 private final List<byte[]> liveOldObjects = new ArrayList<>(); 188 private final List<byte[]> newObjects = new ArrayList<>(); 189 |