|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package sun.management; |
|
|
|
import java.lang.management.GarbageCollectorMXBean; |
|
import java.lang.management.MemoryUsage; |
|
import javax.management.openmbean.OpenType; |
|
import javax.management.openmbean.SimpleType; |
|
import javax.management.openmbean.TabularType; |
|
import javax.management.openmbean.TabularData; |
|
import javax.management.openmbean.TabularDataSupport; |
|
import javax.management.openmbean.CompositeType; |
|
import javax.management.openmbean.CompositeData; |
|
import javax.management.openmbean.CompositeDataSupport; |
|
import javax.management.openmbean.OpenDataException; |
|
import com.sun.management.GcInfo; |
|
|
|
|
|
|
|
*/ |
|
public class GcInfoBuilder { |
|
private final GarbageCollectorMXBean gc; |
|
private final String[] poolNames; |
|
private String[] allItemNames; |
|
|
|
// GC-specific composite type: |
|
// Each GarbageCollectorMXBean may have different GC-specific attributes |
|
|
|
private CompositeType gcInfoCompositeType; |
|
|
|
|
|
private final int gcExtItemCount; |
|
private final String[] gcExtItemNames; |
|
private final String[] gcExtItemDescs; |
|
private final char[] gcExtItemTypes; |
|
|
|
GcInfoBuilder(GarbageCollectorMXBean gc, String[] poolNames) { |
|
this.gc = gc; |
|
this.poolNames = poolNames; |
|
this.gcExtItemCount = getNumGcExtAttributes(gc); |
|
this.gcExtItemNames = new String[gcExtItemCount]; |
|
this.gcExtItemDescs = new String[gcExtItemCount]; |
|
this.gcExtItemTypes = new char[gcExtItemCount]; |
|
|
|
|
|
fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames, |
|
gcExtItemTypes, gcExtItemDescs); |
|
|
|
// lazily build the CompositeType for the GcInfo |
|
|
|
this.gcInfoCompositeType = null; |
|
} |
|
|
|
GcInfo getLastGcInfo() { |
|
MemoryUsage[] usageBeforeGC = new MemoryUsage[poolNames.length]; |
|
MemoryUsage[] usageAfterGC = new MemoryUsage[poolNames.length]; |
|
Object[] values = new Object[gcExtItemCount]; |
|
|
|
return getLastGcInfo0(gc, gcExtItemCount, values, gcExtItemTypes, |
|
usageBeforeGC, usageAfterGC); |
|
} |
|
|
|
public String[] getPoolNames() { |
|
return poolNames; |
|
} |
|
|
|
int getGcExtItemCount() { |
|
return gcExtItemCount; |
|
} |
|
|
|
// Returns the CompositeType for the GcInfo including |
|
|
|
synchronized CompositeType getGcInfoCompositeType() { |
|
if (gcInfoCompositeType != null) |
|
return gcInfoCompositeType; |
|
|
|
|
|
String[] gcInfoItemNames = GcInfoCompositeData.getBaseGcInfoItemNames(); |
|
OpenType[] gcInfoItemTypes = GcInfoCompositeData.getBaseGcInfoItemTypes(); |
|
int numGcInfoItems = gcInfoItemNames.length; |
|
|
|
int itemCount = numGcInfoItems + gcExtItemCount; |
|
allItemNames = new String[itemCount]; |
|
String[] allItemDescs = new String[itemCount]; |
|
OpenType<?>[] allItemTypes = new OpenType<?>[itemCount]; |
|
|
|
System.arraycopy(gcInfoItemNames, 0, allItemNames, 0, numGcInfoItems); |
|
System.arraycopy(gcInfoItemNames, 0, allItemDescs, 0, numGcInfoItems); |
|
System.arraycopy(gcInfoItemTypes, 0, allItemTypes, 0, numGcInfoItems); |
|
|
|
|
|
if (gcExtItemCount > 0) { |
|
fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames, |
|
gcExtItemTypes, gcExtItemDescs); |
|
System.arraycopy(gcExtItemNames, 0, allItemNames, |
|
numGcInfoItems, gcExtItemCount); |
|
System.arraycopy(gcExtItemDescs, 0, allItemDescs, |
|
numGcInfoItems, gcExtItemCount); |
|
for (int i = numGcInfoItems, j = 0; j < gcExtItemCount; i++, j++) { |
|
switch (gcExtItemTypes[j]) { |
|
case 'Z': |
|
allItemTypes[i] = SimpleType.BOOLEAN; |
|
break; |
|
case 'B': |
|
allItemTypes[i] = SimpleType.BYTE; |
|
break; |
|
case 'C': |
|
allItemTypes[i] = SimpleType.CHARACTER; |
|
break; |
|
case 'S': |
|
allItemTypes[i] = SimpleType.SHORT; |
|
break; |
|
case 'I': |
|
allItemTypes[i] = SimpleType.INTEGER; |
|
break; |
|
case 'J': |
|
allItemTypes[i] = SimpleType.LONG; |
|
break; |
|
case 'F': |
|
allItemTypes[i] = SimpleType.FLOAT; |
|
break; |
|
case 'D': |
|
allItemTypes[i] = SimpleType.DOUBLE; |
|
break; |
|
default: |
|
throw new AssertionError( |
|
"Unsupported type [" + gcExtItemTypes[i] + "]"); |
|
} |
|
} |
|
} |
|
|
|
CompositeType gict = null; |
|
try { |
|
final String typeName = |
|
"sun.management." + gc.getName() + ".GcInfoCompositeType"; |
|
|
|
gict = new CompositeType(typeName, |
|
"CompositeType for GC info for " + |
|
gc.getName(), |
|
allItemNames, |
|
allItemDescs, |
|
allItemTypes); |
|
} catch (OpenDataException e) { |
|
|
|
throw Util.newException(e); |
|
} |
|
gcInfoCompositeType = gict; |
|
|
|
return gcInfoCompositeType; |
|
} |
|
|
|
synchronized String[] getItemNames() { |
|
if (allItemNames == null) { |
|
|
|
getGcInfoCompositeType(); |
|
} |
|
return allItemNames; |
|
} |
|
|
|
|
|
private native int getNumGcExtAttributes(GarbageCollectorMXBean gc); |
|
private native void fillGcAttributeInfo(GarbageCollectorMXBean gc, |
|
int numAttributes, |
|
String[] attributeNames, |
|
char[] types, |
|
String[] descriptions); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private native GcInfo getLastGcInfo0(GarbageCollectorMXBean gc, |
|
int numExtAtts, |
|
Object[] extAttValues, |
|
char[] extAttTypes, |
|
MemoryUsage[] before, |
|
MemoryUsage[] after); |
|
} |