1 /*
  2  * Copyright (c) 2010, 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.cms;
 25 
 26 /*
 27  * @test TestMBeanCMS.java
 28  * @bug 6581734
 29  * @requires vm.gc.ConcMarkSweep & !vm.graal.enabled
 30  * @summary CMS Old Gen's collection usage is zero after GC which is incorrect
 31  * @modules java.management
 32  * @run main/othervm -Xmx512m -verbose:gc -XX:+UseConcMarkSweepGC gc.cms.TestMBeanCMS
 33  *
 34  */
 35 
 36 import java.lang.management.GarbageCollectorMXBean;
 37 import java.lang.management.ManagementFactory;
 38 import java.lang.management.MemoryPoolMXBean;
 39 import java.util.LinkedList;
 40 import java.util.List;
 41 
 42 // 6581734 states that memory pool usage via the mbean is wrong
 43 // for CMS (zero, even after a collection).
 44 //
 45 // 6580448 states that the collection count similarly is wrong
 46 // (stays at zero for CMS collections)
 47 // -- closed as dup of 6581734 as the same fix resolves both.
 48 
 49 
 50 public class TestMBeanCMS {
 51 
 52     private String poolName = "CMS";
 53     private String collectorName = "ConcurrentMarkSweep";
 54 
 55     public static void main(String [] args) {
 56 
 57         TestMBeanCMS t = null;
 58         if (args.length==2) {
 59             t = new TestMBeanCMS(args[0], args[1]);
 60         } else {
 61             System.out.println("Defaulting to monitor CMS pool and collector.");
 62             t = new TestMBeanCMS();
 63         }
 64         t.run();
 65     }
 66 
 67     public TestMBeanCMS(String pool, String collector) {
 68         poolName = pool;
 69         collectorName = collector;
 70     }
 71 
 72     public TestMBeanCMS() {
 73     }
 74 
 75     public void run() {
 76         // Use some memory, enough that we expect collections should
 77         // have happened.
 78         // Must run with options to ensure no stop the world full GC,
 79         // but e.g. at least one CMS cycle.
 80         allocationWork(300*1024*1024);
 81         System.out.println("Done allocationWork");
 82 
 83         // Verify some non-zero results are stored.
 84         List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
 85         int poolsFound = 0;
 86         int poolsWithStats = 0;
 87         for (int i=0; i<pools.size(); i++) {
 88             MemoryPoolMXBean pool = pools.get(i);
 89             String name = pool.getName();
 90             System.out.println("found pool: " + name);
 91 
 92             if (name.contains(poolName)) {
 93                 long usage = pool.getCollectionUsage().getUsed();
 94                 System.out.println(name + ": usage after GC = " + usage);
 95                 poolsFound++;
 96                 if (usage > 0) {
 97                     poolsWithStats++;
 98                 }
 99             }
100         }
101         if (poolsFound == 0) {
102             throw new RuntimeException("No matching memory pools found: test with -XX:+UseConcMarkSweepGC");
103         }
104 
105         List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans();
106         int collectorsFound = 0;
107         int collectorsWithTime= 0;
108         for (int i=0; i<collectors.size(); i++) {
109             GarbageCollectorMXBean collector = collectors.get(i);
110             String name = collector.getName();
111             System.out.println("found collector: " + name);
112             if (name.contains(collectorName)) {
113                 collectorsFound++;
114                 System.out.println(name + ": collection count = "
115                                    + collector.getCollectionCount());
116                 System.out.println(name + ": collection time  = "
117                                    + collector.getCollectionTime());
118                 if (collector.getCollectionCount() <= 0) {
119                     throw new RuntimeException("collection count <= 0");
120                 }
121                 if (collector.getCollectionTime() > 0) {
122                     collectorsWithTime++;
123                 }
124             }
125         }
126         // verify:
127         if (poolsWithStats < poolsFound) {
128             throw new RuntimeException("pools found with zero stats");
129         }
130 
131         if (collectorsWithTime<collectorsFound) {
132             throw new RuntimeException("collectors found with zero time");
133         }
134         System.out.println("Test passed.");
135     }
136 
137     public void allocationWork(long target) {
138 
139         long sizeAllocated = 0;
140         List list = new LinkedList();
141         long delay = 50;
142         long count = 0;
143 
144         while (sizeAllocated < target) {
145             int size = 1024*1024;
146             byte [] alloc = new byte[size];
147             if (count % 2 == 0) {
148                 list.add(alloc);
149                 sizeAllocated+=size;
150                 System.out.print(".");
151             }
152             try { Thread.sleep(delay); } catch (InterruptedException ie) { }
153             count++;
154         }
155     }
156 
157 }