blob: b81f83dbf7f4952aedd403b38ce7bfa7ee3266bb [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 4530538
27 * @summary Basic unit test of memory management testing:
28 * 1) setUsatgeThreshold() and getUsageThreshold()
29 * 2) test low memory detection on the old generation.
30 *
31 * @author Mandy Chung
32 *
33 * @build MemoryManagement MemoryUtil
34 * @run main/timeout=600 MemoryManagement
35 */
36
37import java.lang.management.*;
38import java.util.*;
39import javax.management.*;
40import javax.management.openmbean.CompositeData;
41
42public class MemoryManagement {
43 private static MemoryMXBean mm = ManagementFactory.getMemoryMXBean();
44 private static List pools = ManagementFactory.getMemoryPoolMXBeans();
45 private static List managers = ManagementFactory.getMemoryManagerMXBeans();
46 private static MemoryPoolMXBean mpool = null;
47 private static boolean trace = false;
48 private static boolean testFailed = false;
49 private static final int NUM_CHUNKS = 2;
50 private static long chunkSize;
51
52 private static int listenerInvoked = 0;
53 static class SensorListener implements NotificationListener {
54 public void handleNotification(Notification notif, Object handback) {
55 String type = notif.getType();
56 if (type.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED) ||
57 type.equals(MemoryNotificationInfo.
58 MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) {
59
60 MemoryNotificationInfo minfo = MemoryNotificationInfo.
61 from((CompositeData) notif.getUserData());
62
63 MemoryUtil.printMemoryNotificationInfo(minfo, type);
64 listenerInvoked++;
65 }
66 }
67 }
68
69 private static long newThreshold;
70 public static void main(String args[]) throws Exception {
71 if (args.length > 0 && args[0].equals("trace")) {
72 trace = true;
73 }
74
75 if (trace) {
76 MemoryUtil.printMemoryPools(pools);
77 MemoryUtil.printMemoryManagers(managers);
78 }
79
80 // Find the Old generation which supports low memory detection
81 ListIterator iter = pools.listIterator();
82 while (iter.hasNext()) {
83 MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
84 if (p.getType() == MemoryType.HEAP &&
85 p.isUsageThresholdSupported()) {
86 mpool = p;
87 if (trace) {
88 System.out.println("Selected memory pool for low memory " +
89 "detection.");
90 MemoryUtil.printMemoryPool(mpool);
91 }
92 break;
93 }
94 }
95
96 SensorListener listener = new SensorListener();
97 NotificationEmitter emitter = (NotificationEmitter) mm;
98 emitter.addNotificationListener(listener, null, null);
99
100 Thread allocator = new AllocatorThread();
101
102 // Now set threshold
103 MemoryUsage mu = mpool.getUsage();
104 chunkSize = (mu.getMax() - mu.getUsed()) / 20;
105 newThreshold = mu.getUsed() + (chunkSize * NUM_CHUNKS);
106
107 System.out.println("Setting threshold for " + mpool.getName() +
108 " from " + mpool.getUsageThreshold() + " to " + newThreshold +
109 ". Current used = " + mu.getUsed());
110 mpool.setUsageThreshold(newThreshold);
111
112 if (mpool.getUsageThreshold() != newThreshold) {
113 throw new RuntimeException("TEST FAILED: " +
114 "Threshold for Memory pool " + mpool.getName() +
115 "is " + mpool.getUsageThreshold() + " but expected to be" +
116 newThreshold);
117 }
118
119 // Start the AllocatorThread to continously allocate memory
120 System.out.println("Starting an AllocatorThread to allocate memory.");
121 allocator.start();
122
123 try {
124 allocator.join();
125 } catch (InterruptedException e) {
126 e.printStackTrace();
127 System.out.println("Unexpected exception.");
128 testFailed = true;
129 }
130
131 if (listenerInvoked == 0) {
132 throw new RuntimeException("No listener is invoked");
133 }
134
135 if (testFailed)
136 throw new RuntimeException("TEST FAILED.");
137
138 System.out.println("Test passed.");
139
140 }
141
142 static class AllocatorThread extends Thread {
143 private List objectPool = new ArrayList();
144 public void run() {
145 int iterations = 0;
146 int numElements = (int) (chunkSize / 4); // minimal object size
147 while (listenerInvoked == 0) {
148 iterations++;
149 if (trace) {
150 System.out.println(" Iteration " + iterations +
151 ": before allocation " +
152 mpool.getUsage().getUsed());
153 }
154
155 Object[] o = new Object[numElements];
156 if (iterations <= NUM_CHUNKS) {
157 // only hold a reference to the first NUM_CHUNKS
158 // allocated objects
159 objectPool.add(o);
160 }
161
162 if (trace) {
163 System.out.println(" " +
164 " after allocation " +
165 mpool.getUsage().getUsed());
166 }
167 try {
168 Thread.sleep(100);
169 } catch (InterruptedException e) {
170 e.printStackTrace();
171 System.out.println("Unexpected exception.");
172 testFailed = true;
173 }
174 }
175
176 System.out.println("AllocatedThread finished memory allocation " +
177 " num_iteration = " + iterations);
178 }
179 }
180
181}