# HG changeset patch # User pliden # Date 1396514367 -7200 # Node ID fd8ddf2d2f6b4646f2fd52992843e98b4bd5f40e # Parent 5cf196cc540570c2b5bcfe9860eab182c024cf2b 8038461: Test gc/g1/TestStringDeduplicationMemoryUsage.java fails with unexpected memory usage Reviewed-by: jmasa, sjohanss diff -r 5cf196cc5405 -r fd8ddf2d2f6b test/gc/g1/TestStringDeduplicationTools.java --- a/test/gc/g1/TestStringDeduplicationTools.java Sat Apr 05 23:38:24 2014 -0700 +++ b/test/gc/g1/TestStringDeduplicationTools.java Thu Apr 03 10:39:27 2014 +0200 @@ -310,7 +310,9 @@ } System.gc(); + System.out.println("Heap Memory Usage: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()); + System.out.println("Array Header Size: " + unsafe.ARRAY_CHAR_BASE_OFFSET); System.out.println("End: MemoryUsageTest"); } @@ -482,31 +484,40 @@ public static void testMemoryUsage() throws Exception { // Test that memory usage is reduced after deduplication OutputAnalyzer output; - final String usagePattern = "Heap Memory Usage: (\\d+)"; + final String heapMemoryUsagePattern = "Heap Memory Usage: (\\d+)"; + final String arrayHeaderSizePattern = "Array Header Size: (\\d+)"; // Run without deduplication output = MemoryUsageTest.run(false); output.shouldHaveExitValue(0); - final long memoryUsageWithoutDedup = Long.parseLong(output.firstMatch(usagePattern, 1)); + final long heapMemoryUsageWithoutDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); + final long arrayHeaderSizeWithoutDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); // Run with deduplication output = MemoryUsageTest.run(true); output.shouldHaveExitValue(0); - final long memoryUsageWithDedup = Long.parseLong(output.firstMatch(usagePattern, 1)); + final long heapMemoryUsageWithDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); + final long arrayHeaderSizeWithDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); + + // Sanity check to make sure one instance isn't using compressed class pointers and the other not + if (arrayHeaderSizeWithoutDedup != arrayHeaderSizeWithDedup) { + throw new Exception("Unexpected difference between array header sizes"); + } // Calculate expected memory usage with deduplication enabled. This calculation does // not take alignment and padding into account, so it's a conservative estimate. - final long sizeOfChar = 2; // bytes - final long bytesSaved = (LargeNumberOfStrings - 1) * (StringLength * sizeOfChar + unsafe.ARRAY_CHAR_BASE_OFFSET); - final long memoryUsageWithDedupExpected = memoryUsageWithoutDedup - bytesSaved; + final long sizeOfChar = unsafe.ARRAY_CHAR_INDEX_SCALE; + final long sizeOfCharArray = StringLength * sizeOfChar + arrayHeaderSizeWithoutDedup; + final long bytesSaved = (LargeNumberOfStrings - 1) * sizeOfCharArray; + final long heapMemoryUsageWithDedupExpected = heapMemoryUsageWithoutDedup - bytesSaved; System.out.println("Memory usage summary:"); - System.out.println(" memoryUsageWithoutDedup: " + memoryUsageWithoutDedup); - System.out.println(" memoryUsageWithDedup: " + memoryUsageWithDedup); - System.out.println(" memoryUsageWithDedupExpected: " + memoryUsageWithDedupExpected); + System.out.println(" heapMemoryUsageWithoutDedup: " + heapMemoryUsageWithoutDedup); + System.out.println(" heapMemoryUsageWithDedup: " + heapMemoryUsageWithDedup); + System.out.println(" heapMemoryUsageWithDedupExpected: " + heapMemoryUsageWithDedupExpected); - if (memoryUsageWithDedup > memoryUsageWithDedupExpected) { - throw new Exception("Unexpected memory usage, memoryUsageWithDedup should less or equal to memoryUsageWithDedupExpected"); + if (heapMemoryUsageWithDedup > heapMemoryUsageWithDedupExpected) { + throw new Exception("Unexpected memory usage, heapMemoryUsageWithDedup should be less or equal to heapMemoryUsageWithDedupExpected"); } } }