001: /*
002: * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.management;
027:
028: import java.lang.management.MemoryUsage;
029: import java.lang.reflect.Method;
030: import java.util.Iterator;
031: import java.util.Map;
032: import java.util.HashMap;
033: import java.util.List;
034: import java.util.Collections;
035: import java.io.InvalidObjectException;
036: import javax.management.openmbean.CompositeType;
037: import javax.management.openmbean.CompositeData;
038: import javax.management.openmbean.CompositeDataSupport;
039: import javax.management.openmbean.TabularData;
040: import javax.management.openmbean.SimpleType;
041: import javax.management.openmbean.OpenType;
042: import javax.management.openmbean.OpenDataException;
043: import com.sun.management.GcInfo;
044:
045: /**
046: * A CompositeData for GcInfo for the local management support.
047: * This class avoids the performance penalty paid to the
048: * construction of a CompositeData use in the local case.
049: */
050: public class GcInfoCompositeData extends LazyCompositeData {
051: private final GcInfo info;
052: private final GcInfoBuilder builder;
053: private final Object[] gcExtItemValues;
054:
055: public GcInfoCompositeData(GcInfo info, GcInfoBuilder builder,
056: Object[] gcExtItemValues) {
057: this .info = info;
058: this .builder = builder;
059: this .gcExtItemValues = gcExtItemValues;
060: }
061:
062: public GcInfo getGcInfo() {
063: return info;
064: }
065:
066: protected CompositeData getCompositeData() {
067: // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
068: // baseGcInfoItemNames!
069: final Object[] baseGcInfoItemValues;
070:
071: try {
072: baseGcInfoItemValues = new Object[] {
073: new Long(info.getId()),
074: new Long(info.getStartTime()),
075: new Long(info.getEndTime()),
076: new Long(info.getDuration()),
077: memoryUsageMapType.toOpenTypeData(info
078: .getMemoryUsageBeforeGc()),
079: memoryUsageMapType.toOpenTypeData(info
080: .getMemoryUsageAfterGc()), };
081: } catch (OpenDataException e) {
082: // Should never reach here
083: throw Util.newAssertionError(e);
084: }
085:
086: // Get the item values for the extension attributes
087: final int gcExtItemCount = builder.getGcExtItemCount();
088: if (gcExtItemCount == 0 && gcExtItemValues != null
089: && gcExtItemValues.length != 0) {
090: throw new InternalError(
091: "Unexpected Gc Extension Item Values");
092: }
093:
094: if (gcExtItemCount > 0
095: && (gcExtItemValues == null || gcExtItemCount != gcExtItemValues.length)) {
096: throw new InternalError(
097: "Unmatched Gc Extension Item Values");
098: }
099:
100: Object[] values = new Object[baseGcInfoItemValues.length
101: + gcExtItemCount];
102: System.arraycopy(baseGcInfoItemValues, 0, values, 0,
103: baseGcInfoItemValues.length);
104:
105: if (gcExtItemCount > 0) {
106: System.arraycopy(gcExtItemValues, 0, values,
107: baseGcInfoItemValues.length, gcExtItemCount);
108: }
109:
110: try {
111: return new CompositeDataSupport(builder
112: .getGcInfoCompositeType(), builder.getItemNames(),
113: values);
114: } catch (OpenDataException e) {
115: // Should never reach here
116: throw Util.newInternalError(e);
117: }
118: }
119:
120: private static final String ID = "id";
121: private static final String START_TIME = "startTime";
122: private static final String END_TIME = "endTime";
123: private static final String DURATION = "duration";
124: private static final String MEMORY_USAGE_BEFORE_GC = "memoryUsageBeforeGc";
125: private static final String MEMORY_USAGE_AFTER_GC = "memoryUsageAfterGc";
126:
127: private static final String[] baseGcInfoItemNames = { ID,
128: START_TIME, END_TIME, DURATION, MEMORY_USAGE_BEFORE_GC,
129: MEMORY_USAGE_AFTER_GC, };
130:
131: private static MappedMXBeanType memoryUsageMapType;
132: static {
133: try {
134: Method m = GcInfo.class.getMethod("getMemoryUsageBeforeGc");
135: memoryUsageMapType = MappedMXBeanType.getMappedType(m
136: .getGenericReturnType());
137: } catch (NoSuchMethodException e) {
138: // Should never reach here
139: throw Util.newAssertionError(e);
140: } catch (OpenDataException e) {
141: // Should never reach here
142: throw Util.newAssertionError(e);
143: }
144: }
145:
146: static String[] getBaseGcInfoItemNames() {
147: return baseGcInfoItemNames;
148: }
149:
150: private static OpenType[] baseGcInfoItemTypes = null;
151:
152: static synchronized OpenType[] getBaseGcInfoItemTypes() {
153: if (baseGcInfoItemTypes == null) {
154: OpenType<?> memoryUsageOpenType = memoryUsageMapType
155: .getOpenType();
156: baseGcInfoItemTypes = new OpenType[] { SimpleType.LONG,
157: SimpleType.LONG, SimpleType.LONG, SimpleType.LONG,
158:
159: memoryUsageOpenType, memoryUsageOpenType, };
160: }
161: return baseGcInfoItemTypes;
162: }
163:
164: public static long getId(CompositeData cd) {
165: return getLong(cd, ID);
166: }
167:
168: public static long getStartTime(CompositeData cd) {
169: return getLong(cd, START_TIME);
170: }
171:
172: public static long getEndTime(CompositeData cd) {
173: return getLong(cd, END_TIME);
174: }
175:
176: public static Map<String, MemoryUsage> getMemoryUsageBeforeGc(
177: CompositeData cd) {
178: try {
179: TabularData td = (TabularData) cd
180: .get(MEMORY_USAGE_BEFORE_GC);
181: return cast(memoryUsageMapType.toJavaTypeData(td));
182: } catch (InvalidObjectException e) {
183: // Should never reach here
184: throw Util.newAssertionError(e);
185: } catch (OpenDataException e) {
186: // Should never reach here
187: throw Util.newAssertionError(e);
188: }
189: }
190:
191: @SuppressWarnings("unchecked")
192: public static Map<String, MemoryUsage> cast(Object x) {
193: return (Map<String, MemoryUsage>) x;
194: }
195:
196: public static Map<String, MemoryUsage> getMemoryUsageAfterGc(
197: CompositeData cd) {
198: try {
199: TabularData td = (TabularData) cd
200: .get(MEMORY_USAGE_AFTER_GC);
201: //return (Map<String,MemoryUsage>)
202: return cast(memoryUsageMapType.toJavaTypeData(td));
203: } catch (InvalidObjectException e) {
204: // Should never reach here
205: throw Util.newAssertionError(e);
206: } catch (OpenDataException e) {
207: // Should never reach here
208: throw Util.newAssertionError(e);
209: }
210: }
211:
212: /**
213: * Returns true if the input CompositeData has the expected
214: * CompositeType (i.e. contain all attributes with expected
215: * names and types). Otherwise, return false.
216: */
217: public static void validateCompositeData(CompositeData cd) {
218: if (cd == null) {
219: throw new NullPointerException("Null CompositeData");
220: }
221:
222: if (!isTypeMatched(getBaseGcInfoCompositeType(), cd
223: .getCompositeType())) {
224: throw new IllegalArgumentException(
225: "Unexpected composite type for GcInfo");
226: }
227: }
228:
229: // This is only used for validation.
230: private static CompositeType baseGcInfoCompositeType = null;
231:
232: private static synchronized CompositeType getBaseGcInfoCompositeType() {
233: if (baseGcInfoCompositeType == null) {
234: try {
235: baseGcInfoCompositeType = new CompositeType(
236: "sun.management.BaseGcInfoCompositeType",
237: "CompositeType for Base GcInfo",
238: getBaseGcInfoItemNames(),
239: getBaseGcInfoItemNames(),
240: getBaseGcInfoItemTypes());
241: } catch (OpenDataException e) {
242: // shouldn't reach here
243: throw Util.newException(e);
244: }
245: }
246: return baseGcInfoCompositeType;
247: }
248:
249: }
|