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: " + 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); 137 } 138 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(); 193 } 194 System.out.println(Thread.currentThread().getName() + 195 " hashcode: " + hashCode); 196 } 197 198 static class MyThread extends Thread { 199 public MyThread(String name) { 200 super(name); 201 } 202 203 public void run() { 204 ThreadAllocatedMemory.doit(); 205 206 synchronized (obj) { 207 while (!done) { 208 try { 209 obj.wait(); 210 } catch (InterruptedException e) { 211 System.out.println("Unexpected exception is thrown."); 212 e.printStackTrace(System.out); 213 testFailed = true; 214 break; 215 } 216 } 217 } 218 219 long size1 = mbean.getThreadAllocatedBytes(getId()); 220 ThreadAllocatedMemory.doit(); 221 long size2 = mbean.getThreadAllocatedBytes(getId()); 222 223 System.out.println(getName() + ": " + 224 "ThreadAllocatedBytes = " + size1 + 225 " ThreadAllocatedBytes = " + size2); 226 227 if (size1 > size2) { 228 throw new RuntimeException("TEST FAILED: " + getName() + 229 " ThreadAllocatedBytes = " + size1 + 230 " > ThreadAllocatedBytes = " + size2); 231 } 232 233 synchronized (obj) { 234 while (!done1) { 235 try { 236 obj.wait(); 237 } catch (InterruptedException e) { 238 System.out.println("Unexpected exception is thrown."); 239 e.printStackTrace(System.out); 240 testFailed = true; 241 break; 242 } 243 } 244 } 245 } 246 } 247 } | 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 8207266 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 volatile boolean done = false; 37 private static volatile boolean done1 = false; 38 private static Object obj = new Object(); 39 private static final int NUM_THREADS = 10; 40 private static Thread[] threads = new Thread[NUM_THREADS]; 41 private static long[] sizes = new long[NUM_THREADS]; 42 43 public static void main(String[] argv) 44 throws Exception { 45 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()) { 63 return; 64 } 65 66 // disable allocated memory measurement 67 if (mbean.isThreadAllocatedMemoryEnabled()) { 68 mbean.setThreadAllocatedMemoryEnabled(false); 69 } 70 71 if (mbean.isThreadAllocatedMemoryEnabled()) { 72 throw new RuntimeException( 73 "ThreadAllocatedMemory is expected to be disabled"); 74 } 75 76 long s = mbean.getCurrentThreadAllocatedBytes(); 77 if (s != -1) { 78 throw new RuntimeException( 79 "Invalid ThreadAllocatedBytes returned = " + 80 s + " expected = -1"); 81 } 82 83 // enable allocated memory measurement 84 if (!mbean.isThreadAllocatedMemoryEnabled()) { 85 mbean.setThreadAllocatedMemoryEnabled(true); 86 } 87 88 if (!mbean.isThreadAllocatedMemoryEnabled()) { 89 throw new RuntimeException( 90 "ThreadAllocatedMemory is expected to be enabled"); 91 } 92 } 93 94 private static void testGetCurrentThreadAllocatedBytes() { 95 long size = mbean.getCurrentThreadAllocatedBytes(); 96 ensureValidSize(size); 97 98 // do some more allocation 99 doit(); 100 101 checkResult(Thread.currentThread(), size, 102 mbean.getCurrentThreadAllocatedBytes()); 103 } 104 105 private static void testCurrentThreadGetThreadAllocatedBytes() { 106 Thread curThread = Thread.currentThread(); 107 long id = curThread.getId(); 108 109 long size = mbean.getThreadAllocatedBytes(id); 110 ensureValidSize(size); 111 112 // do some more allocation 113 doit(); 114 115 checkResult(curThread, size, mbean.getThreadAllocatedBytes(id)); 116 } 117 118 private static void testGetThreadAllocatedBytes() 119 throws Exception { 120 121 // start a thread 122 done = false; done1 = false; 123 Thread curThread = new MyThread("MyThread"); 124 curThread.start(); 125 long id = curThread.getId(); 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) { 135 done = true; 136 obj.notifyAll(); 137 } 138 139 // wait for thread 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 186 // restarted after we're done sleeping. 187 goSleep(400); 188 189 for (int i = 0; i < NUM_THREADS; i++) { 190 checkResult(threads[i], sizes[i], 191 mbean.getThreadAllocatedBytes(threads[i].getId())); 192 } 193 194 // let threads exit 195 synchronized (obj) { 196 done1 = true; 197 obj.notifyAll(); 198 } 199 200 for (int i = 0; i < NUM_THREADS; i++) { 201 try { 202 threads[i].join(); 203 } catch (InterruptedException e) { 204 System.out.println("Unexpected exception is thrown."); 205 e.printStackTrace(System.out); 206 break; 207 } 208 } 209 } 210 211 private static void ensureValidSize(long size) { 212 // implementation could have started measurement when 213 // measurement was enabled, in which case size can be 0 214 if (size < 0) { 215 throw new RuntimeException( 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 231 private static void goSleep(long ms) throws Exception { 232 try { 233 Thread.sleep(ms); 234 } catch (InterruptedException e) { 235 System.out.println("Unexpected exception is thrown."); 236 throw e; 237 } 238 } 239 240 private static void waitUntilThreadBlocked(Thread thread) 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 { 253 int count = 0; 254 while (count != NUM_THREADS) { 255 goSleep(100); 256 count = 0; 257 for (int i = 0; i < NUM_THREADS; i++) { 258 ThreadInfo info = mbean.getThreadInfo(threads[i].getId()); 259 if (info.getThreadState() == Thread.State.WAITING) { 260 count++; 261 } 262 } 263 } 264 } 265 266 public static void doit() { 267 String tmp = ""; 268 long hashCode = 0; 269 for (int counter = 0; counter < 1000; counter++) { 270 tmp += counter; 271 hashCode = tmp.hashCode(); 272 } 273 System.out.println(Thread.currentThread().getName() + 274 " hashcode: " + hashCode); 275 } 276 277 static class MyThread extends Thread { 278 public MyThread(String name) { 279 super(name); 280 } 281 282 public void run() { 283 ThreadAllocatedMemory.doit(); 284 285 synchronized (obj) { 286 while (!done) { 287 try { 288 obj.wait(); 289 } catch (InterruptedException e) { 290 System.out.println("Unexpected exception is thrown."); 291 e.printStackTrace(System.out); 292 break; 293 } 294 } 295 } 296 297 long size1 = mbean.getThreadAllocatedBytes(getId()); 298 ThreadAllocatedMemory.doit(); 299 long size2 = mbean.getThreadAllocatedBytes(getId()); 300 301 System.out.println(getName() + ": " + 302 "ThreadAllocatedBytes = " + size1 + 303 " ThreadAllocatedBytes = " + size2); 304 305 if (size1 > size2) { 306 throw new RuntimeException(getName() + 307 " ThreadAllocatedBytes = " + size1 + 308 " > ThreadAllocatedBytes = " + size2); 309 } 310 311 synchronized (obj) { 312 while (!done1) { 313 try { 314 obj.wait(); 315 } catch (InterruptedException e) { 316 System.out.println("Unexpected exception is thrown."); 317 e.printStackTrace(System.out); 318 break; 319 } 320 } 321 } 322 } 323 } 324 } |