21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 /* |
25 * @test |
25 * @test |
26 * @bug 6173675 8207266 |
26 * @bug 6173675 |
27 * @summary Basic test of ThreadMXBean.getThreadAllocatedBytes |
27 * @summary Basic test of ThreadMXBean.getThreadAllocatedBytes |
28 * @author Paul Hohensee |
28 * @author Paul Hohensee |
29 */ |
29 */ |
30 |
30 |
31 import java.lang.management.*; |
31 import java.lang.management.*; |
32 |
32 |
33 public class ThreadAllocatedMemory { |
33 public class ThreadAllocatedMemory { |
34 private static com.sun.management.ThreadMXBean mbean = |
34 private static com.sun.management.ThreadMXBean mbean = |
35 (com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean(); |
35 (com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean(); |
36 private static volatile boolean done = false; |
36 private static boolean testFailed = false; |
37 private static volatile boolean done1 = false; |
37 private static boolean done = false; |
|
38 private static boolean done1 = false; |
38 private static Object obj = new Object(); |
39 private static Object obj = new Object(); |
39 private static final int NUM_THREADS = 10; |
40 private static final int NUM_THREADS = 10; |
40 private static Thread[] threads = new Thread[NUM_THREADS]; |
41 private static Thread[] threads = new Thread[NUM_THREADS]; |
41 private static long[] sizes = new long[NUM_THREADS]; |
42 private static long[] sizes = new long[NUM_THREADS]; |
42 |
43 |
43 public static void main(String[] argv) |
44 public static void main(String[] argv) |
44 throws Exception { |
45 throws Exception { |
45 |
46 |
46 testSupportEnableDisable(); |
|
47 |
|
48 // Test current thread two ways |
|
49 testGetCurrentThreadAllocatedBytes(); |
|
50 testCurrentThreadGetThreadAllocatedBytes(); |
|
51 |
|
52 // Test a single thread that is not this one |
|
53 testGetThreadAllocatedBytes(); |
|
54 |
|
55 // Test many threads that are not this one |
|
56 testGetThreadsAllocatedBytes(); |
|
57 |
|
58 System.out.println("Test passed"); |
|
59 } |
|
60 |
|
61 private static void testSupportEnableDisable() { |
|
62 if (!mbean.isThreadAllocatedMemorySupported()) { |
47 if (!mbean.isThreadAllocatedMemorySupported()) { |
63 return; |
48 return; |
64 } |
49 } |
65 |
50 |
66 // disable allocated memory measurement |
51 // disable allocated memory measurement |
87 |
75 |
88 if (!mbean.isThreadAllocatedMemoryEnabled()) { |
76 if (!mbean.isThreadAllocatedMemoryEnabled()) { |
89 throw new RuntimeException( |
77 throw new RuntimeException( |
90 "ThreadAllocatedMemory is expected to be enabled"); |
78 "ThreadAllocatedMemory is expected to be enabled"); |
91 } |
79 } |
92 } |
80 |
93 |
81 long size = mbean.getThreadAllocatedBytes(id); |
94 private static void testGetCurrentThreadAllocatedBytes() { |
82 // implementation could have started measurement when |
95 long size = mbean.getCurrentThreadAllocatedBytes(); |
83 // measurement was enabled, in which case size can be 0 |
96 ensureValidSize(size); |
84 if (size < 0) { |
97 |
85 throw new RuntimeException( |
98 // do some more allocation |
86 "Invalid allocated bytes returned = " + size); |
|
87 } |
|
88 |
99 doit(); |
89 doit(); |
100 |
90 |
101 checkResult(Thread.currentThread(), size, |
91 // Expected to be size1 >= size |
102 mbean.getCurrentThreadAllocatedBytes()); |
92 long size1 = mbean.getThreadAllocatedBytes(id); |
103 } |
93 if (size1 < size) { |
104 |
94 throw new RuntimeException("Allocated bytes " + size1 + |
105 private static void testCurrentThreadGetThreadAllocatedBytes() { |
95 " expected >= " + size); |
106 Thread curThread = Thread.currentThread(); |
96 } |
107 long id = curThread.getId(); |
97 System.out.println(curThread.getName() + |
108 |
98 " Current thread allocated bytes = " + size + |
109 long size = mbean.getThreadAllocatedBytes(id); |
99 " allocated bytes = " + size1); |
110 ensureValidSize(size); |
100 |
111 |
101 |
112 // do some more allocation |
102 // start threads, wait for them to block |
113 doit(); |
103 for (int i = 0; i < NUM_THREADS; i++) { |
114 |
104 threads[i] = new MyThread("MyThread-" + i); |
115 checkResult(curThread, size, mbean.getThreadAllocatedBytes(id)); |
105 threads[i].start(); |
116 } |
106 } |
117 |
107 |
118 private static void testGetThreadAllocatedBytes() |
108 // threads block after doing some allocation |
119 throws Exception { |
109 waitUntilThreadBlocked(); |
120 |
110 |
121 // start a thread |
111 for (int i = 0; i < NUM_THREADS; i++) { |
122 done = false; done1 = false; |
112 sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId()); |
123 Thread curThread = new MyThread("MyThread"); |
113 } |
124 curThread.start(); |
114 |
125 long id = curThread.getId(); |
115 // let threads go and do some more allocation |
126 |
|
127 // wait for thread to block after doing some allocation |
|
128 waitUntilThreadBlocked(curThread); |
|
129 |
|
130 long size = mbean.getThreadAllocatedBytes(id); |
|
131 ensureValidSize(size); |
|
132 |
|
133 // let thread go to do some more allocation |
|
134 synchronized (obj) { |
116 synchronized (obj) { |
135 done = true; |
117 done = true; |
136 obj.notifyAll(); |
118 obj.notifyAll(); |
137 } |
119 } |
138 |
120 |
139 // wait for thread to get going again. we don't care if we |
121 // wait for threads to get going again. we don't care if we |
140 // catch it in mid-execution or if it hasn't |
|
141 // restarted after we're done sleeping. |
|
142 goSleep(400); |
|
143 |
|
144 checkResult(curThread, size, mbean.getThreadAllocatedBytes(id)); |
|
145 |
|
146 // let thread exit |
|
147 synchronized (obj) { |
|
148 done1 = true; |
|
149 obj.notifyAll(); |
|
150 } |
|
151 |
|
152 try { |
|
153 curThread.join(); |
|
154 } catch (InterruptedException e) { |
|
155 System.out.println("Unexpected exception is thrown."); |
|
156 e.printStackTrace(System.out); |
|
157 } |
|
158 } |
|
159 |
|
160 private static void testGetThreadsAllocatedBytes() |
|
161 throws Exception { |
|
162 |
|
163 // start threads |
|
164 done = false; done1 = false; |
|
165 for (int i = 0; i < NUM_THREADS; i++) { |
|
166 threads[i] = new MyThread("MyThread-" + i); |
|
167 threads[i].start(); |
|
168 } |
|
169 |
|
170 // wait for threads to block after doing some allocation |
|
171 waitUntilThreadsBlocked(); |
|
172 |
|
173 for (int i = 0; i < NUM_THREADS; i++) { |
|
174 sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId()); |
|
175 ensureValidSize(sizes[i]); |
|
176 } |
|
177 |
|
178 // let threads go to do some more allocation |
|
179 synchronized (obj) { |
|
180 done = true; |
|
181 obj.notifyAll(); |
|
182 } |
|
183 |
|
184 // wait for threads to get going again. we don't care if we |
|
185 // catch them in mid-execution or if some of them haven't |
122 // catch them in mid-execution or if some of them haven't |
186 // restarted after we're done sleeping. |
123 // restarted after we're done sleeping. |
187 goSleep(400); |
124 goSleep(400); |
188 |
125 |
189 for (int i = 0; i < NUM_THREADS; i++) { |
126 for (int i = 0; i < NUM_THREADS; i++) { |
190 checkResult(threads[i], sizes[i], |
127 long newSize = mbean.getThreadAllocatedBytes(threads[i].getId()); |
191 mbean.getThreadAllocatedBytes(threads[i].getId())); |
128 if (sizes[i] > newSize) { |
|
129 throw new RuntimeException("TEST FAILED: " + |
|
130 threads[i].getName() + |
|
131 " previous allocated bytes = " + sizes[i] + |
|
132 " > current allocated bytes = " + newSize); |
|
133 } |
|
134 System.out.println(threads[i].getName() + |
|
135 " Previous allocated bytes = " + sizes[i] + |
|
136 " Current allocated bytes = " + newSize); |
192 } |
137 } |
193 |
138 |
194 // let threads exit |
139 // let threads exit |
195 synchronized (obj) { |
140 synchronized (obj) { |
196 done1 = true; |
141 done1 = true; |
201 try { |
146 try { |
202 threads[i].join(); |
147 threads[i].join(); |
203 } catch (InterruptedException e) { |
148 } catch (InterruptedException e) { |
204 System.out.println("Unexpected exception is thrown."); |
149 System.out.println("Unexpected exception is thrown."); |
205 e.printStackTrace(System.out); |
150 e.printStackTrace(System.out); |
|
151 testFailed = true; |
206 break; |
152 break; |
207 } |
153 } |
208 } |
154 } |
209 } |
155 if (testFailed) { |
210 |
156 throw new RuntimeException("TEST FAILED"); |
211 private static void ensureValidSize(long size) { |
157 } |
212 // implementation could have started measurement when |
158 |
213 // measurement was enabled, in which case size can be 0 |
159 System.out.println("Test passed"); |
214 if (size < 0) { |
160 } |
215 throw new RuntimeException( |
161 |
216 "Invalid allocated bytes returned = " + size); |
|
217 } |
|
218 } |
|
219 |
|
220 private static void checkResult(Thread curThread, |
|
221 long prev_size, long curr_size) { |
|
222 if (curr_size < prev_size) { |
|
223 throw new RuntimeException("Allocated bytes " + curr_size + |
|
224 " expected >= " + prev_size); |
|
225 } |
|
226 System.out.println(curThread.getName() + |
|
227 " Previous allocated bytes = " + prev_size + |
|
228 " Current allocated bytes = " + curr_size); |
|
229 } |
|
230 |
162 |
231 private static void goSleep(long ms) throws Exception { |
163 private static void goSleep(long ms) throws Exception { |
232 try { |
164 try { |
233 Thread.sleep(ms); |
165 Thread.sleep(ms); |
234 } catch (InterruptedException e) { |
166 } catch (InterruptedException e) { |
235 System.out.println("Unexpected exception is thrown."); |
167 System.out.println("Unexpected exception is thrown."); |
236 throw e; |
168 throw e; |
237 } |
169 } |
238 } |
170 } |
239 |
171 |
240 private static void waitUntilThreadBlocked(Thread thread) |
172 private static void waitUntilThreadBlocked() |
241 throws Exception { |
|
242 while (true) { |
|
243 goSleep(100); |
|
244 ThreadInfo info = mbean.getThreadInfo(thread.getId()); |
|
245 if (info.getThreadState() == Thread.State.WAITING) { |
|
246 break; |
|
247 } |
|
248 } |
|
249 } |
|
250 |
|
251 private static void waitUntilThreadsBlocked() |
|
252 throws Exception { |
173 throws Exception { |
253 int count = 0; |
174 int count = 0; |
254 while (count != NUM_THREADS) { |
175 while (count != NUM_THREADS) { |
255 goSleep(100); |
176 goSleep(100); |
256 count = 0; |
177 count = 0; |