1 /*
2  * Copyright (c) 2011, 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.
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 
24 package nsk.monitoring.ThreadMXBean;
25 
26 import java.util.*;
27 import nsk.share.test.*;
28 import nsk.monitoring.share.*;
29 import nsk.share.gc.Memory;
30 
31 public abstract class ThreadMXBeanTestBase extends MonitoringTestBase
32         implements Initializable {
33 
34     /**
35      * Maximum allocation object size. about 2 Mb
36      */
37     private static final int MAX_OBJECT_SIZE = 2*1024*1024;
38     /**
39      * Allocations count for each MXBeanTestThread
40      */
41     private static final int ALLOCATIONS = 100;
42     /**
43      * Minimum size of allocated objects for a single thread stressing GC: 1Mb
44      */
45     protected static final int MIN_STRESS_ALLOCATION_AMOUNT = 1024*1024;
46     /**
47      * Percent of maximum difference of actual result from expected one
48      */
49     protected static final int DELTA_PERCENT = 15;
50     /**
51      * java.util.Random instance for allocArr filling
52      */
53     private final java.util.Random random = new java.util.Random();
54 
55     /**
56      * Instance of com.sun.management.ThreadMXBean used by all tests
57      * Obtained in initialize() method
58      */
59     protected com.sun.management.ThreadMXBean threadMXBean;
60     /**
61      * Stresser class instance used in StressTest
62      */
63     protected Stresser stresser;
64     /**
65      * String indicating the GarbageProducer type used in test
66      */
67     protected String garbageProducerId;
68     /**
69      * Defined array with allocation objects sizes
70      */
71     protected static int[] allocArr = new int[ALLOCATIONS];
72 
73     /**
74      * Obtains instance of com.sun.management.ThreadMXBean
75      * and stores it in threadMXBean field
76      * If com.sun.management.ThreadMXBean API is not available,
77      * threadMXBean is set to null and appropriate message is
78      * prompted
79      */
initialize()80     public void initialize() {
81         if (monitoringFactory.hasThreadMXBeanNew()) {
82             threadMXBean =
83                     (com.sun.management.ThreadMXBean) monitoringFactory.getThreadMXBeanNew();
84             for (int i = 0; i < ALLOCATIONS; i++) {
85                 allocArr[i] = Memory.getArrayExtraSize() + Memory.getIntSize()
86                         + Memory.getReferenceSize() // don't be zero-length
87                         + random.nextInt(MAX_OBJECT_SIZE);
88             }
89         } else {
90             log.info("com.sun.management.ThreadMXBean API is not available!");
91         }
92     }
93 
94     /**
95      * Obtains instance of Stresser and stores it in stresser field
96      * @param args Stresser arguments
97      */
setStresser(String[] args)98     public void setStresser(String[] args) {
99         if (stresser == null)
100             stresser = new Stresser(args);
101     }
102 
103     /**
104      * Parses input String arrays searching for GarbageProducer
105      * settings. If found, sets garbageProducerID filed.
106      * @param args input arguments
107      * @return input arguments without GarbageProducer options
108      */
setGarbageProducer(String[] args)109     public String[] setGarbageProducer(String[] args) {
110         if (garbageProducerId == null) {
111             ArrayList<String> list = new ArrayList<String>();
112             for (int i = 0; i < args.length; i++) {
113                 if (args[i].equals("-gp")) {
114                     garbageProducerId = args[++i];
115                 } else {
116                     list.add(args[i]);
117                 }
118             }
119             return list.toArray(new String[] {});
120         } else {
121             return args;
122         }
123     }
124 
125     /**
126      * Starts all specified TestThread threads
127      * @param threads threads to start
128      */
startThreads(MXBeanTestThread... threads)129     public BarrierHandler startThreads(MXBeanTestThread... threads) {
130         BarrierHandler handler = new BarrierHandler(threads);
131         for (MXBeanTestThread thread : threads) {
132             thread.setHandler(handler);
133             thread.start();
134         }
135         handler.start();
136         return handler;
137     }
138 
139     /**
140      * Returns expected memory size allocated by MXBeanTestThreads during
141      * stress test (allocateStress() method execution)
142      *
143      * @param array of MXBeanTestThreads
144      * @return expected amount of memory allocated by each StressTestThread
145      */
getStressAllocatedBytes(MXBeanTestThread... threads)146     public long[] getStressAllocatedBytes(MXBeanTestThread... threads) {
147         long[] result = new long[threads.length];
148         int counter = 0;
149         for (MXBeanTestThread thread : threads) {
150             result[counter++] = thread.getStressAllocatedBytes();
151         }
152         return result;
153     }
154 }
155