comparison test/gc/g1/TestStringDeduplicationTools.java @ 17964:660b3f6bf7d7

8042310: TestStringDeduplicationMemoryUsage test failing Reviewed-by: ehelin, jwilhelm
author pliden
date Fri, 30 May 2014 10:43:51 +0200
parents fd8ddf2d2f6b
children
comparison
equal deleted inserted replaced
17963:f644f1468780 17964:660b3f6bf7d7
292 InternedTest.class.getName(), 292 InternedTest.class.getName(),
293 "" + DefaultAgeThreshold); 293 "" + DefaultAgeThreshold);
294 } 294 }
295 } 295 }
296 296
297 private static class MemoryUsageTest {
298 public static void main(String[] args) {
299 System.out.println("Begin: MemoryUsageTest");
300
301 final boolean useStringDeduplication = Boolean.parseBoolean(args[0]);
302 final int numberOfStrings = LargeNumberOfStrings;
303 final int numberOfUniqueStrings = 1;
304
305 ArrayList<String> list = createStrings(numberOfStrings, numberOfUniqueStrings);
306 forceDeduplication(DefaultAgeThreshold, FullGC);
307
308 if (useStringDeduplication) {
309 verifyStrings(list, numberOfUniqueStrings);
310 }
311
312 System.gc();
313
314 System.out.println("Heap Memory Usage: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed());
315 System.out.println("Array Header Size: " + unsafe.ARRAY_CHAR_BASE_OFFSET);
316
317 System.out.println("End: MemoryUsageTest");
318 }
319
320 public static OutputAnalyzer run(boolean useStringDeduplication) throws Exception {
321 String[] extraArgs = new String[0];
322
323 if (useStringDeduplication) {
324 extraArgs = new String[] {
325 "-XX:+UseStringDeduplication",
326 "-XX:+PrintStringDeduplicationStatistics",
327 "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold
328 };
329 }
330
331 String[] defaultArgs = new String[] {
332 "-XX:+PrintGC",
333 "-XX:+PrintGCDetails",
334 MemoryUsageTest.class.getName(),
335 "" + useStringDeduplication
336 };
337
338 ArrayList<String> args = new ArrayList<String>();
339 args.addAll(Arrays.asList(extraArgs));
340 args.addAll(Arrays.asList(defaultArgs));
341
342 return runTest(args.toArray(new String[args.size()]));
343 }
344 }
345
346 /* 297 /*
347 * Tests 298 * Tests
348 */ 299 */
349 300
350 private static final int LargeNumberOfStrings = 10000; 301 private static final int LargeNumberOfStrings = 10000;
478 public static void testInterned() throws Exception { 429 public static void testInterned() throws Exception {
479 // Test that interned strings are deduplicated before being interned 430 // Test that interned strings are deduplicated before being interned
480 OutputAnalyzer output = InternedTest.run(); 431 OutputAnalyzer output = InternedTest.run();
481 output.shouldHaveExitValue(0); 432 output.shouldHaveExitValue(0);
482 } 433 }
483
484 public static void testMemoryUsage() throws Exception {
485 // Test that memory usage is reduced after deduplication
486 OutputAnalyzer output;
487 final String heapMemoryUsagePattern = "Heap Memory Usage: (\\d+)";
488 final String arrayHeaderSizePattern = "Array Header Size: (\\d+)";
489
490 // Run without deduplication
491 output = MemoryUsageTest.run(false);
492 output.shouldHaveExitValue(0);
493 final long heapMemoryUsageWithoutDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1));
494 final long arrayHeaderSizeWithoutDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1));
495
496 // Run with deduplication
497 output = MemoryUsageTest.run(true);
498 output.shouldHaveExitValue(0);
499 final long heapMemoryUsageWithDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1));
500 final long arrayHeaderSizeWithDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1));
501
502 // Sanity check to make sure one instance isn't using compressed class pointers and the other not
503 if (arrayHeaderSizeWithoutDedup != arrayHeaderSizeWithDedup) {
504 throw new Exception("Unexpected difference between array header sizes");
505 }
506
507 // Calculate expected memory usage with deduplication enabled. This calculation does
508 // not take alignment and padding into account, so it's a conservative estimate.
509 final long sizeOfChar = unsafe.ARRAY_CHAR_INDEX_SCALE;
510 final long sizeOfCharArray = StringLength * sizeOfChar + arrayHeaderSizeWithoutDedup;
511 final long bytesSaved = (LargeNumberOfStrings - 1) * sizeOfCharArray;
512 final long heapMemoryUsageWithDedupExpected = heapMemoryUsageWithoutDedup - bytesSaved;
513
514 System.out.println("Memory usage summary:");
515 System.out.println(" heapMemoryUsageWithoutDedup: " + heapMemoryUsageWithoutDedup);
516 System.out.println(" heapMemoryUsageWithDedup: " + heapMemoryUsageWithDedup);
517 System.out.println(" heapMemoryUsageWithDedupExpected: " + heapMemoryUsageWithDedupExpected);
518
519 if (heapMemoryUsageWithDedup > heapMemoryUsageWithDedupExpected) {
520 throw new Exception("Unexpected memory usage, heapMemoryUsageWithDedup should be less or equal to heapMemoryUsageWithDedupExpected");
521 }
522 }
523 } 434 }