Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/com/sun/management/GarbageCollectorMXBean/GarbageCollectionNotificationContentTest.java
38855 views
/*1* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 703619926* @summary Check that GarbageCollectionNotification contents are reasonable27* @author Frederic Parain28* @run main/othervm GarbageCollectionNotificationContentTest29*/3031import java.util.*;32import java.lang.management.*;33import java.lang.reflect.*;34import javax.management.*;35import javax.management.openmbean.*;36import com.sun.management.GarbageCollectionNotificationInfo;37import com.sun.management.GcInfo;38import java.security.AccessController;39import java.security.PrivilegedAction;40import java.lang.reflect.Field;4142public class GarbageCollectionNotificationContentTest {43private static HashMap<String,GarbageCollectionNotificationInfo> listenerInvoked44= new HashMap<String,GarbageCollectionNotificationInfo>();45static volatile long count = 0;46static volatile long number = 0;47static Object synchronizer = new Object();4849static class GcListener implements NotificationListener {50public void handleNotification(Notification notif, Object handback) {51String type = notif.getType();52if (type.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {53GarbageCollectionNotificationInfo gcNotif =54GarbageCollectionNotificationInfo.from((CompositeData) notif.getUserData());55String source = ((ObjectName)notif.getSource()).getCanonicalName();56synchronized(synchronizer) {57if(listenerInvoked.get(source) == null) {58listenerInvoked.put(((ObjectName)notif.getSource()).getCanonicalName(),gcNotif);59count++;60if(count >= number) {61synchronizer.notify();62}63}64}65}66}67}6869public static void main(String[] args) throws Exception {70MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();71final Boolean isNotificationSupported = AccessController.doPrivileged (new PrivilegedAction<Boolean>() {72public Boolean run() {73try {74Class cl = Class.forName("sun.management.VMManagementImpl");75Field f = cl.getDeclaredField("gcNotificationSupport");76f.setAccessible(true);77return f.getBoolean(null);78} catch(ClassNotFoundException e) {79return false;80} catch(NoSuchFieldException e) {81return false;82} catch(IllegalAccessException e) {83return false;84}85}86});87if(!isNotificationSupported) {88System.out.println("GC Notification not supported by the JVM, test skipped");89return;90}91final ObjectName gcMXBeanPattern =92new ObjectName("java.lang:type=GarbageCollector,*");93Set<ObjectName> names =94mbs.queryNames(gcMXBeanPattern, null);95if (names.isEmpty())96throw new Exception("Test incorrect: no GC MXBeans");97number = names.size();98for (ObjectName n : names) {99if(mbs.isInstanceOf(n,"javax.management.NotificationEmitter")) {100listenerInvoked.put(n.getCanonicalName(),null);101GcListener listener = new GcListener();102mbs.addNotificationListener(n, listener, null, null);103}104}105// Invocation of System.gc() to trigger major GC106System.gc();107// Allocation of many short living and small objects to trigger minor GC108Object data[] = new Object[32];109for(int i = 0; i<100000000; i++) {110data[i%32] = new int[8];111}112int wakeup = 0;113synchronized(synchronizer) {114while(count != number) {115synchronizer.wait(10000);116wakeup++;117if(wakeup > 10)118break;119}120}121for (GarbageCollectionNotificationInfo notif : listenerInvoked.values() ) {122checkGarbageCollectionNotificationInfoContent(notif);123}124System.out.println("Test passed");125}126127private static void checkGarbageCollectionNotificationInfoContent(GarbageCollectionNotificationInfo notif) throws Exception {128System.out.println("GC notification for "+notif.getGcName());129System.out.print("Action: "+notif.getGcAction());130System.out.println(" Cause: "+notif.getGcCause());131GcInfo info = notif.getGcInfo();132System.out.print("GC Info #" + info.getId());133System.out.print(" start:" + info.getStartTime());134System.out.print(" end:" + info.getEndTime());135System.out.println(" (" + info.getDuration() + "ms)");136Map<String, MemoryUsage> usage = info.getMemoryUsageBeforeGc();137138List<String> pnames = new ArrayList<String>();139for (Map.Entry entry : usage.entrySet() ) {140String poolname = (String) entry.getKey();141pnames.add(poolname);142MemoryUsage busage = (MemoryUsage) entry.getValue();143MemoryUsage ausage = (MemoryUsage) info.getMemoryUsageAfterGc().get(poolname);144if (ausage == null) {145throw new RuntimeException("After Gc Memory does not exist" +146" for " + poolname);147}148System.out.println("Usage for pool " + poolname);149System.out.println(" Before GC: " + busage);150System.out.println(" After GC: " + ausage);151}152153// check if memory usage for all memory pools are returned154List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();155for (MemoryPoolMXBean p : pools ) {156if (!pnames.contains(p.getName())) {157throw new RuntimeException("GcInfo does not contain " +158"memory usage for pool " + p.getName());159}160}161}162}163164165