test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java
changeset 50113 caf115bb98ad
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package jdk.jfr.event.gc.heapsummary;
       
    27 
       
    28 import java.time.Duration;
       
    29 import java.util.List;
       
    30 
       
    31 import jdk.jfr.Recording;
       
    32 import jdk.jfr.consumer.RecordedEvent;
       
    33 import jdk.test.lib.Asserts;
       
    34 import jdk.test.lib.jfr.EventNames;
       
    35 import jdk.test.lib.jfr.Events;
       
    36 import jdk.test.lib.jfr.GCHelper;
       
    37 
       
    38 public class HeapSummaryEventAllGcs {
       
    39 
       
    40     public static void test(String expectedYoungCollector, String expectedOldCollector) throws Exception {
       
    41         Recording recording = new Recording();
       
    42         recording.enable(EventNames.GCConfiguration);
       
    43         recording.enable(EventNames.GCHeapSummary);
       
    44         recording.enable(EventNames.PSHeapSummary);
       
    45         recording.enable(EventNames.MetaspaceSummary).withThreshold(Duration.ofMillis(0));
       
    46 
       
    47         recording.start();
       
    48         // To eliminate the risk of being in the middle of a GC when the recording starts/stops,
       
    49         // we run 5 System.gc() and ignores the first and last GC.
       
    50         GCHelper.callSystemGc(5, true);
       
    51         recording.stop();
       
    52 
       
    53         if (!checkCollectors(recording, expectedYoungCollector, expectedOldCollector)) {
       
    54             return;
       
    55         }
       
    56         List<RecordedEvent> events = GCHelper.removeFirstAndLastGC(Events.fromRecording(recording));
       
    57         for (RecordedEvent event : events) {
       
    58             System.out.println("Event:" + event);
       
    59         }
       
    60 
       
    61         Asserts.assertFalse(events.isEmpty(), "Expected at least one event.");
       
    62         Asserts.assertEquals(events.size() % 2, 0, "Events should come in pairs");
       
    63 
       
    64         int lastHeapGcId = -1;
       
    65         int lastPSGcId = -1;
       
    66         int lastMetaspaceGcId = -1;
       
    67 
       
    68         for (RecordedEvent event : events) {
       
    69             final String eventName = event.getEventType().getName();
       
    70             switch (eventName) {
       
    71                 case EventNames.GCHeapSummary:
       
    72                     lastHeapGcId = checkGcId(event, lastHeapGcId);
       
    73                     checkHeapEventContent(event);
       
    74                     break;
       
    75                 case EventNames.PSHeapSummary:
       
    76                     lastPSGcId = checkGcId(event, lastPSGcId);
       
    77                     checkPSEventContent(event);
       
    78                     break;
       
    79                 case EventNames.MetaspaceSummary:
       
    80                     lastMetaspaceGcId = checkGcId(event, lastMetaspaceGcId);
       
    81                     checkMetaspaceEventContent(event);
       
    82                     break;
       
    83                 default:
       
    84                     System.out.println("Failed event: " + event);
       
    85                     Asserts.fail("Unknown event type: " + eventName);
       
    86             }
       
    87         }
       
    88 
       
    89         // Sanity check. Not complete.
       
    90         Asserts.assertEquals(lastHeapGcId, lastMetaspaceGcId, "Should have gotten perm gen events for all GCs");
       
    91     }
       
    92 
       
    93     private static void checkMetaspaceEventContent(RecordedEvent event) {
       
    94         long totalUsed = Events.assertField(event, "metaspace.used").atLeast(0L).getValue();
       
    95         long totalCommitted = Events.assertField(event, "metaspace.committed").atLeast(totalUsed).getValue();
       
    96         long totalReserved = Events.assertField(event, "metaspace.reserved").atLeast(totalCommitted).getValue();
       
    97 
       
    98         long dataUsed = Events.assertField(event, "dataSpace.used").atLeast(0L).getValue();
       
    99         long dataCommitted = Events.assertField(event, "dataSpace.committed").atLeast(dataUsed).getValue();
       
   100         long dataReserved = Events.assertField(event, "dataSpace.reserved").atLeast(dataCommitted).getValue();
       
   101 
       
   102         long classUsed = Events.assertField(event, "classSpace.used").atLeast(0L).getValue();
       
   103         long classCommitted = Events.assertField(event, "classSpace.committed").atLeast(classUsed).getValue();
       
   104         long classReserved = Events.assertField(event, "classSpace.reserved").atLeast(classCommitted).getValue();
       
   105 
       
   106         Asserts.assertEquals(dataCommitted + classCommitted, totalCommitted, "Wrong committed memory");
       
   107         Asserts.assertEquals(dataUsed + classUsed, totalUsed, "Wrong used memory");
       
   108         Asserts.assertEquals(dataReserved + classReserved, totalReserved, "Wrong reserved memory");
       
   109     }
       
   110 
       
   111     private static int checkGcId(RecordedEvent event, int currGcId) {
       
   112         int gcId = Events.assertField(event, "gcId").getValue();
       
   113         String when = Events.assertField(event, "when").notEmpty().getValue();
       
   114         if ("Before GC".equals(when)) {
       
   115             Asserts.assertGreaterThan(gcId, currGcId, "gcId should be increasing");
       
   116         } else {
       
   117             Asserts.assertEquals(gcId, currGcId, "After should have same gcId as last Before event");
       
   118         }
       
   119         return gcId;
       
   120     }
       
   121 
       
   122     private static void checkHeapEventContent(RecordedEvent event) {
       
   123         checkVirtualSpace(event, "heapSpace");
       
   124         long heapUsed = Events.assertField(event, "heapUsed").atLeast(0L).getValue();
       
   125         long start = Events.assertField(event, "heapSpace.start").atLeast(0L).getValue();
       
   126         long committedEnd = Events.assertField(event, "heapSpace.committedEnd").above(start).getValue();
       
   127         Asserts.assertLessThanOrEqual(heapUsed, committedEnd- start, "used can not exceed size");
       
   128     }
       
   129 
       
   130     private static void checkPSEventContent(RecordedEvent event) {
       
   131         checkVirtualSpace(event, "oldSpace");
       
   132         checkVirtualSpace(event, "youngSpace");
       
   133         checkSpace(event, "oldObjectSpace");
       
   134         checkSpace(event, "edenSpace");
       
   135         checkSpace(event, "fromSpace");
       
   136         checkSpace(event, "toSpace");
       
   137 
       
   138         checkPSYoungSizes(event);
       
   139         checkPSYoungStartEnd(event);
       
   140     }
       
   141 
       
   142     private static void checkPSYoungSizes(RecordedEvent event) {
       
   143         long youngSize = (long)Events.assertField(event, "youngSpace.committedEnd").getValue() -
       
   144                         (long)Events.assertField(event, "youngSpace.start").getValue();
       
   145         long edenSize = (long)Events.assertField(event, "edenSpace.end").getValue() -
       
   146                         (long)Events.assertField(event, "edenSpace.start").getValue();
       
   147         long fromSize = (long)Events.assertField(event, "fromSpace.end").getValue() -
       
   148                         (long)Events.assertField(event, "fromSpace.start").getValue();
       
   149         long toSize = (long)Events.assertField(event, "toSpace.end").getValue() -
       
   150                         (long)Events.assertField(event, "toSpace.start").getValue();
       
   151         Asserts.assertGreaterThanOrEqual(youngSize, edenSize + fromSize + toSize, "Young sizes don't match");
       
   152     }
       
   153 
       
   154     private static void checkPSYoungStartEnd(RecordedEvent event) {
       
   155         long oldEnd = Events.assertField(event, "oldSpace.reservedEnd").getValue();
       
   156         long youngStart = Events.assertField(event, "youngSpace.start").getValue();
       
   157         long youngEnd = Events.assertField(event, "youngSpace.committedEnd").getValue();
       
   158         long edenStart = Events.assertField(event, "edenSpace.start").getValue();
       
   159         long edenEnd = Events.assertField(event, "edenSpace.end").getValue();
       
   160         long fromStart = Events.assertField(event, "fromSpace.start").getValue();
       
   161         long fromEnd = Events.assertField(event, "fromSpace.end").getValue();
       
   162         long toStart = Events.assertField(event, "toSpace.start").getValue();
       
   163         long toEnd = Events.assertField(event, "toSpace.end").getValue();
       
   164         Asserts.assertEquals(oldEnd, youngStart, "Young should start where old ends");
       
   165         Asserts.assertEquals(youngStart, edenStart, "Eden should be placed first in young");
       
   166         if (fromStart < toStart) {
       
   167             // [eden][from][to]
       
   168             Asserts.assertGreaterThanOrEqual(fromStart, edenEnd, "From should start after eden");
       
   169             Asserts.assertLessThanOrEqual(fromEnd, toStart, "To should start after From");
       
   170             Asserts.assertLessThanOrEqual(toEnd, youngEnd, "To should start after From");
       
   171         } else {
       
   172             // [eden][to][from]
       
   173             Asserts.assertGreaterThanOrEqual(toStart, edenEnd, "From should start after eden");
       
   174             Asserts.assertLessThanOrEqual(toEnd, fromStart, "To should start after From");
       
   175             Asserts.assertLessThanOrEqual(fromEnd, youngEnd, "To should start after From");
       
   176         }
       
   177     }
       
   178 
       
   179     private static void checkVirtualSpace(RecordedEvent event, String structName) {
       
   180         long start = Events.assertField(event, structName + ".start").atLeast(0L).getValue();
       
   181         long committedEnd = Events.assertField(event, structName + ".committedEnd").above(start).getValue();
       
   182         Events.assertField(event, structName + ".reservedEnd").atLeast(committedEnd);
       
   183         long committedSize = Events.assertField(event, structName + ".committedSize").atLeast(0L).getValue();
       
   184         Events.assertField(event, structName + ".reservedSize").atLeast(committedSize);
       
   185     }
       
   186 
       
   187     private static void checkSpace(RecordedEvent event, String structName) {
       
   188         long start = Events.assertField(event, structName + ".start").atLeast(0L).getValue();
       
   189         long end = Events.assertField(event, structName + ".end").above(start).getValue();
       
   190         long used =  Events.assertField(event, structName + ".used").atLeast(0L).getValue();
       
   191         long size = Events.assertField(event, structName + ".size").atLeast(used).getValue();
       
   192         Asserts.assertEquals(size, end - start, "Size mismatch");
       
   193     }
       
   194 
       
   195     private static boolean checkCollectors(Recording recording, String expectedYoung, String expectedOld) throws Exception {
       
   196         for (RecordedEvent event : Events.fromRecording(recording)) {
       
   197             if (Events.isEventType(event, EventNames.GCConfiguration)) {
       
   198                 final String young = Events.assertField(event, "youngCollector").notEmpty().getValue();
       
   199                 final String old = Events.assertField(event, "oldCollector").notEmpty().getValue();
       
   200                 if (young.equals(expectedYoung) && old.equals(expectedOld)) {
       
   201                     return true;
       
   202                 }
       
   203                 // TODO: We treat wrong collector types as an error. Old test only warned. Not sure what is correct.
       
   204                 Asserts.fail(String.format("Wrong collector types: got('%s','%s'), expected('%s','%s')",
       
   205                 young, old, expectedYoung, expectedOld));
       
   206             }
       
   207         }
       
   208         Asserts.fail("Missing event type " + EventNames.GCConfiguration);
       
   209         return false;
       
   210     }
       
   211 }