1 /*
2 * Copyright (c) 2011, 2015, 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 /*
25 * @test
26 * @bug 6173675
27 * @summary Basic test of ThreadMXBean.getThreadAllocatedBytes
28 * @author Paul Hohensee
29 */
30
31 import java.lang.management.*;
32
33 public class ThreadAllocatedMemory {
34 private static com.sun.management.ThreadMXBean mbean =
35 (com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
36 private static boolean testFailed = false;
37 private static boolean done = false;
38 private static boolean done1 = false;
39 private static Object obj = new Object();
40 private static final int NUM_THREADS = 10;
41 private static Thread[] threads = new Thread[NUM_THREADS];
42 private static long[] sizes = new long[NUM_THREADS];
43
44 public static void main(String[] argv)
45 throws Exception {
46
47 if (!mbean.isThreadAllocatedMemorySupported()) {
48 return;
49 }
50
51 // disable allocated memory measurement
52 if (mbean.isThreadAllocatedMemoryEnabled()) {
53 mbean.setThreadAllocatedMemoryEnabled(false);
54 }
55
56 if (mbean.isThreadAllocatedMemoryEnabled()) {
57 throw new RuntimeException(
58 "ThreadAllocatedMemory is expected to be disabled");
59 }
60
61 Thread curThread = Thread.currentThread();
62 long id = curThread.getId();
63
64 long s = mbean.getThreadAllocatedBytes(id);
65 if (s != -1) {
66 throw new RuntimeException(
67 "Invalid ThreadAllocatedBytes returned = " +
68 s + " expected = -1");
69 }
70
71 // enable allocated memory measurement
72 if (!mbean.isThreadAllocatedMemoryEnabled()) {
73 mbean.setThreadAllocatedMemoryEnabled(true);
74 }
75
76 if (!mbean.isThreadAllocatedMemoryEnabled()) {
77 throw new RuntimeException(
78 "ThreadAllocatedMemory is expected to be enabled");
79 }
80
81 long size = mbean.getThreadAllocatedBytes(id);
82 // implementation could have started measurement when
83 // measurement was enabled, in which case size can be 0
84 if (size < 0) {
85 throw new RuntimeException(
86 "Invalid allocated bytes returned = " + size);
87 }
88
89 doit();
90
91 // Expected to be size1 >= size
92 long size1 = mbean.getThreadAllocatedBytes(id);
93 if (size1 < size) {
94 throw new RuntimeException("Allocated bytes " + size1 +
95 " expected >= " + size);
96 }
97 System.out.println(curThread.getName() +
98 " Current thread allocated bytes = " + size +
99 " allocated bytes = " + size1);
100
101
102 // start threads, wait for them to block
103 for (int i = 0; i < NUM_THREADS; i++) {
104 threads[i] = new MyThread("MyThread-" + i);
105 threads[i].start();
106 }
107
108 // threads block after doing some allocation
109 waitUntilThreadBlocked();
110
111 for (int i = 0; i < NUM_THREADS; i++) {
112 sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId());
113 }
114
115 // let threads go and do some more allocation
116 synchronized (obj) {
117 done = true;
118 obj.notifyAll();
119 }
120
121 // wait for threads to get going again. we don't care if we
122 // catch them in mid-execution or if some of them haven't
123 // restarted after we're done sleeping.
124 goSleep(400);
125
126 for (int i = 0; i < NUM_THREADS; i++) {
127 long newSize = mbean.getThreadAllocatedBytes(threads[i].getId());
128 if (sizes[i] > newSize) {
129 throw new RuntimeException("TEST FAILED: " +
139 // let threads exit
140 synchronized (obj) {
141 done1 = true;
142 obj.notifyAll();
143 }
144
145 for (int i = 0; i < NUM_THREADS; i++) {
146 try {
147 threads[i].join();
148 } catch (InterruptedException e) {
149 System.out.println("Unexpected exception is thrown.");
150 e.printStackTrace(System.out);
151 testFailed = true;
152 break;
153 }
154 }
155 if (testFailed) {
156 throw new RuntimeException("TEST FAILED");
157 }
158
159 System.out.println("Test passed");
160 }
161
162
163 private static void goSleep(long ms) throws Exception {
164 try {
165 Thread.sleep(ms);
166 } catch (InterruptedException e) {
167 System.out.println("Unexpected exception is thrown.");
168 throw e;
169 }
170 }
171
172 private static void waitUntilThreadBlocked()
173 throws Exception {
174 int count = 0;
175 while (count != NUM_THREADS) {
176 goSleep(100);
177 count = 0;
178 for (int i = 0; i < NUM_THREADS; i++) {
179 ThreadInfo info = mbean.getThreadInfo(threads[i].getId());
180 if (info.getThreadState() == Thread.State.WAITING) {
181 count++;
182 }
183 }
184 }
185 }
186
187 public static void doit() {
188 String tmp = "";
189 long hashCode = 0;
190 for (int counter = 0; counter < 1000; counter++) {
191 tmp += counter;
192 hashCode = tmp.hashCode();
|
1 /*
2 * Copyright (c) 2011, 2019, 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 /*
25 * @test
26 * @bug 6173675
27 * @summary Basic test of ThreadMXBean.getThreadAllocatedBytes
28 * @author Paul Hohensee
29 */
30
31 import java.lang.management.*;
32
33 public class ThreadAllocatedMemory {
34 private static com.sun.management.ThreadMXBean mbean =
35 (com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
36 private static boolean testFailed = false;
37 private static volatile boolean done = false;
38 private static volatile boolean done1 = false;
39 private static Object obj = new Object();
40 private static final int NUM_THREADS = 10;
41 private static Thread[] threads = new Thread[NUM_THREADS];
42 private static long[] sizes = new long[NUM_THREADS];
43
44 public static void main(String[] argv)
45 throws Exception {
46
47 if (!mbean.isThreadAllocatedMemorySupported()) {
48 return;
49 }
50
51 // disable allocated memory measurement
52 if (mbean.isThreadAllocatedMemoryEnabled()) {
53 mbean.setThreadAllocatedMemoryEnabled(false);
54 }
55
56 if (mbean.isThreadAllocatedMemoryEnabled()) {
57 throw new RuntimeException(
58 "TEST FAILED: ThreadAllocatedMemory is expected to be disabled");
59 }
60
61 Thread curThread = Thread.currentThread();
62 long id = curThread.getId();
63
64 long s = mbean.getThreadAllocatedBytes(id);
65 if (s != -1) {
66 throw new RuntimeException(
67 "TEST FAILED: Invalid ThreadAllocatedBytes returned = " +
68 s + " expected = -1");
69 }
70
71 // enable allocated memory measurement
72 if (!mbean.isThreadAllocatedMemoryEnabled()) {
73 mbean.setThreadAllocatedMemoryEnabled(true);
74 }
75
76 if (!mbean.isThreadAllocatedMemoryEnabled()) {
77 throw new RuntimeException(
78 "TEST FAILED: ThreadAllocatedMemory is expected to be enabled");
79 }
80
81 // Test current thread two ways
82
83 // First way, getCurrentThreadAllocatedBytes
84 long size = mbean.getCurrentThreadAllocatedBytes();
85 // implementation could have started measurement when
86 // measurement was enabled, in which case size can be 0
87 if (size < 0) {
88 throw new RuntimeException(
89 "TEST FAILED: Invalid allocated bytes returned = " + size);
90 }
91
92 doit();
93
94 // Expected to be size1 >= size
95 long size1 = mbean.getThreadAllocatedBytes(id);
96 if (size1 < size) {
97 throw new RuntimeException("TEST FAILED: Allocated bytes " + size1 +
98 " expected >= " + size);
99 }
100 System.out.println(curThread.getName() +
101 " Previous allocated bytes = " + size +
102 " Current allocated bytes = " + size1);
103
104 // back-to-back calls shouldn't allocate any memory
105 size = mbean.getThreadAllocatedBytes(id);
106 size1 = mbean.getThreadAllocatedBytes(id);
107 if (size1 != size) {
108 throw new RuntimeException("TEST FAILED: Allocated bytes " + size1 +
109 " expected == " + size);
110 }
111 System.out.println(curThread.getName() +
112 " Previous allocated bytes = " + size +
113 " Current allocated bytes = " + size1);
114
115
116 // Second way, getThreadAllocatedBytes
117 size = mbean.getThreadAllocatedBytes(id);
118 // implementation could have started measurement when
119 // measurement was enabled, in which case size can be 0
120 if (size < 0) {
121 throw new RuntimeException(
122 "TEST FAILED: Invalid allocated bytes returned = " + size);
123 }
124
125 doit();
126
127 // Expected to be size1 >= size
128 size1 = mbean.getThreadAllocatedBytes(id);
129 if (size1 < size) {
130 throw new RuntimeException("TEST FAILED: Allocated bytes " + size1 +
131 " expected >= " + size);
132 }
133 System.out.println(curThread.getName() +
134 " Previous allocated bytes = " + size +
135 " Current allocated bytes = " + size1);
136
137
138 // back-to-back calls shouldn't allocate any memory
139 size = mbean.getThreadAllocatedBytes(id);
140 size1 = mbean.getThreadAllocatedBytes(id);
141 if (size1 != size) {
142 throw new RuntimeException("TEST FAILED: Allocated bytes " + size1 +
143 " expected == " + size);
144 }
145 System.out.println(curThread.getName() +
146 " Previous allocated bytes = " + size +
147 " Current allocated bytes = " + size1);
148
149
150 // Test a single thread that isn't ourself
151
152 // Start one thread, wait for it to block
153 // after doing some allocation
154 done = false; done1 = false;
155 curThread = new MyThread("MyThread");
156 curThread.start();
157 id = curThread.getId();
158 waitUntilThreadBlocked(curThread);
159 size = mbean.getThreadAllocatedBytes(id);
160
161 // let thread go to do some more allocation
162 synchronized (obj) {
163 done = true;
164 obj.notifyAll();
165 }
166
167 // wait for thread to get going again and sample it
168 goSleep(400);
169 size1 = mbean.getThreadAllocatedBytes(id);
170 if (size > size1) {
171 throw new RuntimeException("TEST FAILED: " +
172 curThread.getName() +
173 " previous allocated bytes = " + size +
174 " > current allocated bytes = " + size1);
175 }
176 System.out.println(curThread.getName() +
177 " Previous allocated bytes = " + size +
178 " Current allocated bytes = " + size1);
179
180 // let thread exit
181 synchronized (obj) {
182 done1 = true;
183 obj.notifyAll();
184 }
185
186 try {
187 curThread.join();
188 } catch (InterruptedException e) {
189 System.out.println("Unexpected exception is thrown.");
190 e.printStackTrace(System.out);
191 testFailed = true;
192 }
193 if (testFailed) {
194 throw new RuntimeException("TEST FAILED");
195 }
196
197
198 // Test many threads
199
200 // start threads, wait for them to block
201 done = false; done1 = false;
202 for (int i = 0; i < NUM_THREADS; i++) {
203 threads[i] = new MyThread("MyThread-" + i);
204 threads[i].start();
205 }
206
207 // threads block after doing some allocation
208 waitUntilThreadsBlocked();
209
210 for (int i = 0; i < NUM_THREADS; i++) {
211 sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId());
212 }
213
214 // let threads go and do some more allocation
215 synchronized (obj) {
216 done = true;
217 obj.notifyAll();
218 }
219
220 // wait for threads to get going again. we don't care if we
221 // catch them in mid-execution or if some of them haven't
222 // restarted after we're done sleeping.
223 goSleep(400);
224
225 for (int i = 0; i < NUM_THREADS; i++) {
226 long newSize = mbean.getThreadAllocatedBytes(threads[i].getId());
227 if (sizes[i] > newSize) {
228 throw new RuntimeException("TEST FAILED: " +
238 // let threads exit
239 synchronized (obj) {
240 done1 = true;
241 obj.notifyAll();
242 }
243
244 for (int i = 0; i < NUM_THREADS; i++) {
245 try {
246 threads[i].join();
247 } catch (InterruptedException e) {
248 System.out.println("Unexpected exception is thrown.");
249 e.printStackTrace(System.out);
250 testFailed = true;
251 break;
252 }
253 }
254 if (testFailed) {
255 throw new RuntimeException("TEST FAILED");
256 }
257
258
259 System.out.println("Test passed");
260 }
261
262
263 private static void goSleep(long ms) throws Exception {
264 try {
265 Thread.sleep(ms);
266 } catch (InterruptedException e) {
267 System.out.println("Unexpected exception is thrown.");
268 throw e;
269 }
270 }
271
272 private static void waitUntilThreadBlocked(Thread thread)
273 throws Exception {
274 while (true) {
275 goSleep(100);
276 ThreadInfo info = mbean.getThreadInfo(thread.getId());
277 if (info.getThreadState() == Thread.State.WAITING) {
278 break;
279 }
280 }
281 }
282
283 private static void waitUntilThreadsBlocked()
284 throws Exception {
285 int count = 0;
286 while (count != NUM_THREADS) {
287 goSleep(100);
288 count = 0;
289 for (int i = 0; i < NUM_THREADS; i++) {
290 ThreadInfo info = mbean.getThreadInfo(threads[i].getId());
291 if (info.getThreadState() == Thread.State.WAITING) {
292 count++;
293 }
294 }
295 }
296 }
297
298 public static void doit() {
299 String tmp = "";
300 long hashCode = 0;
301 for (int counter = 0; counter < 1000; counter++) {
302 tmp += counter;
303 hashCode = tmp.hashCode();
|