1/* 2 * Copyright (c) 2017, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import java.lang.management.ManagementFactory; 25import utils.GarbageProducer; 26import common.TmTool; 27import utils.JstatResults; 28 29/** 30 * Base class for jstat testing which uses GarbageProducer to allocate garbage. 31 */ 32public class GarbageProducerTest { 33 34 // Iterations of measurement to get consistent value of counters and jstat. 35 private final static int ITERATIONS = 10; 36 private final static float TARGET_MEMORY_USAGE = 0.7f; 37 private final static float MEASUREMENT_TOLERANCE = 0.05f; 38 private final GarbageProducer garbageProducer; 39 private final TmTool<? extends JstatResults> jstatTool; 40 41 public GarbageProducerTest(TmTool<? extends JstatResults> tool) { 42 garbageProducer = new GarbageProducer(TARGET_MEMORY_USAGE); 43 // We will be running jstat tool 44 jstatTool = tool; 45 } 46 47 public void run() throws Exception { 48 // Run once and get the results asserting that they are reasonable 49 JstatResults measurement1 = jstatTool.measure(); 50 measurement1.assertConsistency(); 51 // Eat metaspace and heap then run the tool again and get the results asserting that they are reasonable 52 System.gc(); 53 garbageProducer.allocateMetaspaceAndHeap(); 54 // Collect garbage. Also update VM statistics 55 System.gc(); 56 int i = 0; 57 long collectionCountBefore = getCollectionCount(); 58 JstatResults measurement2 = jstatTool.measure(); 59 do { 60 System.out.println("Measurement #" + i); 61 long currentCounter = getCollectionCount(); 62 // Check if GC cycle occured during measurement 63 if (currentCounter == collectionCountBefore) { 64 measurement2.assertConsistency(); 65 checkOldGenMeasurement(measurement2); 66 return; 67 } else { 68 System.out.println("GC happened during measurement."); 69 } 70 collectionCountBefore = getCollectionCount(); 71 measurement2 = jstatTool.measure(); 72 73 } while (i++ < ITERATIONS); 74 // Checking will be performed without consistency guarantee. 75 checkOldGenMeasurement(measurement2); 76 } 77 78 private void checkOldGenMeasurement(JstatResults measurement2) { 79 float oldGenAllocationRatio = garbageProducer.getOldGenAllocationRatio() - MEASUREMENT_TOLERANCE; 80 // Assert that space has been utilized accordingly 81 JstatResults.assertSpaceUtilization(measurement2, TARGET_MEMORY_USAGE, oldGenAllocationRatio); 82 } 83 84 private static long getCollectionCount() { 85 return ManagementFactory.getGarbageCollectorMXBeans().stream() 86 .mapToLong(b -> b.getCollectionCount()) 87 .sum(); 88 } 89} 90