287 Object beforeInternedValue = getValue(dupString2); 288 String internedString = dupString2.intern(); 289 if (internedString != dupString2) { 290 throw new RuntimeException("String should match"); 291 } 292 if (getValue(internedString) != getValue(baseString)) { 293 throw new RuntimeException("Values should match"); 294 } 295 296 // Check original value of interned string, to make sure 297 // deduplication happened on the interned string and not 298 // on the base string 299 if (beforeInternedValue == getValue(baseString)) { 300 throw new RuntimeException("Values should not match"); 301 } 302 303 System.out.println("End: InternedTest"); 304 } 305 306 public static OutputAnalyzer run() throws Exception { 307 return runTest("-XX:+PrintGC", 308 "-XX:+PrintGCDetails", 309 "-XX:+UseStringDeduplication", 310 "-XX:+PrintStringDeduplicationStatistics", 311 "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold, 312 InternedTest.class.getName(), 313 "" + DefaultAgeThreshold); 314 } 315 } 316 317 /* 318 * Tests 319 */ 320 321 private static final int LargeNumberOfStrings = 10000; 322 private static final int SmallNumberOfStrings = 10; 323 324 private static final int MaxAgeThreshold = 15; 325 private static final int DefaultAgeThreshold = 3; 326 private static final int MinAgeThreshold = 1; 327 328 private static final int TooLowAgeThreshold = MinAgeThreshold - 1; 329 private static final int TooHighAgeThreshold = MaxAgeThreshold + 1; 330 331 public static void testYoungGC() throws Exception { 332 // Do young GC to age strings to provoke deduplication 333 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 334 DefaultAgeThreshold, 335 YoungGC, 336 "-XX:+PrintGC", 337 "-XX:+PrintStringDeduplicationStatistics"); 338 output.shouldNotContain("Full GC"); 339 output.shouldContain("GC pause (G1 Evacuation Pause) (young)"); 340 output.shouldContain("GC concurrent-string-deduplication"); 341 output.shouldContain("Deduplicated:"); 342 output.shouldHaveExitValue(0); 343 } 344 345 public static void testFullGC() throws Exception { 346 // Do full GC to age strings to provoke deduplication 347 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 348 DefaultAgeThreshold, 349 FullGC, 350 "-XX:+PrintGC", 351 "-XX:+PrintStringDeduplicationStatistics"); 352 output.shouldNotContain("GC pause (G1 Evacuation Pause) (young)"); 353 output.shouldContain("Full GC"); 354 output.shouldContain("GC concurrent-string-deduplication"); 355 output.shouldContain("Deduplicated:"); 356 output.shouldHaveExitValue(0); 357 } 358 359 public static void testTableResize() throws Exception { 360 // Test with StringDeduplicationResizeALot 361 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 362 DefaultAgeThreshold, 363 YoungGC, 364 "-XX:+PrintGC", 365 "-XX:+PrintStringDeduplicationStatistics", 366 "-XX:+StringDeduplicationResizeALot"); 367 output.shouldContain("GC concurrent-string-deduplication"); 368 output.shouldContain("Deduplicated:"); 369 output.shouldNotContain("Resize Count: 0"); 370 output.shouldHaveExitValue(0); 371 } 372 373 public static void testTableRehash() throws Exception { 374 // Test with StringDeduplicationRehashALot 375 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 376 DefaultAgeThreshold, 377 YoungGC, 378 "-XX:+PrintGC", 379 "-XX:+PrintStringDeduplicationStatistics", 380 "-XX:+StringDeduplicationRehashALot"); 381 output.shouldContain("GC concurrent-string-deduplication"); 382 output.shouldContain("Deduplicated:"); 383 output.shouldNotContain("Rehash Count: 0"); 384 output.shouldNotContain("Hash Seed: 0x0"); 385 output.shouldHaveExitValue(0); 386 } 387 388 public static void testAgeThreshold() throws Exception { 389 OutputAnalyzer output; 390 391 // Test with max age theshold 392 output = DeduplicationTest.run(SmallNumberOfStrings, 393 MaxAgeThreshold, 394 YoungGC, 395 "-XX:+PrintGC", 396 "-XX:+PrintStringDeduplicationStatistics"); 397 output.shouldContain("GC concurrent-string-deduplication"); 398 output.shouldContain("Deduplicated:"); 399 output.shouldHaveExitValue(0); 400 401 // Test with min age theshold 402 output = DeduplicationTest.run(SmallNumberOfStrings, 403 MinAgeThreshold, 404 YoungGC, 405 "-XX:+PrintGC", 406 "-XX:+PrintStringDeduplicationStatistics"); 407 output.shouldContain("GC concurrent-string-deduplication"); 408 output.shouldContain("Deduplicated:"); 409 output.shouldHaveExitValue(0); 410 411 // Test with too low age threshold 412 output = DeduplicationTest.run(SmallNumberOfStrings, 413 TooLowAgeThreshold, 414 YoungGC); 415 output.shouldContain("outside the allowed range"); 416 output.shouldHaveExitValue(1); 417 418 // Test with too high age threshold 419 output = DeduplicationTest.run(SmallNumberOfStrings, 420 TooHighAgeThreshold, 421 YoungGC); 422 output.shouldContain("outside the allowed range"); 423 output.shouldHaveExitValue(1); 424 } 425 426 public static void testPrintOptions() throws Exception { 427 OutputAnalyzer output; 428 429 // Test without PrintGC and without PrintStringDeduplicationStatistics 430 output = DeduplicationTest.run(SmallNumberOfStrings, 431 DefaultAgeThreshold, 432 YoungGC); 433 output.shouldNotContain("GC concurrent-string-deduplication"); 434 output.shouldNotContain("Deduplicated:"); 435 output.shouldHaveExitValue(0); 436 437 // Test with PrintGC but without PrintStringDeduplicationStatistics 438 output = DeduplicationTest.run(SmallNumberOfStrings, 439 DefaultAgeThreshold, 440 YoungGC, 441 "-XX:+PrintGC"); 442 output.shouldContain("GC concurrent-string-deduplication"); 443 output.shouldNotContain("Deduplicated:"); 444 output.shouldHaveExitValue(0); 445 } 446 447 public static void testInterned() throws Exception { 448 // Test that interned strings are deduplicated before being interned 449 OutputAnalyzer output = InternedTest.run(); 450 output.shouldHaveExitValue(0); 451 } 452 } | 287 Object beforeInternedValue = getValue(dupString2); 288 String internedString = dupString2.intern(); 289 if (internedString != dupString2) { 290 throw new RuntimeException("String should match"); 291 } 292 if (getValue(internedString) != getValue(baseString)) { 293 throw new RuntimeException("Values should match"); 294 } 295 296 // Check original value of interned string, to make sure 297 // deduplication happened on the interned string and not 298 // on the base string 299 if (beforeInternedValue == getValue(baseString)) { 300 throw new RuntimeException("Values should not match"); 301 } 302 303 System.out.println("End: InternedTest"); 304 } 305 306 public static OutputAnalyzer run() throws Exception { 307 return runTest("-Xlog:gc=debug,gc+stringdedup=trace", 308 "-XX:+UseStringDeduplication", 309 "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold, 310 InternedTest.class.getName(), 311 "" + DefaultAgeThreshold); 312 } 313 } 314 315 /* 316 * Tests 317 */ 318 319 private static final int LargeNumberOfStrings = 10000; 320 private static final int SmallNumberOfStrings = 10; 321 322 private static final int MaxAgeThreshold = 15; 323 private static final int DefaultAgeThreshold = 3; 324 private static final int MinAgeThreshold = 1; 325 326 private static final int TooLowAgeThreshold = MinAgeThreshold - 1; 327 private static final int TooHighAgeThreshold = MaxAgeThreshold + 1; 328 329 public static void testYoungGC() throws Exception { 330 // Do young GC to age strings to provoke deduplication 331 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 332 DefaultAgeThreshold, 333 YoungGC, 334 "-Xlog:gc,gc+stringdedup=trace"); 335 output.shouldNotContain("Full GC"); 336 output.shouldContain("Pause Young (G1 Evacuation Pause)"); 337 output.shouldContain("Concurrent String Deduplication"); 338 output.shouldContain("Deduplicated:"); 339 output.shouldHaveExitValue(0); 340 } 341 342 public static void testFullGC() throws Exception { 343 // Do full GC to age strings to provoke deduplication 344 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 345 DefaultAgeThreshold, 346 FullGC, 347 "-Xlog:gc,gc+stringdedup=trace"); 348 output.shouldNotContain("Pause Young (G1 Evacuation Pause)"); 349 output.shouldContain("Full GC"); 350 output.shouldContain("Concurrent String Deduplication"); 351 output.shouldContain("Deduplicated:"); 352 output.shouldHaveExitValue(0); 353 } 354 355 public static void testTableResize() throws Exception { 356 // Test with StringDeduplicationResizeALot 357 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 358 DefaultAgeThreshold, 359 YoungGC, 360 "-Xlog:gc,gc+stringdedup=trace", 361 "-XX:+StringDeduplicationResizeALot"); 362 output.shouldContain("Concurrent String Deduplication"); 363 output.shouldContain("Deduplicated:"); 364 output.shouldNotContain("Resize Count: 0"); 365 output.shouldHaveExitValue(0); 366 } 367 368 public static void testTableRehash() throws Exception { 369 // Test with StringDeduplicationRehashALot 370 OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings, 371 DefaultAgeThreshold, 372 YoungGC, 373 "-Xlog:gc,gc+stringdedup=trace", 374 "-XX:+StringDeduplicationRehashALot"); 375 output.shouldContain("Concurrent String Deduplication"); 376 output.shouldContain("Deduplicated:"); 377 output.shouldNotContain("Rehash Count: 0"); 378 output.shouldNotContain("Hash Seed: 0x0"); 379 output.shouldHaveExitValue(0); 380 } 381 382 public static void testAgeThreshold() throws Exception { 383 OutputAnalyzer output; 384 385 // Test with max age theshold 386 output = DeduplicationTest.run(SmallNumberOfStrings, 387 MaxAgeThreshold, 388 YoungGC, 389 "-Xlog:gc,gc+stringdedup=trace"); 390 output.shouldContain("Concurrent String Deduplication"); 391 output.shouldContain("Deduplicated:"); 392 output.shouldHaveExitValue(0); 393 394 // Test with min age theshold 395 output = DeduplicationTest.run(SmallNumberOfStrings, 396 MinAgeThreshold, 397 YoungGC, 398 "-Xlog:gc,gc+stringdedup=trace"); 399 output.shouldContain("Concurrent String Deduplication"); 400 output.shouldContain("Deduplicated:"); 401 output.shouldHaveExitValue(0); 402 403 // Test with too low age threshold 404 output = DeduplicationTest.run(SmallNumberOfStrings, 405 TooLowAgeThreshold, 406 YoungGC); 407 output.shouldContain("outside the allowed range"); 408 output.shouldHaveExitValue(1); 409 410 // Test with too high age threshold 411 output = DeduplicationTest.run(SmallNumberOfStrings, 412 TooHighAgeThreshold, 413 YoungGC); 414 output.shouldContain("outside the allowed range"); 415 output.shouldHaveExitValue(1); 416 } 417 418 public static void testPrintOptions() throws Exception { 419 OutputAnalyzer output; 420 421 // Test without -Xlog:gc 422 output = DeduplicationTest.run(SmallNumberOfStrings, 423 DefaultAgeThreshold, 424 YoungGC); 425 output.shouldNotContain("Concurrent String Deduplication"); 426 output.shouldNotContain("Deduplicated:"); 427 output.shouldHaveExitValue(0); 428 429 // Test with -Xlog:gc+stringdedup 430 output = DeduplicationTest.run(SmallNumberOfStrings, 431 DefaultAgeThreshold, 432 YoungGC, 433 "-Xlog:gc+stringdedup"); 434 output.shouldContain("Concurrent String Deduplication"); 435 output.shouldNotContain("Deduplicated:"); 436 output.shouldHaveExitValue(0); 437 } 438 439 public static void testInterned() throws Exception { 440 // Test that interned strings are deduplicated before being interned 441 OutputAnalyzer output = InternedTest.run(); 442 output.shouldHaveExitValue(0); 443 } 444 } |