Skip to content

Commit

Permalink
Updating RamUsageEstimator with changes related to LUCENE-5086: RamUs…
Browse files Browse the repository at this point in the history
…ageEstimator causes AWT classes to be loaded by calling ManagementFactory#getPlatformMBeanServer
  • Loading branch information
dweiss committed Jul 5, 2013
1 parent 1cd8176 commit bfd0570
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 25 deletions.
26 changes: 22 additions & 4 deletions .classpath
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
2 changes: 2 additions & 0 deletions .settings/org.eclipse.jdt.apt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=false
2 changes: 1 addition & 1 deletion .settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#Mon Mar 19 22:47:48 CET 2012
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.processAnnotations=disabled
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
Expand Down
98 changes: 78 additions & 20 deletions src/main/java/com/carrotsearch/sizeof/RamUsageEstimator.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
* Estimates the size (memory representation) of Java objects.
*
* @see #sizeOf(Object)
* @see #shallowSizeOf(Object)
* @see #shallowSizeOfInstance(Class)
*/
public final class RamUsageEstimator {
/**
Expand Down Expand Up @@ -69,14 +71,14 @@ public String toString() {
/** No instantiation. */
private RamUsageEstimator() {}

private final static int NUM_BYTES_BOOLEAN = 1;
private final static int NUM_BYTES_BYTE = 1;
private final static int NUM_BYTES_CHAR = 2;
private final static int NUM_BYTES_SHORT = 2;
private final static int NUM_BYTES_INT = 4;
private final static int NUM_BYTES_FLOAT = 4;
private final static int NUM_BYTES_LONG = 8;
private final static int NUM_BYTES_DOUBLE = 8;
public final static int NUM_BYTES_BOOLEAN = 1;
public final static int NUM_BYTES_BYTE = 1;
public final static int NUM_BYTES_CHAR = 2;
public final static int NUM_BYTES_SHORT = 2;
public final static int NUM_BYTES_INT = 4;
public final static int NUM_BYTES_FLOAT = 4;
public final static int NUM_BYTES_LONG = 8;
public final static int NUM_BYTES_DOUBLE = 8;

/**
* Number of bytes this jvm uses to represent an object reference.
Expand Down Expand Up @@ -177,7 +179,7 @@ private RamUsageEstimator() {}
// estimateRamUsage().
Method tempObjectFieldOffsetMethod = null;
try {
Method objectFieldOffsetM = unsafeClass.getMethod("objectFieldOffset", Field.class);
final Method objectFieldOffsetM = unsafeClass.getMethod("objectFieldOffset", Field.class);
final Field dummy1Field = DummyTwoLongObject.class.getDeclaredField("dummy1");
final int ofs1 = ((Number) objectFieldOffsetM.invoke(theUnsafe, dummy1Field)).intValue();
final Field dummy2Field = DummyTwoLongObject.class.getDeclaredField("dummy2");
Expand Down Expand Up @@ -213,17 +215,33 @@ private RamUsageEstimator() {}
int objectAlignment = 8;
try {
final Class<?> beanClazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
final Object hotSpotBean = ManagementFactory.newPlatformMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(),
"com.sun.management:type=HotSpotDiagnostic",
beanClazz
);
final Method getVMOptionMethod = beanClazz.getMethod("getVMOption", String.class);
final Object vmOption = getVMOptionMethod.invoke(hotSpotBean, "ObjectAlignmentInBytes");
objectAlignment = Integer.parseInt(
vmOption.getClass().getMethod("getValue").invoke(vmOption).toString()
);
supportedFeatures.add(JvmFeature.OBJECT_ALIGNMENT);
// Try to get the diagnostic mxbean without calling {@link ManagementFactory#getPlatformMBeanServer()}
// which starts AWT thread (and shows junk in the dock) on a Mac:
Object hotSpotBean;
// Java 7+, HotSpot
try {
hotSpotBean = ManagementFactory.class
.getMethod("getPlatformMXBean", Class.class)
.invoke(null, beanClazz);
} catch (Exception e1) {
// Java 6, HotSpot
try {
Class<?> sunMF = Class.forName("sun.management.ManagementFactory");
hotSpotBean = sunMF.getMethod("getDiagnosticMXBean").invoke(null);
} catch (Exception e2) {
// Last resort option is an attempt to get it from ManagementFactory's server anyway (may start AWT).
hotSpotBean = ManagementFactory.newPlatformMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(),
"com.sun.management:type=HotSpotDiagnostic", beanClazz);
}
}
if (hotSpotBean != null) {
final Method getVMOptionMethod = beanClazz.getMethod("getVMOption", String.class);
final Object vmOption = getVMOptionMethod.invoke(hotSpotBean, "ObjectAlignmentInBytes");
objectAlignment = Integer.parseInt(
vmOption.getClass().getMethod("getValue").invoke(vmOption).toString());
supportedFeatures.add(JvmFeature.OBJECT_ALIGNMENT);
}
} catch (Exception e) {
// Ignore.
}
Expand Down Expand Up @@ -280,6 +298,46 @@ public static long alignObjectSize(long size) {
return size - (size % NUM_BYTES_OBJECT_ALIGNMENT);
}

/** Returns the size in bytes of the byte[] object. */
public static long sizeOf(byte[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + arr.length);
}

/** Returns the size in bytes of the boolean[] object. */
public static long sizeOf(boolean[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + arr.length);
}

/** Returns the size in bytes of the char[] object. */
public static long sizeOf(char[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_CHAR * arr.length);
}

/** Returns the size in bytes of the short[] object. */
public static long sizeOf(short[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_SHORT * arr.length);
}

/** Returns the size in bytes of the int[] object. */
public static long sizeOf(int[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_INT * arr.length);
}

/** Returns the size in bytes of the float[] object. */
public static long sizeOf(float[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_FLOAT * arr.length);
}

/** Returns the size in bytes of the long[] object. */
public static long sizeOf(long[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_LONG * arr.length);
}

/** Returns the size in bytes of the double[] object. */
public static long sizeOf(double[] arr) {
return alignObjectSize((long) NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_DOUBLE * arr.length);
}

/**
* Estimates the RAM usage by the given object. It will
* walk the object tree and sum up all referenced objects.
Expand Down

0 comments on commit bfd0570

Please sign in to comment.