23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package sun.management; |
26 package sun.management; |
27 |
27 |
28 import com.sun.management.GarbageCollectorMXBean; |
28 import java.lang.management.GarbageCollectorMXBean; |
29 import com.sun.management.GarbageCollectionNotificationInfo; |
|
30 import java.lang.management.ManagementFactory; |
29 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; |
30 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 |
31 |
49 /** |
32 /** |
50 * Implementation class for the garbage collector. |
33 * Implementation class for the garbage collector. |
51 * Standard and committed hotspot-specific metrics if any. |
|
52 * |
34 * |
53 * ManagementFactory.getGarbageCollectorMXBeans() returns a list |
35 * ManagementFactory.getGarbageCollectorMXBeans() returns a list |
54 * of instances of this class. |
36 * of instances of this class. |
55 */ |
37 */ |
56 class GarbageCollectorImpl extends MemoryManagerImpl |
38 public class GarbageCollectorImpl extends MemoryManagerImpl |
57 implements GarbageCollectorMXBean { |
39 implements GarbageCollectorMXBean { |
58 |
40 |
59 GarbageCollectorImpl(String name) { |
41 protected GarbageCollectorImpl(String name) { |
60 super(name); |
42 super(name); |
61 } |
43 } |
62 |
44 |
|
45 @Override |
63 public native long getCollectionCount(); |
46 public native long getCollectionCount(); |
|
47 |
|
48 @Override |
64 public native long getCollectionTime(); |
49 public native long getCollectionTime(); |
65 |
50 |
66 |
51 @Override |
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() { |
52 public ObjectName getObjectName() { |
186 return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName()); |
53 return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName()); |
187 } |
54 } |
188 |
|
189 native void setNotificationEnabled(GarbageCollectorMXBean gc, |
|
190 boolean enabled); |
|
191 |
|
192 } |
55 } |