View Javadoc
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 }