blob: 2e8fcf25944343b1819115d006d3068ab8f51c79 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2005 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.management;
27
28import java.lang.management.MemoryMXBean;
29import java.lang.management.MemoryUsage;
30import java.lang.management.MemoryNotificationInfo;
31import java.lang.management.MemoryManagerMXBean;
32import java.lang.management.MemoryPoolMXBean;
33import javax.management.ObjectName;
34import javax.management.MalformedObjectNameException;
35import javax.management.MBeanNotificationInfo;
36import javax.management.Notification;
37import javax.management.NotificationEmitter;
38import javax.management.NotificationFilter;
39import javax.management.NotificationListener;
40import javax.management.ListenerNotFoundException;
41import javax.management.openmbean.CompositeData;
42import java.util.List;
43import java.util.ArrayList;
44import java.util.ListIterator;
45import java.util.Collections;
46
47/**
48 * Implementation class for the memory subsystem.
49 * Standard and committed hotspot-specific metrics if any.
50 *
51 * ManagementFactory.getMemoryMXBean() returns an instance
52 * of this class.
53 */
54class MemoryImpl extends NotificationEmitterSupport
55 implements MemoryMXBean {
56
57 private final VMManagement jvm;
58
59 private static MemoryPoolMXBean[] pools = null;
60 private static MemoryManagerMXBean[] mgrs = null;
61
62 /**
63 * Constructor of MemoryImpl class
64 */
65 MemoryImpl(VMManagement vm) {
66 this.jvm = vm;
67 }
68
69 public int getObjectPendingFinalizationCount() {
70 return sun.misc.VM.getFinalRefCount();
71 }
72
73 public void gc() {
74 Runtime.getRuntime().gc();
75 }
76
77 // Need to make a VM call to get coherent value
78 public MemoryUsage getHeapMemoryUsage() {
79 return getMemoryUsage0(true);
80 }
81
82 public MemoryUsage getNonHeapMemoryUsage() {
83 return getMemoryUsage0(false);
84 }
85
86 public boolean isVerbose() {
87 return jvm.getVerboseGC();
88 }
89
90 public void setVerbose(boolean value) {
91 ManagementFactory.checkControlAccess();
92
93 setVerboseGC(value);
94 }
95
96 // The current Hotspot implementation does not support
97 // dynamically add or remove memory pools & managers.
98 static synchronized MemoryPoolMXBean[] getMemoryPools() {
99 if (pools == null) {
100 pools = getMemoryPools0();
101 }
102 return pools;
103 }
104 static synchronized MemoryManagerMXBean[] getMemoryManagers() {
105 if (mgrs == null) {
106 mgrs = getMemoryManagers0();
107 }
108 return mgrs;
109 }
110 private static native MemoryPoolMXBean[] getMemoryPools0();
111 private static native MemoryManagerMXBean[] getMemoryManagers0();
112 private native MemoryUsage getMemoryUsage0(boolean heap);
113 private native void setVerboseGC(boolean value);
114
115 private final static String notifName =
116 "javax.management.Notification";
117 private final static String[] notifTypes = {
118 MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
119 MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED
120 };
121 private final static String[] notifMsgs = {
122 "Memory usage exceeds usage threshold",
123 "Memory usage exceeds collection usage threshold"
124 };
125
126 private MBeanNotificationInfo[] notifInfo = null;
127 public MBeanNotificationInfo[] getNotificationInfo() {
128 synchronized (this) {
129 if (notifInfo == null) {
130 notifInfo = new MBeanNotificationInfo[1];
131 notifInfo[0] = new MBeanNotificationInfo(notifTypes,
132 notifName,
133 "Memory Notification");
134 }
135 }
136 return notifInfo;
137 }
138
139 private static String getNotifMsg(String notifType) {
140 for (int i = 0; i < notifTypes.length; i++) {
141 if (notifType == notifTypes[i]) {
142 return notifMsgs[i];
143 }
144 }
145 return "Unknown message";
146 }
147
148 private static long seqNumber = 0;
149 private static long getNextSeqNumber() {
150 return ++seqNumber;
151 }
152
153 private static ObjectName objname = null;
154 private static synchronized ObjectName getObjectName() {
155 if (objname != null) return objname;
156
157 try {
158 objname = new ObjectName(java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME);
159 } catch (MalformedObjectNameException e) {
160 // should never reach here
161 throw Util.newInternalError(e);
162 }
163 return objname;
164 }
165
166 static void createNotification(String notifType,
167 String poolName,
168 MemoryUsage usage,
169 long count) {
170 MemoryImpl mbean = (MemoryImpl) ManagementFactory.getMemoryMXBean();
171 if (!mbean.hasListeners()) {
172 // if no listener is registered.
173 return;
174 }
175 long timestamp = System.currentTimeMillis();
176 String msg = getNotifMsg(notifType);
177 Notification notif = new Notification(notifType,
178 getObjectName(),
179 getNextSeqNumber(),
180 timestamp,
181 msg);
182 MemoryNotificationInfo info =
183 new MemoryNotificationInfo(poolName,
184 usage,
185 count);
186 CompositeData cd =
187 MemoryNotifInfoCompositeData.toCompositeData(info);
188 notif.setUserData(cd);
189 mbean.sendNotification(notif);
190 }
191
192}