288 /** 289 * Tests event stacktrace during metaspace GC threshold if 290 * -XX:+UseParallelGC is used 291 */ 292 public static void testMetaspaceParallelGCAllocEvent() throws Exception { 293 GarbageCollectorMXBean bean = garbageCollectorMXBean("PS MarkSweep"); 294 MemoryAllocator memory = new MetaspaceMemoryAllocator(); 295 296 String[] expectedStack = new String[]{ 297 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 298 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testMetaspaceParallelGCAllocEvent" 299 }; 300 301 testAllocEvent(bean, memory, expectedStack); 302 } 303 304 /** 305 * Tests event stacktrace for young GC if -XX:+UseG1GC is used 306 */ 307 public static void testG1YoungAllocEvent() throws Exception { 308 GarbageCollectorMXBean bean = garbageCollectorMXBean("G1 Young Generation"); 309 MemoryAllocator memory = new EdenMemoryAllocator(); 310 311 String[] expectedStack = new String[]{ 312 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 313 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testG1YoungAllocEvent" 314 }; 315 316 testAllocEvent(bean, memory, expectedStack); 317 } 318 319 /** 320 * Tests event stacktrace for old GC if -XX:+UseG1GC is used 321 */ 322 public static void testG1OldAllocEvent() throws Exception { 323 GarbageCollectorMXBean bean = garbageCollectorMXBean("G1 Old Generation"); 324 MemoryAllocator memory = new OldGenMemoryAllocator(); 325 326 String[] expectedStack = new String[]{ 327 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 328 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testG1OldAllocEvent" 329 }; 330 331 testAllocEvent(bean, memory, expectedStack); 332 } 333 334 /** 335 * Tests event stacktrace during metaspace GC threshold if -XX:+UseG1GC is 336 * used 337 */ 338 public static void testMetaspaceG1GCAllocEvent() throws Exception { 339 GarbageCollectorMXBean bean = garbageCollectorMXBean("G1 Young Generation"); 340 MemoryAllocator memory = new MetaspaceMemoryAllocator(); 341 342 String[] expectedStack = new String[]{ 343 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 344 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testMetaspaceG1GCAllocEvent" 345 }; 346 347 testAllocEvent(bean, memory, expectedStack); 348 } 349 350 /** 351 * Tests event stacktrace for GC caused by humongous allocations if 352 * -XX:+UseG1GC is used 353 */ 354 public static void testG1HumonAllocEvent() throws Exception { 355 // G1 tries to reclaim humongous objects at every young collection 356 // after doing a conservative estimate of its liveness 357 GarbageCollectorMXBean bean = garbageCollectorMXBean("G1 Young Generation"); 358 MemoryAllocator memory = new HumongousMemoryAllocator(); 359 360 String[] expectedStack = new String[]{ 361 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 362 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testG1HumonAllocEvent" 363 }; 364 365 testAllocEvent(bean, memory, expectedStack); 366 } 367 368 private static GarbageCollectorMXBean garbageCollectorMXBean(String name) throws Exception { 369 MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 370 GarbageCollectorMXBean bean = ManagementFactory.newPlatformMXBeanProxy( 371 server, "java.lang:type=GarbageCollector,name=" + name, GarbageCollectorMXBean.class); 372 return bean; 373 } 374 375 /** 376 * Performs JFR recording, GC provocation/detection and stacktrace 377 * verification for JFR event. In case of verification failure 378 * repeats several times. 379 * 380 * @param bean MX bean for desired GC 381 * @param memory allocator for desired type of allocations 382 * @param expectedStack array of expected frames 383 */ 384 private static void testAllocEvent(GarbageCollectorMXBean bean, MemoryAllocator memory, String[] expectedStack) throws Exception { 385 // The test checks the stacktrace of events and expects all the events are fired 386 // in the current thread. But compilation may also trigger GC. 387 // So to filter out such cases the test performs several iterations and expects 388 // that the memory allocations made by the test will produce the desired JFR event. 389 final int iterations = 5; 390 for (int i = 0; i < iterations; i++) { 391 if (allocAndCheck(bean, memory, expectedStack)) { | 288 /** 289 * Tests event stacktrace during metaspace GC threshold if 290 * -XX:+UseParallelGC is used 291 */ 292 public static void testMetaspaceParallelGCAllocEvent() throws Exception { 293 GarbageCollectorMXBean bean = garbageCollectorMXBean("PS MarkSweep"); 294 MemoryAllocator memory = new MetaspaceMemoryAllocator(); 295 296 String[] expectedStack = new String[]{ 297 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 298 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testMetaspaceParallelGCAllocEvent" 299 }; 300 301 testAllocEvent(bean, memory, expectedStack); 302 } 303 304 /** 305 * Tests event stacktrace for young GC if -XX:+UseG1GC is used 306 */ 307 public static void testG1YoungAllocEvent() throws Exception { 308 GarbageCollectorMXBean bean = g1YoungGarbageCollectorMXBean(); 309 MemoryAllocator memory = new EdenMemoryAllocator(); 310 311 String[] expectedStack = new String[]{ 312 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 313 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testG1YoungAllocEvent" 314 }; 315 316 testAllocEvent(bean, memory, expectedStack); 317 } 318 319 /** 320 * Tests event stacktrace for old/full GC if -XX:+UseG1GC is used 321 */ 322 public static void testG1OldAllocEvent() throws Exception { 323 GarbageCollectorMXBean bean = g1FullGarbageCollectorMXBean(); 324 MemoryAllocator memory = new OldGenMemoryAllocator(); 325 326 String[] expectedStack = new String[]{ 327 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 328 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testG1OldAllocEvent" 329 }; 330 331 testAllocEvent(bean, memory, expectedStack); 332 } 333 334 /** 335 * Tests event stacktrace during metaspace GC threshold if -XX:+UseG1GC is 336 * used 337 */ 338 public static void testMetaspaceG1GCAllocEvent() throws Exception { 339 GarbageCollectorMXBean bean = g1YoungGarbageCollectorMXBean(); 340 MemoryAllocator memory = new MetaspaceMemoryAllocator(); 341 342 String[] expectedStack = new String[]{ 343 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 344 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testMetaspaceG1GCAllocEvent" 345 }; 346 347 testAllocEvent(bean, memory, expectedStack); 348 } 349 350 /** 351 * Tests event stacktrace for GC caused by humongous allocations if 352 * -XX:+UseG1GC is used 353 */ 354 public static void testG1HumonAllocEvent() throws Exception { 355 // G1 tries to reclaim humongous objects at every young collection 356 // after doing a conservative estimate of its liveness 357 GarbageCollectorMXBean bean = g1YoungGarbageCollectorMXBean(); 358 MemoryAllocator memory = new HumongousMemoryAllocator(); 359 360 String[] expectedStack = new String[]{ 361 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testAllocEvent", 362 "jdk.jfr.event.gc.stacktrace.AllocationStackTrace.testG1HumonAllocEvent" 363 }; 364 365 testAllocEvent(bean, memory, expectedStack); 366 } 367 368 private static GarbageCollectorMXBean garbageCollectorMXBean(String name) throws Exception { 369 MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 370 GarbageCollectorMXBean bean; 371 try { 372 bean = ManagementFactory.newPlatformMXBeanProxy(server, 373 "java.lang:type=GarbageCollector,name=" + name, 374 GarbageCollectorMXBean.class); 375 } catch (IllegalArgumentException e) { 376 bean = null; 377 } 378 return bean; 379 } 380 381 private static GarbageCollectorMXBean g1YoungGarbageCollectorMXBean() throws Exception { 382 GarbageCollectorMXBean bean = garbageCollectorMXBean("G1 Young Generation"); 383 if (bean == null) { 384 bean = garbageCollectorMXBean("G1 Young"); 385 } 386 return bean; 387 } 388 389 private static GarbageCollectorMXBean g1FullGarbageCollectorMXBean() throws Exception { 390 GarbageCollectorMXBean bean = garbageCollectorMXBean("G1 Old Generation"); 391 if (bean == null) { 392 bean = garbageCollectorMXBean("G1 Full"); 393 } 394 return bean; 395 } 396 397 /** 398 * Performs JFR recording, GC provocation/detection and stacktrace 399 * verification for JFR event. In case of verification failure 400 * repeats several times. 401 * 402 * @param bean MX bean for desired GC 403 * @param memory allocator for desired type of allocations 404 * @param expectedStack array of expected frames 405 */ 406 private static void testAllocEvent(GarbageCollectorMXBean bean, MemoryAllocator memory, String[] expectedStack) throws Exception { 407 // The test checks the stacktrace of events and expects all the events are fired 408 // in the current thread. But compilation may also trigger GC. 409 // So to filter out such cases the test performs several iterations and expects 410 // that the memory allocations made by the test will produce the desired JFR event. 411 final int iterations = 5; 412 for (int i = 0; i < iterations; i++) { 413 if (allocAndCheck(bean, memory, expectedStack)) { |