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 }