1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 */ 5 6 import java.util.ArrayList; 7 import java.util.HashSet; 8 import java.util.List; 9 import java.util.Random; 10 import java.util.Set; 11 import java.util.regex.Pattern; 12 import jrockit.Asserts; 13 import jrockit.jfr.TestRecording; 14 import oracle.jrockit.jfr.parser.FLREvent; 15 import static jrockit.Asserts.*; 16 17 /* 18 * @test 19 * @key jfr 20 * @library ../common 21 * @build jrockit.jfr.ParseHelper 22 * @run main/othervm -XX:G1HeapRegionSize=1m -Xmx64m -Xmn16m -XX:+UnlockCommercialFeatures -XX:+UseG1GC -XX:+FlightRecorder -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps TestEvacuationInfoEvent 23 */ 24 public class TestEvacuationInfoEvent { 25 private final static String EVENT_INFO_PATH = "vm/gc/detailed/evacuation_info"; 26 private final static String EVENT_FAILED_PATH = "vm/gc/detailed/evacuation_failed"; 27 28 public static List<DummyObject> dummyList; 29 30 public static void main(String[] args) throws Throwable { 31 TestRecording r = new TestRecording(); 32 final long g1HeapRegionSize = 1024 * 1024; 33 try { 34 r.createJVMSetting(EVENT_INFO_PATH, true, false, 0, 0); 35 r.createJVMSetting(EVENT_FAILED_PATH, true, false, 0, 0); 36 r.start(); 37 allocate(); 38 r.stop(); 39 String regexpPattern = String.format("(%s)|(%s)", EVENT_INFO_PATH, EVENT_FAILED_PATH); 40 List<FLREvent> all = r.parser().findJVMEvents(Pattern.compile(regexpPattern)); 41 Asserts.assertFalse(all.isEmpty(), String.format("No events of type '%s' found", EVENT_INFO_PATH)); 42 43 // Save gcIds for all EvacuationFailedEvents. These will be used to verify the EvacuationInfo event. 44 Set<Long> failedEvacuationGcIds = new HashSet<Long>(); 45 for (FLREvent event : all) { 46 if (EVENT_FAILED_PATH.equals(event.getPath())) { 47 failedEvacuationGcIds.add((Long)event.getValue("gcId")); 48 } 49 } 50 51 for (FLREvent event : all) { 52 if (EVENT_INFO_PATH.equals(event.getPath())) { 53 int setRegions = ((Integer)event.getValue("cSetRegions")).intValue(); 54 long setUsedBefore = ((Long)event.getValue("cSetUsedBefore")).longValue(); 55 long setUsedAfter = ((Long)event.getValue("cSetUsedAfter")).longValue(); 56 int allocationRegions = ((Integer)event.getValue("allocationRegions")).intValue(); 57 long allocRegionsUsedBefore = ((Long)event.getValue("allocRegionsUsedBefore")).longValue(); 58 long allocRegionsUsedAfter = ((Long)event.getValue("allocRegionsUsedAfter")).longValue(); 59 long bytesCopied = ((Long)event.getValue("bytesCopied")).longValue(); 60 int regionsFreed = ((Integer)event.getValue("regionsFreed")).intValue(); 61 62 try { 63 assertGreaterOrEqualThan(setRegions, 0, "setRegions >= 0"); 64 assertGreaterOrEqualThan(setUsedBefore, 0L, "setUsedBefore>= 0"); 65 assertGreaterOrEqualThan(setUsedAfter, 0L, "setUsedAfter >= 0"); 66 assertGreaterOrEqualThan(allocationRegions, 0, "allocationRegions >= 0"); 67 assertGreaterOrEqualThan(allocRegionsUsedBefore, 0L, "allocRegionsUsedBefore >= 0"); 68 assertGreaterOrEqualThan(allocRegionsUsedAfter, 0L, "allocRegionsUsedAfter >= 0"); 69 assertGreaterOrEqualThan(bytesCopied, 0L, "bytesCopied >= 0"); 70 assertGreaterOrEqualThan(regionsFreed, 0, "regionsFreed >= 0"); 71 72 assertGreaterOrEqualThan(setUsedBefore, setUsedAfter, "setUsedBefore >= setUsedAfter"); 73 assertEquals(allocRegionsUsedBefore + bytesCopied, allocRegionsUsedAfter, "allocRegionsUsedBefore + bytesCopied = allocRegionsUsedAfter"); 74 assertGreaterOrEqualThan(setRegions, regionsFreed, "setRegions >= regionsFreed"); 75 assertGreaterOrEqualThan(g1HeapRegionSize * allocationRegions, allocRegionsUsedAfter, "G1HeapRegionSize * allocationRegions >= allocationRegionsUsedAfter"); 76 assertGreaterOrEqualThan(g1HeapRegionSize * setRegions, setUsedAfter, "G1HeapRegionSize * setRegions >= setUsedAfter"); 77 assertGreaterOrEqualThan(g1HeapRegionSize * setRegions, setUsedBefore, "G1HeapRegionSize * setRegions >= setUsedBefore"); 78 assertGreaterOrEqualThan(g1HeapRegionSize, allocRegionsUsedBefore, "G1HeapRegionSize >= allocRegionsUsedBefore"); 79 if (failedEvacuationGcIds.contains((Long)event.getValue("gcId"))) { 80 assertGreaterThan(setUsedAfter, 0L, "EvacuationFailure -> setUsedAfter > 0"); 81 assertGreaterThan(setRegions, regionsFreed, "EvacuationFailure -> setRegions > regionsFreed"); 82 } else { 83 assertEquals(setUsedAfter, 0L, "No EvacuationFailure -> setUsedAfter = 0"); 84 assertEquals(setRegions, regionsFreed, "No EvacuationFailure -> setRegions = regionsFreed"); 85 } 86 } catch (Throwable t) { 87 System.out.println("Failed event:"); 88 System.out.println(event.toString()); 89 throw t; 90 } 91 } 92 } 93 } catch (Throwable e) { 94 e.printStackTrace(); 95 r.copyTo("TestEvacuationInfoEvent_failed.jfr"); 96 throw e; 97 } finally { 98 r.close(); 99 } 100 } 101 102 /** 103 * Allocate memory to trigger garbage collections. 104 * We want the allocated objects to have different life time, because we want both "young" and "old" objects. 105 * This is done by keeping the objects in an array and step the current index by a small random number in the loop. 106 * The loop will continue until we have allocated a fixed number of bytes. 107 */ 108 private static void allocate() { 109 Random r = new Random(0); 110 final int arraySize = 6000; 111 dummyList = new ArrayList<DummyObject>(arraySize); 112 for (int c=0; c<arraySize; c++) { 113 dummyList.add(null); 114 } 115 long bytesToAllocate = 256 * 1024 * 1024; 116 int currPos = 0; 117 while (bytesToAllocate > 0) { 118 try { 119 int nextAlloc = 1000 + (r.nextInt(4000)); 120 bytesToAllocate -= nextAlloc; 121 dummyList.set(currPos, new DummyObject(nextAlloc)); 122 123 // Skip a few positions to get different duration on the objects. 124 currPos += r.nextInt(20); 125 if (currPos >= arraySize) { 126 currPos = 0; 127 } 128 } catch (OutOfMemoryError e) { 129 // We should not get an OOM, but if we do, just clear the dummyList. 130 dummyList = null; 131 System.gc(); 132 dummyList = new ArrayList<DummyObject>(arraySize); 133 for (int c=0; c<arraySize; c++) { 134 dummyList.add(null); 135 } 136 } 137 } 138 dummyList = null; 139 System.gc(); 140 } 141 142 private static class DummyObject { 143 public byte[] payload; 144 DummyObject(int size) { 145 payload = new byte[size]; 146 } 147 } 148 } 149