/* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ import java.util.ArrayList; import java.util.List; import java.util.HashMap; import jrockit.jfr.TestRecording; import oracle.jrockit.jfr.parser.FLREvent; import oracle.jrockit.jfr.parser.FLRStruct; import static jrockit.Asserts.*; /* * @test TestHeapSummaryEventConcurrentCMS * @key jfr * @library ../common * @run main/othervm -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps TestHeapSummaryEventConcurrentCMS */ public class TestHeapSummaryEventConcurrentCMS { private static final String gcPath = "vm/gc/collector/garbage_collection"; private static final String heapSummaryPath = "vm/gc/heap/summary"; private static final String cmsGCName = "ConcurrentMarkSweep"; public static void main(String[] args) throws Exception { TestRecording r = new TestRecording(); try { enableEvent(r, heapSummaryPath); enableEvent(r, gcPath); r.start(); // Need to two GCs in order to ensure at least one heap summary // event from a concurrent CMS cycle System.gc(); System.gc(); r.stop(); List allEvents = getAllEvents(r); List gcEvents = filterEventsOnPath(allEvents, gcPath); assertTrue(gcEvents.size() > 0, "Expected at least one " + gcPath + " event"); List heapSummaryEvents = filterEventsOnPath(allEvents, heapSummaryPath); assertTrue(heapSummaryEvents.size() > 0, "Expected at least one " + heapSummaryPath + " event"); List cmsEvents = filterGCEventsOnCollector(gcEvents, cmsGCName); assertTrue(cmsEvents.size() > 0, "Expected at least one " + gcPath + " event for collector " + cmsGCName); List cmsGCIds = mapGCEventsToGCIds(cmsEvents); List cmsHeapSummaryEvents = filterHeapSummaryEventsOnGCIds(heapSummaryEvents, cmsGCIds); HashMap gcIdToHeapSummaryBefore = mapGCIdToHeapSummary("Before GC", cmsHeapSummaryEvents); HashMap gcIdToHeapSummaryAfter = mapGCIdToHeapSummary("After GC", cmsHeapSummaryEvents); for (Integer gcId : cmsGCIds) { assertTrue(gcIdToHeapSummaryBefore.get(gcId) != null, "Expected a " + heapSummaryPath + " event before " + gcPath + " event with id " + gcId); assertTrue(gcIdToHeapSummaryAfter.get(gcId) != null, "Expected a " + heapSummaryPath + " event after " + gcPath + " event with id " + gcId); } int numHeapSummaryBefore = gcIdToHeapSummaryBefore.size(); int numHeapSummaryAfter = gcIdToHeapSummaryAfter.size(); if (numHeapSummaryBefore != numHeapSummaryAfter) { // Can happen if the last System.gc() did not send a // vm/gc/collector/garbage_collection event assertTrue(numHeapSummaryBefore == numHeapSummaryAfter + 1, "Expected at most one more " + heapSummaryPath); FLREvent last = heapSummaryEvents.get(heapSummaryEvents.size() - 1); assertFalse(cmsGCIds.contains(getGCId(last)), "Expected the last " + heapSummaryPath + " event to not " + "have a corresponding " + gcPath + " event"); } } catch (Throwable t) { r.copyTo("TestHeapSummaryEventConcurrentCMS.jfr"); throw t; } finally { r.close(); } } private static void enableEvent(TestRecording r, String path) throws Exception { r.createJVMSetting(path, true, false, 0, 0); } private static List getAllEvents(TestRecording r) throws Exception { return r.parser().findJVMEvents(".*"); } private static List filterEventsOnPath(List events, String path) throws Exception { List result = new ArrayList(); for (FLREvent e : events) { if (e.getPath().equals(path)) { result.add(e); } } return result; } private static List filterGCEventsOnCollector(List events, String gcName) throws Exception { List result = new ArrayList(); for (FLREvent e : events) { if (getGCName(e).equals(gcName)) { result.add(e); } } return result; } private static List mapGCEventsToGCIds(List events) throws Exception { List result = new ArrayList(); for (FLREvent e : events) { result.add((Integer) e.getValue("gcId")); } return result; } private static List filterHeapSummaryEventsOnGCIds(List events, List gcIds) throws Exception { List result = new ArrayList(); for (FLREvent e : events) { Integer gcId = (Integer) e.getValue("gcId"); if (gcIds.contains(gcId)) { result.add(e); } } return result; } private static HashMap mapGCIdToHeapSummary(String when, List events) throws Exception { HashMap map = new HashMap(); for (FLREvent e : events) { if (getWhen(e).equals(when)) { map.put(getGCId(e), e); } } return map; } private static String getWhen(FLREvent e) throws Exception { FLRStruct s = (FLRStruct) e.getResolvedValue("when"); return (String) s.getValue("when"); } private static String getGCName(FLREvent e) throws Exception { FLRStruct s = (FLRStruct) e.getResolvedValue("name"); String ret = (String) s.getValue("name"); return ret; } private static Integer getGCId(FLREvent e) throws Exception { return (Integer) e.getValue("gcId"); } }