blob: 9face5bded95533024d9dd5536a6d6dc19bde617 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2004-2006 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.MemoryUsage;
29import java.lang.reflect.Method;
30import java.util.Iterator;
31import java.util.Map;
32import java.util.HashMap;
33import java.util.List;
34import java.util.Collections;
35import java.io.InvalidObjectException;
36import javax.management.openmbean.CompositeType;
37import javax.management.openmbean.CompositeData;
38import javax.management.openmbean.CompositeDataSupport;
39import javax.management.openmbean.TabularData;
40import javax.management.openmbean.SimpleType;
41import javax.management.openmbean.OpenType;
42import javax.management.openmbean.OpenDataException;
43import com.sun.management.GcInfo;
44
45/**
46 * A CompositeData for GcInfo for the local management support.
47 * This class avoids the performance penalty paid to the
48 * construction of a CompositeData use in the local case.
49 */
50public class GcInfoCompositeData extends LazyCompositeData {
51 private final GcInfo info;
52 private final GcInfoBuilder builder;
53 private final Object[] gcExtItemValues;
54
55 public GcInfoCompositeData(GcInfo info,
56 GcInfoBuilder builder,
57 Object[] gcExtItemValues) {
58 this.info = info;
59 this.builder = builder;
60 this.gcExtItemValues = gcExtItemValues;
61 }
62
63 public GcInfo getGcInfo() {
64 return info;
65 }
66
67 protected CompositeData getCompositeData() {
68 // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
69 // baseGcInfoItemNames!
70 final Object[] baseGcInfoItemValues;
71
72 try {
73 baseGcInfoItemValues = new Object[] {
74 new Long(info.getId()),
75 new Long(info.getStartTime()),
76 new Long(info.getEndTime()),
77 new Long(info.getDuration()),
78 memoryUsageMapType.toOpenTypeData(info.getMemoryUsageBeforeGc()),
79 memoryUsageMapType.toOpenTypeData(info.getMemoryUsageAfterGc()),
80 };
81 } catch (OpenDataException e) {
82 // Should never reach here
83 throw Util.newAssertionError(e);
84 }
85
86 // Get the item values for the extension attributes
87 final int gcExtItemCount = builder.getGcExtItemCount();
88 if (gcExtItemCount == 0 &&
89 gcExtItemValues != null && gcExtItemValues.length != 0) {
90 throw new InternalError("Unexpected Gc Extension Item Values");
91 }
92
93 if (gcExtItemCount > 0 && (gcExtItemValues == null ||
94 gcExtItemCount != gcExtItemValues.length)) {
95 throw new InternalError("Unmatched Gc Extension Item Values");
96 }
97
98 Object[] values = new Object[baseGcInfoItemValues.length +
99 gcExtItemCount];
100 System.arraycopy(baseGcInfoItemValues, 0, values, 0,
101 baseGcInfoItemValues.length);
102
103 if (gcExtItemCount > 0) {
104 System.arraycopy(gcExtItemValues, 0, values,
105 baseGcInfoItemValues.length, gcExtItemCount);
106 }
107
108 try {
109 return new CompositeDataSupport(builder.getGcInfoCompositeType(),
110 builder.getItemNames(),
111 values);
112 } catch (OpenDataException e) {
113 // Should never reach here
114 throw Util.newInternalError(e);
115 }
116 }
117
118
119 private static final String ID = "id";
120 private static final String START_TIME = "startTime";
121 private static final String END_TIME = "endTime";
122 private static final String DURATION = "duration";
123 private static final String MEMORY_USAGE_BEFORE_GC = "memoryUsageBeforeGc";
124 private static final String MEMORY_USAGE_AFTER_GC = "memoryUsageAfterGc";
125
126 private static final String[] baseGcInfoItemNames = {
127 ID,
128 START_TIME,
129 END_TIME,
130 DURATION,
131 MEMORY_USAGE_BEFORE_GC,
132 MEMORY_USAGE_AFTER_GC,
133 };
134
135
136 private static MappedMXBeanType memoryUsageMapType;
137 static {
138 try {
139 Method m = GcInfo.class.getMethod("getMemoryUsageBeforeGc");
140 memoryUsageMapType =
141 MappedMXBeanType.getMappedType(m.getGenericReturnType());
142 } catch (NoSuchMethodException e) {
143 // Should never reach here
144 throw Util.newAssertionError(e);
145 } catch (OpenDataException e) {
146 // Should never reach here
147 throw Util.newAssertionError(e);
148 }
149 }
150
151 static String[] getBaseGcInfoItemNames() {
152 return baseGcInfoItemNames;
153 }
154
155 private static OpenType[] baseGcInfoItemTypes = null;
156 static synchronized OpenType[] getBaseGcInfoItemTypes() {
157 if (baseGcInfoItemTypes == null) {
158 OpenType<?> memoryUsageOpenType = memoryUsageMapType.getOpenType();
159 baseGcInfoItemTypes = new OpenType[] {
160 SimpleType.LONG,
161 SimpleType.LONG,
162 SimpleType.LONG,
163 SimpleType.LONG,
164
165 memoryUsageOpenType,
166 memoryUsageOpenType,
167 };
168 }
169 return baseGcInfoItemTypes;
170 }
171
172 public static long getId(CompositeData cd) {
173 return getLong(cd, ID);
174 }
175 public static long getStartTime(CompositeData cd) {
176 return getLong(cd, START_TIME);
177 }
178 public static long getEndTime(CompositeData cd) {
179 return getLong(cd, END_TIME);
180 }
181
182 public static Map<String, MemoryUsage>
183 getMemoryUsageBeforeGc(CompositeData cd) {
184 try {
185 TabularData td = (TabularData) cd.get(MEMORY_USAGE_BEFORE_GC);
186 return cast(memoryUsageMapType.toJavaTypeData(td));
187 } catch (InvalidObjectException e) {
188 // Should never reach here
189 throw Util.newAssertionError(e);
190 } catch (OpenDataException e) {
191 // Should never reach here
192 throw Util.newAssertionError(e);
193 }
194 }
195
196 @SuppressWarnings("unchecked")
197 public static Map<String, MemoryUsage> cast(Object x) {
198 return (Map<String, MemoryUsage>) x;
199 }
200 public static Map<String, MemoryUsage>
201 getMemoryUsageAfterGc(CompositeData cd) {
202 try {
203 TabularData td = (TabularData) cd.get(MEMORY_USAGE_AFTER_GC);
204 //return (Map<String,MemoryUsage>)
205 return cast(memoryUsageMapType.toJavaTypeData(td));
206 } catch (InvalidObjectException e) {
207 // Should never reach here
208 throw Util.newAssertionError(e);
209 } catch (OpenDataException e) {
210 // Should never reach here
211 throw Util.newAssertionError(e);
212 }
213 }
214
215 /**
216 * Returns true if the input CompositeData has the expected
217 * CompositeType (i.e. contain all attributes with expected
218 * names and types). Otherwise, return false.
219 */
220 public static void validateCompositeData(CompositeData cd) {
221 if (cd == null) {
222 throw new NullPointerException("Null CompositeData");
223 }
224
225 if (!isTypeMatched(getBaseGcInfoCompositeType(),
226 cd.getCompositeType())) {
227 throw new IllegalArgumentException(
228 "Unexpected composite type for GcInfo");
229 }
230 }
231
232 // This is only used for validation.
233 private static CompositeType baseGcInfoCompositeType = null;
234 private static synchronized CompositeType getBaseGcInfoCompositeType() {
235 if (baseGcInfoCompositeType == null) {
236 try {
237 baseGcInfoCompositeType =
238 new CompositeType("sun.management.BaseGcInfoCompositeType",
239 "CompositeType for Base GcInfo",
240 getBaseGcInfoItemNames(),
241 getBaseGcInfoItemNames(),
242 getBaseGcInfoItemTypes());
243 } catch (OpenDataException e) {
244 // shouldn't reach here
245 throw Util.newException(e);
246 }
247 }
248 return baseGcInfoCompositeType;
249 }
250
251}