Index: lucene/core/src/java/org/apache/lucene/util/Constants.java =================================================================== --- lucene/core/src/java/org/apache/lucene/util/Constants.java (revision 1300016) +++ lucene/core/src/java/org/apache/lucene/util/Constants.java (working copy) @@ -17,6 +17,8 @@ * limitations under the License. */ +import java.lang.management.ManagementFactory; + import org.apache.lucene.LucenePackage; /** @@ -51,6 +53,7 @@ public static final boolean JRE_IS_64BIT; public static final boolean JRE_IS_MINIMUM_JAVA7; + public static final boolean JRE_USES_COMPRESSED_OOPS; static { // NOTE: this logic may not be correct; if you know of a // more reliable approach please raise it on java-dev! @@ -73,6 +76,26 @@ v7 = false; } JRE_IS_MINIMUM_JAVA7 = v7; + + boolean compressedOops = false; + if (JRE_IS_64BIT) try { + final Class beanClazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean"); + final Object hotSpotBean = ManagementFactory.newPlatformMXBeanProxy( + ManagementFactory.getPlatformMBeanServer(), + "com.sun.management:type=HotSpotDiagnostic", + beanClazz + ); + final Object vmOption = hotSpotBean.getClass().getMethod("getVMOption", String.class) + .invoke(hotSpotBean, "UseCompressedOops"); + compressedOops = Boolean.valueOf( + vmOption.getClass().getMethod("getValue") + .invoke(vmOption).toString() + ).booleanValue(); + } catch (Exception e) { + // if anything fails before, we assume that oops are not compressed + compressedOops = false; + } + JRE_USES_COMPRESSED_OOPS = compressedOops; } // this method prevents inlining the final version constant in compiled classes, Index: lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java =================================================================== --- lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java (revision 1300016) +++ lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java (working copy) @@ -45,7 +45,7 @@ public final static int NUM_BYTES_DOUBLE = 8; public final static int NUM_BYTES_CHAR = 2; public final static int NUM_BYTES_OBJECT_HEADER = 8; - public final static int NUM_BYTES_OBJECT_REF = Constants.JRE_IS_64BIT ? 8 : 4; + public final static int NUM_BYTES_OBJECT_REF = (Constants.JRE_IS_64BIT && !Constants.JRE_USES_COMPRESSED_OOPS) ? 8 : 4; public final static int NUM_BYTES_ARRAY_HEADER = NUM_BYTES_OBJECT_HEADER + NUM_BYTES_INT + NUM_BYTES_OBJECT_REF; private MemoryModel memoryModel; Index: lucene/core/src/test/org/apache/lucene/util/TestRamUsageEstimator.java =================================================================== --- lucene/core/src/test/org/apache/lucene/util/TestRamUsageEstimator.java (revision 1300016) +++ lucene/core/src/test/org/apache/lucene/util/TestRamUsageEstimator.java (working copy) @@ -35,6 +35,21 @@ rue.estimateRamUsage(strings); } + public void testCompressedOops() { + System.out.println("NOTE: This JVM is 64bit: " + Constants.JRE_IS_64BIT); + System.out.println("NOTE: This JVM uses CompressedOops: " + Constants.JRE_USES_COMPRESSED_OOPS); + if (Constants.JRE_IS_64BIT) { + if (Constants.JRE_USES_COMPRESSED_OOPS) { + assertEquals(4, RamUsageEstimator.NUM_BYTES_OBJECT_REF); + } else { + assertEquals(8, RamUsageEstimator.NUM_BYTES_OBJECT_REF); + } + } else { + assertFalse(Constants.JRE_USES_COMPRESSED_OOPS); + assertEquals(4, RamUsageEstimator.NUM_BYTES_OBJECT_REF); + } + } + private static final class Holder { long field1 = 5000L; String name = "name";