|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.management; |
|
|
|
import com.sun.management.GarbageCollectorMXBean; |
|
import com.sun.management.GarbageCollectionNotificationInfo; |
|
import java.lang.management.ManagementFactory; |
|
import java.lang.management.MemoryPoolMXBean; |
|
import java.lang.management.MemoryUsage; |
|
|
|
import com.sun.management.GcInfo; |
|
import javax.management.openmbean.CompositeData; |
|
import javax.management.MBeanInfo; |
|
import javax.management.MBeanAttributeInfo; |
|
import javax.management.ObjectName; |
|
import javax.management.MBeanNotificationInfo; |
|
import javax.management.Notification; |
|
import javax.management.NotificationFilter; |
|
import javax.management.NotificationListener; |
|
import javax.management.ListenerNotFoundException; |
|
|
|
import java.util.List; |
|
import java.util.ListIterator; |
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
class GarbageCollectorImpl extends MemoryManagerImpl |
|
implements GarbageCollectorMXBean { |
|
|
|
GarbageCollectorImpl(String name) { |
|
super(name); |
|
} |
|
|
|
public native long getCollectionCount(); |
|
public native long getCollectionTime(); |
|
|
|
|
|
// The memory pools are static and won't be changed. |
|
// TODO: If the hotspot implementation begins to have pools |
|
|
|
private String[] poolNames = null; |
|
synchronized String[] getAllPoolNames() { |
|
if (poolNames == null) { |
|
List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); |
|
poolNames = new String[pools.size()]; |
|
int i = 0; |
|
for (MemoryPoolMXBean m : pools) { |
|
poolNames[i++] = m.getName(); |
|
} |
|
} |
|
return poolNames; |
|
} |
|
|
|
|
|
private GcInfoBuilder gcInfoBuilder; |
|
|
|
private synchronized GcInfoBuilder getGcInfoBuilder() { |
|
if(gcInfoBuilder == null) { |
|
gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames()); |
|
} |
|
return gcInfoBuilder; |
|
} |
|
|
|
public GcInfo getLastGcInfo() { |
|
GcInfo info = getGcInfoBuilder().getLastGcInfo(); |
|
return info; |
|
} |
|
|
|
private final static String notifName = |
|
"javax.management.Notification"; |
|
|
|
private final static String[] gcNotifTypes = { |
|
GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION |
|
}; |
|
|
|
@Override |
|
public MBeanNotificationInfo[] getNotificationInfo() { |
|
return new MBeanNotificationInfo[]{ |
|
new MBeanNotificationInfo(gcNotifTypes, |
|
notifName, |
|
"GC Notification") |
|
}; |
|
} |
|
|
|
private static long seqNumber = 0; |
|
private static long getNextSeqNumber() { |
|
return ++seqNumber; |
|
} |
|
|
|
void createGCNotification(long timestamp, |
|
String gcName, |
|
String gcAction, |
|
String gcCause, |
|
GcInfo gcInfo) { |
|
|
|
if (!hasListeners()) { |
|
return; |
|
} |
|
|
|
Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, |
|
getObjectName(), |
|
getNextSeqNumber(), |
|
timestamp, |
|
gcName); |
|
GarbageCollectionNotificationInfo info = |
|
new GarbageCollectionNotificationInfo(gcName, |
|
gcAction, |
|
gcCause, |
|
gcInfo); |
|
|
|
CompositeData cd = |
|
GarbageCollectionNotifInfoCompositeData.toCompositeData(info); |
|
notif.setUserData(cd); |
|
sendNotification(notif); |
|
} |
|
|
|
public synchronized void addNotificationListener(NotificationListener listener, |
|
NotificationFilter filter, |
|
Object handback) |
|
{ |
|
boolean before = hasListeners(); |
|
super.addNotificationListener(listener, filter, handback); |
|
boolean after = hasListeners(); |
|
if (!before && after) { |
|
setNotificationEnabled(this, true); |
|
} |
|
} |
|
|
|
public synchronized void removeNotificationListener(NotificationListener listener) |
|
throws ListenerNotFoundException { |
|
boolean before = hasListeners(); |
|
super.removeNotificationListener(listener); |
|
boolean after = hasListeners(); |
|
if (before && !after) { |
|
setNotificationEnabled(this,false); |
|
} |
|
} |
|
|
|
public synchronized void removeNotificationListener(NotificationListener listener, |
|
NotificationFilter filter, |
|
Object handback) |
|
throws ListenerNotFoundException |
|
{ |
|
boolean before = hasListeners(); |
|
super.removeNotificationListener(listener,filter,handback); |
|
boolean after = hasListeners(); |
|
if (before && !after) { |
|
setNotificationEnabled(this,false); |
|
} |
|
} |
|
|
|
public ObjectName getObjectName() { |
|
return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName()); |
|
} |
|
|
|
native void setNotificationEnabled(GarbageCollectorMXBean gc, |
|
boolean enabled); |
|
|
|
} |