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  package sun.management;
26  
27  import java.lang.management.GarbageCollectorMXBean;
28  import java.lang.management.MemoryUsage;
29  import javax.management.openmbean.OpenType;
30  import javax.management.openmbean.SimpleType;
31  import javax.management.openmbean.TabularType;
32  import javax.management.openmbean.TabularData;
33  import javax.management.openmbean.TabularDataSupport;
34  import javax.management.openmbean.CompositeType;
35  import javax.management.openmbean.CompositeData;
36  import javax.management.openmbean.CompositeDataSupport;
37  import javax.management.openmbean.OpenDataException;
38  import com.sun.management.GcInfo;
39  
40  /**
41   * Helper class to build composite data.
42   */
43  public class GcInfoBuilder {
44      private final GarbageCollectorMXBean gc;
45      private final String[] poolNames;
46      private String[] allItemNames;
47  
48      // GC-specific composite type:
49      // Each GarbageCollectorMXBean may have different GC-specific attributes
50      // the CompositeType for the GcInfo could be different.
51      private CompositeType gcInfoCompositeType;
52  
53      // GC-specific items
54      private final int gcExtItemCount;
55      private final String[] gcExtItemNames;
56      private final String[] gcExtItemDescs;
57      private final char[] gcExtItemTypes;
58  
59      GcInfoBuilder(GarbageCollectorMXBean gc, String[] poolNames) {
60          this.gc = gc;
61          this.poolNames = poolNames;
62          this.gcExtItemCount = getNumGcExtAttributes(gc);
63          this.gcExtItemNames = new String[gcExtItemCount];
64          this.gcExtItemDescs = new String[gcExtItemCount];
65          this.gcExtItemTypes = new char[gcExtItemCount];
66  
67          // Fill the information about extension attributes
68          fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames,
69                              gcExtItemTypes, gcExtItemDescs);
70  
71          // lazily build the CompositeType for the GcInfo
72          // including the GC-specific extension attributes
73          this.gcInfoCompositeType = null;
74      }
75  
76      GcInfo getLastGcInfo() {
77          MemoryUsage[] usageBeforeGC = new MemoryUsage[poolNames.length];
78          MemoryUsage[] usageAfterGC = new MemoryUsage[poolNames.length];
79          Object[] values = new Object[gcExtItemCount];
80  
81          return getLastGcInfo0(gc, gcExtItemCount, values, gcExtItemTypes,
82                                usageBeforeGC, usageAfterGC);
83      }
84  
85      public String[] getPoolNames() {
86          return poolNames;
87      }
88  
89      int getGcExtItemCount() {
90          return gcExtItemCount;
91      }
92  
93      // Returns the CompositeType for the GcInfo including
94      // the extension attributes
95      synchronized CompositeType getGcInfoCompositeType() {
96          if (gcInfoCompositeType != null)
97              return gcInfoCompositeType;
98  
99          // First, fill with the attributes in the GcInfo
100         String[] gcInfoItemNames = GcInfoCompositeData.getBaseGcInfoItemNames();
101         OpenType[] gcInfoItemTypes = GcInfoCompositeData.getBaseGcInfoItemTypes();
102         int numGcInfoItems = gcInfoItemNames.length;
103 
104         int itemCount = numGcInfoItems + gcExtItemCount;
105         allItemNames = new String[itemCount];
106         String[] allItemDescs = new String[itemCount];
107         OpenType<?>[] allItemTypes = new OpenType<?>[itemCount];
108 
109         System.arraycopy(gcInfoItemNames, 0, allItemNames, 0, numGcInfoItems);
110         System.arraycopy(gcInfoItemNames, 0, allItemDescs, 0, numGcInfoItems);
111         System.arraycopy(gcInfoItemTypes, 0, allItemTypes, 0, numGcInfoItems);
112 
113         // Then fill with the extension GC-specific attributes, if any.
114         if (gcExtItemCount > 0) {
115             fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames,
116                                 gcExtItemTypes, gcExtItemDescs);
117             System.arraycopy(gcExtItemNames, 0, allItemNames,
118                              numGcInfoItems, gcExtItemCount);
119             System.arraycopy(gcExtItemDescs, 0, allItemDescs,
120                              numGcInfoItems, gcExtItemCount);
121             for (int i = numGcInfoItems, j = 0; j < gcExtItemCount; i++, j++) {
122                 switch (gcExtItemTypes[j]) {
123                     case 'Z':
124                         allItemTypes[i] = SimpleType.BOOLEAN;
125                         break;
126                     case 'B':
127                         allItemTypes[i] = SimpleType.BYTE;
128                         break;
129                     case 'C':
130                         allItemTypes[i] = SimpleType.CHARACTER;
131                         break;
132                     case 'S':
133                         allItemTypes[i] = SimpleType.SHORT;
134                         break;
135                     case 'I':
136                         allItemTypes[i] = SimpleType.INTEGER;
137                         break;
138                     case 'J':
139                         allItemTypes[i] = SimpleType.LONG;
140                         break;
141                     case 'F':
142                         allItemTypes[i] = SimpleType.FLOAT;
143                         break;
144                     case 'D':
145                         allItemTypes[i] = SimpleType.DOUBLE;
146                         break;
147                     default:
148                         throw new AssertionError(
149                             "Unsupported type [" + gcExtItemTypes[i] + "]");
150                 }
151             }
152         }
153 
154         CompositeType gict = null;
155         try {
156             final String typeName =
157                 "sun.management." + gc.getName() + ".GcInfoCompositeType";
158 
159             gict = new CompositeType(typeName,
160                                      "CompositeType for GC info for " +
161                                          gc.getName(),
162                                      allItemNames,
163                                      allItemDescs,
164                                      allItemTypes);
165         } catch (OpenDataException e) {
166             // shouldn't reach here
167             throw Util.newException(e);
168         }
169         gcInfoCompositeType = gict;
170 
171         return gcInfoCompositeType;
172     }
173 
174     synchronized String[] getItemNames() {
175         if (allItemNames == null) {
176             // initialize when forming the composite type
177             getGcInfoCompositeType();
178         }
179         return allItemNames;
180     }
181 
182     // Retrieve information about extension attributes
183     private native int getNumGcExtAttributes(GarbageCollectorMXBean gc);
184     private native void fillGcAttributeInfo(GarbageCollectorMXBean gc,
185                                             int numAttributes,
186                                             String[] attributeNames,
187                                             char[] types,
188                                             String[] descriptions);
189 
190     /**
191      * Returns the last GcInfo
192      *
193      * @param gc GarbageCollectorMXBean that the gc info is associated with.
194      * @param numExtAtts number of extension attributes
195      * @param extAttValues Values of extension attributes to be filled.
196      * @param before Memory usage before GC to be filled.
197      * @param after Memory usage after GC to be filled.
198      */
199     private native GcInfo getLastGcInfo0(GarbageCollectorMXBean gc,
200                                          int numExtAtts,
201                                          Object[] extAttValues,
202                                          char[] extAttTypes,
203                                          MemoryUsage[] before,
204                                          MemoryUsage[] after);
205 }