1 /*
2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3  * Copyright (c) 2018, Google and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  */
24 
25 package MyPackage;
26 
27 /**
28  * @test
29  * @summary Verifies the JVMTI Heap Monitor sampling interval average.
30  * @build Frame HeapMonitor
31  * @compile HeapMonitorStatIntervalTest.java
32  * @requires vm.compMode != "Xcomp"
33  * @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatIntervalTest
34  */
35 
36 public class HeapMonitorStatIntervalTest {
testIntervalOnce(int interval, boolean throwIfFailure)37   private static boolean testIntervalOnce(int interval, boolean throwIfFailure) {
38     HeapMonitor.resetEventStorage();
39     HeapMonitor.setSamplingInterval(interval);
40 
41     HeapMonitor.enableSamplingEvents();
42 
43     int allocationTotal = 10 * 1024 * 1024;
44     int allocationIterations = 10;
45 
46     double actualCount = 0;
47     for (int i = 0; i < allocationIterations; i++) {
48       HeapMonitor.resetEventStorage();
49       HeapMonitor.allocateSize(allocationTotal);
50       actualCount += HeapMonitor.getEventStorageElementCount();
51     }
52 
53     HeapMonitor.disableSamplingEvents();
54 
55     double expectedCount = allocationTotal * allocationIterations / interval;
56 
57     double error = Math.abs(actualCount - expectedCount);
58     double errorPercentage = error / expectedCount * 100;
59 
60     boolean success = (errorPercentage < 10.0);
61     System.out.println("Interval: " + interval + ", throw if failure: " + throwIfFailure
62         + " - Expected count: " + expectedCount + ", allocationIterations: " + allocationIterations
63         + ", actualCount: " + actualCount + " -> " + success);
64 
65     if (!success && throwIfFailure) {
66       throw new RuntimeException("Interval average over 10% for interval " + interval + " -> "
67           + actualCount + ", " + expectedCount);
68     }
69 
70     return success;
71   }
72 
73 
testInterval(int interval)74   private static void testInterval(int interval) {
75     // Test the interval twice, it can happen that the test is "unlucky" and the interval just goes above
76     // the 10% mark. So try again to squash flakiness.
77     // Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
78     // statistical geometric variable around the sampling interval. This means that the test could be
79     // unlucky and not achieve the mean average fast enough for the test case.
80     if (!testIntervalOnce(interval, false)) {
81       testIntervalOnce(interval, true);
82     }
83   }
84 
main(String[] args)85   public static void main(String[] args) {
86     int[] tab = {1024, 8192};
87 
88     HeapMonitor.calculateOneElementSize();
89 
90     for (int intervalIdx = 0; intervalIdx < tab.length; intervalIdx++) {
91       testInterval(tab[intervalIdx]);
92     }
93   }
94 }
95