1 /* 2 * Copyright (c) 2003, 2012, 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 26 package sun.management; 27 28 import com.sun.management.GarbageCollectorMXBean; 29 import com.sun.management.GarbageCollectionNotificationInfo; 30 import java.lang.management.ManagementFactory; 31 import java.lang.management.MemoryPoolMXBean; 32 import java.lang.management.MemoryUsage; 33 34 import com.sun.management.GcInfo; 35 import javax.management.openmbean.CompositeData; 36 import javax.management.MBeanInfo; 37 import javax.management.MBeanAttributeInfo; 38 import javax.management.ObjectName; 39 import javax.management.MBeanNotificationInfo; 40 import javax.management.Notification; 41 import javax.management.NotificationFilter; 42 import javax.management.NotificationListener; 43 import javax.management.ListenerNotFoundException; 44 45 import java.util.List; 46 import java.util.ListIterator; 47 import java.util.Map; 48 49 /** 50 * Implementation class for the garbage collector. 51 * Standard and committed hotspot-specific metrics if any. 52 * 53 * ManagementFactory.getGarbageCollectorMXBeans() returns a list 54 * of instances of this class. 55 */ 56 class GarbageCollectorImpl extends MemoryManagerImpl 57 implements GarbageCollectorMXBean { 58 59 GarbageCollectorImpl(String name) { 60 super(name); 61 } 62 63 public native long getCollectionCount(); 64 public native long getCollectionTime(); 65 66 67 // The memory pools are static and won't be changed. 68 // TODO: If the hotspot implementation begins to have pools 69 // dynamically created and removed, this needs to be modified. 70 private String[] poolNames = null; 71 synchronized String[] getAllPoolNames() { 72 if (poolNames == null) { 73 List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); 74 poolNames = new String[pools.size()]; 75 int i = 0; 76 for (MemoryPoolMXBean m : pools) { 77 poolNames[i++] = m.getName(); 78 } 79 } 80 return poolNames; 81 } 82 83 // Sun JDK extension 84 private GcInfoBuilder gcInfoBuilder; 85 86 private synchronized GcInfoBuilder getGcInfoBuilder() { 87 if(gcInfoBuilder == null) { 88 gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames()); 89 } 90 return gcInfoBuilder; 91 } 92 93 public GcInfo getLastGcInfo() { 94 GcInfo info = getGcInfoBuilder().getLastGcInfo(); 95 return info; 96 } 97 98 private final static String notifName = 99 "javax.management.Notification"; 100 101 private final static String[] gcNotifTypes = { 102 GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION 103 }; 104 105 private MBeanNotificationInfo[] notifInfo = null; 106 public MBeanNotificationInfo[] getNotificationInfo() { 107 synchronized (this) { 108 if (notifInfo == null) { 109 notifInfo = new MBeanNotificationInfo[1]; 110 notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes, 111 notifName, 112 "GC Notification"); 113 } 114 } 115 return notifInfo; 116 } 117 118 private static long seqNumber = 0; 119 private static long getNextSeqNumber() { 120 return ++seqNumber; 121 } 122 123 void createGCNotification(long timestamp, 124 String gcName, 125 String gcAction, 126 String gcCause, 127 GcInfo gcInfo) { 128 129 if (!hasListeners()) { 130 return; 131 } 132 133 Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, 134 getObjectName(), 135 getNextSeqNumber(), 136 timestamp, 137 gcName); 138 GarbageCollectionNotificationInfo info = 139 new GarbageCollectionNotificationInfo(gcName, 140 gcAction, 141 gcCause, 142 gcInfo); 143 144 CompositeData cd = 145 GarbageCollectionNotifInfoCompositeData.toCompositeData(info); 146 notif.setUserData(cd); 147 sendNotification(notif); 148 } 149 150 public synchronized void addNotificationListener(NotificationListener listener, 151 NotificationFilter filter, 152 Object handback) 153 { 154 boolean before = hasListeners(); 155 super.addNotificationListener(listener, filter, handback); 156 boolean after = hasListeners(); 157 if (!before && after) { 158 setNotificationEnabled(this, true); 159 } 160 } 161 162 public synchronized void removeNotificationListener(NotificationListener listener) 163 throws ListenerNotFoundException { 164 boolean before = hasListeners(); 165 super.removeNotificationListener(listener); 166 boolean after = hasListeners(); 167 if (before && !after) { 168 setNotificationEnabled(this,false); 169 } 170 } 171 172 public synchronized void removeNotificationListener(NotificationListener listener, 173 NotificationFilter filter, 174 Object handback) 175 throws ListenerNotFoundException 176 { 177 boolean before = hasListeners(); 178 super.removeNotificationListener(listener,filter,handback); 179 boolean after = hasListeners(); 180 if (before && !after) { 181 setNotificationEnabled(this,false); 182 } 183 } 184 185 public ObjectName getObjectName() { 186 return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName()); 187 } 188 189 native void setNotificationEnabled(GarbageCollectorMXBean gc, 190 boolean enabled); 191 192 }