< prev index next >

test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemory.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -32,12 +32,12 @@
 
 public class ThreadAllocatedMemory {
     private static com.sun.management.ThreadMXBean mbean =
         (com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
     private static boolean testFailed = false;
-    private static boolean done = false;
-    private static boolean done1 = false;
+    private static volatile boolean done = false;
+    private static volatile boolean done1 = false;
     private static Object obj = new Object();
     private static final int NUM_THREADS = 10;
     private static Thread[] threads = new Thread[NUM_THREADS];
     private static long[] sizes = new long[NUM_THREADS];
 

@@ -76,11 +76,17 @@
         if (!mbean.isThreadAllocatedMemoryEnabled()) {
             throw new RuntimeException(
                 "ThreadAllocatedMemory is expected to be enabled");
         }
 
-        long size = mbean.getThreadAllocatedBytes(id);
+
+        // Test current thread two ways
+
+
+        // First way, getCurrentThreadAllocatedBytes
+
+        long size = mbean.getCurrentThreadAllocatedBytes();
         // implementation could have started measurement when
         // measurement was enabled, in which case size can be 0
         if (size < 0) {
             throw new RuntimeException(
                 "Invalid allocated bytes returned = " + size);

@@ -93,22 +99,118 @@
         if (size1 < size) {
             throw new RuntimeException("Allocated bytes " + size1 +
                 " expected >= " + size);
         }
         System.out.println(curThread.getName() +
-            " Current thread allocated bytes = " + size +
-            " allocated bytes = " + size1);
+            " Previous allocated bytes = " + size +
+            " Current allocated bytes = " + size1);
+
+        // back-to-back calls shouldn't allocate any memory
+        size = mbean.getCurrentThreadAllocatedBytes();
+        size1 = mbean.getCurrentThreadAllocatedBytes();
+        if (size1 != size) {
+            throw new RuntimeException("Allocated bytes " + size1 +
+                " expected == " + size);
+        }
+        System.out.println(curThread.getName() +
+            " Previous allocated bytes = " + size +
+            " Current allocated bytes = " + size1);
+
 
+        // Second way, getThreadAllocatedBytes
+
+        size = mbean.getThreadAllocatedBytes(id);
+        // implementation could have started measurement when
+        // measurement was enabled, in which case size can be 0
+        if (size < 0) {
+            throw new RuntimeException(
+                "Invalid allocated bytes returned = " + size);
+        }
+
+        doit();
+
+        // Expected to be size1 >= size
+        size1 = mbean.getThreadAllocatedBytes(id);
+        if (size1 < size) {
+            throw new RuntimeException("Allocated bytes " + size1 +
+                " expected >= " + size);
+        }
+        System.out.println(curThread.getName() +
+            " Previous allocated bytes = " + size +
+            " Current allocated bytes = " + size1);
+
+        // back-to-back calls shouldn't allocate any memory
+        size = mbean.getThreadAllocatedBytes(id);
+        size1 = mbean.getThreadAllocatedBytes(id);
+        if (size1 != size) {
+            throw new RuntimeException("Allocated bytes " + size1 +
+                " expected == " + size);
+        }
+        System.out.println(curThread.getName() +
+            " Previous allocated bytes = " + size +
+            " Current allocated bytes = " + size1);
+
+
+        // Test a single thread that isn't ourself
+
+        // Start one thread, wait for it to block
+        // after doing some allocation
+        done = false; done1 = false;
+        curThread = new MyThread("MyThread");
+        curThread.start();
+        id = curThread.getId();
+        waitUntilThreadBlocked(curThread);
+        size = mbean.getThreadAllocatedBytes(id);
+
+        // let thread go to do some more allocation
+        synchronized (obj) {
+            done = true;
+            obj.notifyAll();
+        }
+
+        // wait for thread to get going again and sample it
+        goSleep(400);
+        size1 = mbean.getThreadAllocatedBytes(id);
+        if (size > size1) {
+            throw new RuntimeException(
+                curThread.getName() +
+                " previous allocated bytes = " + size +
+                " > current allocated bytes = " + size1);
+        }
+        System.out.println(curThread.getName() +
+            " Previous allocated bytes = " + size +
+            " Current allocated bytes = " + size1);
+
+        // let thread exit
+        synchronized (obj) {
+            done1 = true;
+            obj.notifyAll();
+        }
+
+        try {
+            curThread.join();
+        } catch (InterruptedException e) {
+            System.out.println("Unexpected exception is thrown.");
+            e.printStackTrace(System.out);
+            testFailed = true;
+        }
+        if (testFailed) {
+            throw new RuntimeException("TEST FAILED");
+        }
+
+
+        // Test many threads
 
         // start threads, wait for them to block
+        done = false; done1 = false;
         for (int i = 0; i < NUM_THREADS; i++) {
             threads[i] = new MyThread("MyThread-" + i);
             threads[i].start();
         }
 
         // threads block after doing some allocation
-        waitUntilThreadBlocked();
+        waitUntilThreadsBlocked();
 
         for (int i = 0; i < NUM_THREADS; i++) {
             sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId());
         }
 

@@ -124,11 +226,11 @@
         goSleep(400);
 
         for (int i = 0; i < NUM_THREADS; i++) {
             long newSize = mbean.getThreadAllocatedBytes(threads[i].getId());
             if (sizes[i] > newSize) {
-                throw new RuntimeException("TEST FAILED: " +
+                throw new RuntimeException(
                     threads[i].getName() +
                     " previous allocated bytes = " + sizes[i] +
                     " > current allocated bytes = " + newSize);
             }
             System.out.println(threads[i].getName() +

@@ -154,10 +256,11 @@
         }
         if (testFailed) {
             throw new RuntimeException("TEST FAILED");
         }
 
+
         System.out.println("Test passed");
     }
 
 
     private static void goSleep(long ms) throws Exception {

@@ -167,11 +270,22 @@
             System.out.println("Unexpected exception is thrown.");
             throw e;
         }
     }
 
-    private static void waitUntilThreadBlocked()
+    private static void waitUntilThreadBlocked(Thread thread)
+        throws Exception {
+        while (true) {
+            goSleep(100);
+            ThreadInfo info = mbean.getThreadInfo(thread.getId());
+            if (info.getThreadState() == Thread.State.WAITING) {
+                break;
+            }
+        }
+    }
+
+    private static void waitUntilThreadsBlocked()
         throws Exception {
         int count = 0;
         while (count != NUM_THREADS) {
             goSleep(100);
             count = 0;

@@ -223,11 +337,11 @@
             System.out.println(getName() + ": " +
                 "ThreadAllocatedBytes  = " + size1 +
                 " ThreadAllocatedBytes  = " + size2);
 
             if (size1 > size2) {
-                throw new RuntimeException("TEST FAILED: " + getName() +
+                throw new RuntimeException(getName() +
                     " ThreadAllocatedBytes = " + size1 +
                     " > ThreadAllocatedBytes = " + size2);
             }
 
             synchronized (obj) {
< prev index next >