1/* 2 * Copyright (c) 2003, 2015, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.management.internal; 27 28import com.sun.management.GarbageCollectionNotificationInfo; 29import com.sun.management.GarbageCollectorMXBean; 30import com.sun.management.GcInfo; 31import java.lang.management.ManagementFactory; 32import java.lang.management.MemoryPoolMXBean; 33import java.util.List; 34import javax.management.ListenerNotFoundException; 35import javax.management.MBeanNotificationInfo; 36import javax.management.Notification; 37import javax.management.NotificationFilter; 38import javax.management.NotificationListener; 39import javax.management.openmbean.CompositeData; 40import sun.management.GarbageCollectorImpl; 41 42/** 43 * Implementation class for the garbage collector. 44 * Standard and committed hotspot-specific metrics if any. 45 * 46 * ManagementFactory.getGarbageCollectorMXBeans() returns a list 47 * of instances of this class. 48 */ 49public class GarbageCollectorExtImpl extends GarbageCollectorImpl 50 implements GarbageCollectorMXBean { 51 52 public GarbageCollectorExtImpl(String name) { 53 super(name); 54 } 55 56 // The memory pools are static and won't be changed. 57 // TODO: If the hotspot implementation begins to have pools 58 // dynamically created and removed, this needs to be modified. 59 private String[] poolNames = null; 60 private synchronized String[] getAllPoolNames() { 61 if (poolNames == null) { 62 List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); 63 poolNames = new String[pools.size()]; 64 int i = 0; 65 for (MemoryPoolMXBean m : pools) { 66 poolNames[i++] = m.getName(); 67 } 68 } 69 return poolNames; 70 } 71 72 public GcInfo getLastGcInfo() { 73 GcInfo info = getGcInfoBuilder().getLastGcInfo(); 74 return info; 75 } 76 77 private final static String notifName = 78 "javax.management.Notification"; 79 80 private final static String[] gcNotifTypes = { 81 GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION 82 }; 83 84 public MBeanNotificationInfo[] getNotificationInfo() { 85 return new MBeanNotificationInfo[]{ 86 new MBeanNotificationInfo(gcNotifTypes, 87 notifName, 88 "GC Notification") 89 }; 90 } 91 92 private static long seqNumber = 0; 93 private static long getNextSeqNumber() { 94 return ++seqNumber; 95 } 96 97 protected void createGCNotification(long timestamp, 98 String gcName, 99 String gcAction, 100 String gcCause, 101 GcInfo gcInfo) { 102 if (!hasListeners()) { 103 return; 104 } 105 Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, 106 getObjectName(), 107 getNextSeqNumber(), 108 timestamp, 109 gcName); 110 GarbageCollectionNotificationInfo info = 111 new GarbageCollectionNotificationInfo(gcName, 112 gcAction, 113 gcCause, 114 gcInfo); 115 116 CompositeData cd = 117 GarbageCollectionNotifInfoCompositeData.toCompositeData(info); 118 notif.setUserData(cd); 119 sendNotification(notif); 120 } 121 122 public synchronized void addNotificationListener(NotificationListener listener, 123 NotificationFilter filter, 124 Object handback) 125 { 126 boolean before = hasListeners(); 127 super.addNotificationListener(listener, filter, handback); 128 boolean after = hasListeners(); 129 if (!before && after) { 130 setNotificationEnabled(this, true); 131 } 132 } 133 134 public synchronized void removeNotificationListener(NotificationListener listener) 135 throws ListenerNotFoundException { 136 boolean before = hasListeners(); 137 super.removeNotificationListener(listener); 138 boolean after = hasListeners(); 139 140 if (before && !after) { 141 setNotificationEnabled(this,false); 142 } 143 } 144 145 public synchronized void removeNotificationListener(NotificationListener listener, 146 NotificationFilter filter, 147 Object handback) 148 throws ListenerNotFoundException 149 { 150 boolean before = hasListeners(); 151 super.removeNotificationListener(listener,filter,handback); 152 boolean after = hasListeners(); 153 if (before && !after) { 154 setNotificationEnabled(this,false); 155 } 156 } 157 158 private GcInfoBuilder gcInfoBuilder; 159 // Invoked also by the VM 160 private synchronized GcInfoBuilder getGcInfoBuilder() { 161 if(gcInfoBuilder == null) { 162 gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames()); 163 } 164 return gcInfoBuilder; 165 } 166 167 private native void setNotificationEnabled(GarbageCollectorMXBean gc, 168 boolean enabled); 169 170 // Invoked by the VM 171 private static java.lang.management.GarbageCollectorMXBean 172 createGarbageCollector(String name, String type) { 173 174 return new GarbageCollectorExtImpl(name); 175 } 176} 177