Mercurial > hg > graal-compiler
comparison test/runtime/NMT/MallocStressTest.java @ 20394:017b0145f20c
8054952: [TESTBUG] Add missing NMT2 tests
Summary: The new NMT2 tests got lost on the way into jdk9 yesterday, this change adds them.
Reviewed-by: coleenp, zgu, ctornqvi
author | gtriantafill |
---|---|
date | Tue, 12 Aug 2014 14:06:41 -0700 |
parents | |
children | 3f9ff5e261c6 |
comparison
equal
deleted
inserted
replaced
20393:966601b12d4f | 20394:017b0145f20c |
---|---|
1 /* | |
2 * Copyright (c) 2014, 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 * @key stress | |
26 * @test | |
27 * @summary Stress test for malloc tracking | |
28 * @key nmt jcmd | |
29 * @library /testlibrary /testlibrary/whitebox | |
30 * @build MallocStressTest | |
31 * @ignore - This test is disabled since it will stress NMT and timeout during normal testing | |
32 * @run main ClassFileInstaller sun.hotspot.WhiteBox | |
33 * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocStressTest | |
34 */ | |
35 | |
36 import java.util.concurrent.atomic.AtomicInteger; | |
37 import java.util.ArrayList; | |
38 import java.util.List; | |
39 import java.util.Random; | |
40 import com.oracle.java.testlibrary.*; | |
41 import sun.hotspot.WhiteBox; | |
42 | |
43 public class MallocStressTest { | |
44 private static int K = 1024; | |
45 | |
46 // The stress test runs in three phases: | |
47 // 1. alloc: A lot of malloc with fewer free, which simulates a burst memory allocation | |
48 // that is usually seen during startup or class loading. | |
49 // 2. pause: Pause the test to check accuracy of native memory tracking | |
50 // 3. release: Release all malloc'd memory and check native memory tracking result. | |
51 public enum TestPhase { | |
52 alloc, | |
53 pause, | |
54 release | |
55 }; | |
56 | |
57 static TestPhase phase = TestPhase.alloc; | |
58 | |
59 // malloc'd memory | |
60 static ArrayList<MallocMemory> mallocd_memory = new ArrayList<MallocMemory>(); | |
61 static long mallocd_total = 0; | |
62 static WhiteBox whiteBox; | |
63 static AtomicInteger pause_count = new AtomicInteger(); | |
64 | |
65 static boolean is_64_bit_system; | |
66 | |
67 private static boolean is_64_bit_system() { return is_64_bit_system; } | |
68 | |
69 public static void main(String args[]) throws Exception { | |
70 is_64_bit_system = (Platform.is64bit()); | |
71 | |
72 OutputAnalyzer output; | |
73 whiteBox = WhiteBox.getWhiteBox(); | |
74 | |
75 // Grab my own PID | |
76 String pid = Integer.toString(ProcessTools.getProcessId()); | |
77 ProcessBuilder pb = new ProcessBuilder(); | |
78 | |
79 AllocThread[] alloc_threads = new AllocThread[256]; | |
80 ReleaseThread[] release_threads = new ReleaseThread[64]; | |
81 | |
82 int index; | |
83 // Create many allocation threads | |
84 for (index = 0; index < alloc_threads.length; index ++) { | |
85 alloc_threads[index] = new AllocThread(); | |
86 } | |
87 | |
88 // Fewer release threads | |
89 for (index = 0; index < release_threads.length; index ++) { | |
90 release_threads[index] = new ReleaseThread(); | |
91 } | |
92 | |
93 if (is_64_bit_system()) { | |
94 sleep_wait(2*60*1000); | |
95 } else { | |
96 sleep_wait(60*1000); | |
97 } | |
98 // pause the stress test | |
99 phase = TestPhase.pause; | |
100 while (pause_count.intValue() < alloc_threads.length + release_threads.length) { | |
101 sleep_wait(10); | |
102 } | |
103 | |
104 long mallocd_total_in_KB = (mallocd_total + K / 2) / K; | |
105 | |
106 // Now check if the result from NMT matches the total memory allocated. | |
107 String expected_test_summary = "Test (reserved=" + mallocd_total_in_KB +"KB, committed=" + mallocd_total_in_KB + "KB)"; | |
108 // Run 'jcmd <pid> VM.native_memory summary' | |
109 pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"}); | |
110 output = new OutputAnalyzer(pb.start()); | |
111 output.shouldContain(expected_test_summary); | |
112 | |
113 // Release all allocated memory | |
114 phase = TestPhase.release; | |
115 synchronized(mallocd_memory) { | |
116 mallocd_memory.notifyAll(); | |
117 } | |
118 | |
119 // Join all threads | |
120 for (index = 0; index < alloc_threads.length; index ++) { | |
121 try { | |
122 alloc_threads[index].join(); | |
123 } catch (InterruptedException e) { | |
124 } | |
125 } | |
126 | |
127 for (index = 0; index < release_threads.length; index ++) { | |
128 try { | |
129 release_threads[index].join(); | |
130 } catch (InterruptedException e) { | |
131 } | |
132 } | |
133 | |
134 // All test memory allocated should be released | |
135 output = new OutputAnalyzer(pb.start()); | |
136 output.shouldNotContain("Test (reserved="); | |
137 | |
138 // Verify that tracking level has not been downgraded | |
139 pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"}); | |
140 output = new OutputAnalyzer(pb.start()); | |
141 output.shouldNotContain("Tracking level has been downgraded due to lack of resources"); | |
142 } | |
143 | |
144 private static void sleep_wait(int n) { | |
145 try { | |
146 Thread.sleep(n); | |
147 } catch (InterruptedException e) { | |
148 } | |
149 } | |
150 | |
151 | |
152 static class MallocMemory { | |
153 private long addr; | |
154 private int size; | |
155 | |
156 MallocMemory(long addr, int size) { | |
157 this.addr = addr; | |
158 this.size = size; | |
159 } | |
160 | |
161 long addr() { return this.addr; } | |
162 int size() { return this.size; } | |
163 } | |
164 | |
165 static class AllocThread extends Thread { | |
166 AllocThread() { | |
167 this.setName("MallocThread"); | |
168 this.start(); | |
169 } | |
170 | |
171 // AllocThread only runs "Alloc" phase | |
172 public void run() { | |
173 Random random = new Random(); | |
174 while (MallocStressTest.phase == TestPhase.alloc) { | |
175 int r = Math.abs(random.nextInt()); | |
176 // Only malloc small amount to avoid OOM | |
177 int size = r % 32; | |
178 if (is_64_bit_system()) { | |
179 r = r % 32 * K; | |
180 } else { | |
181 r = r % 64; | |
182 } | |
183 if (size == 0) size = 1; | |
184 long addr = MallocStressTest.whiteBox.NMTMallocWithPseudoStack(size, r); | |
185 if (addr != 0) { | |
186 MallocMemory mem = new MallocMemory(addr, size); | |
187 synchronized(MallocStressTest.mallocd_memory) { | |
188 MallocStressTest.mallocd_memory.add(mem); | |
189 MallocStressTest.mallocd_total += size; | |
190 } | |
191 } else { | |
192 System.out.println("Out of malloc memory"); | |
193 break; | |
194 } | |
195 } | |
196 MallocStressTest.pause_count.incrementAndGet(); | |
197 } | |
198 } | |
199 | |
200 static class ReleaseThread extends Thread { | |
201 private Random random = new Random(); | |
202 ReleaseThread() { | |
203 this.setName("ReleaseThread"); | |
204 this.start(); | |
205 } | |
206 | |
207 public void run() { | |
208 while(true) { | |
209 switch(MallocStressTest.phase) { | |
210 case alloc: | |
211 slow_release(); | |
212 break; | |
213 case pause: | |
214 enter_pause(); | |
215 break; | |
216 case release: | |
217 quick_release(); | |
218 return; | |
219 } | |
220 } | |
221 } | |
222 | |
223 private void enter_pause() { | |
224 MallocStressTest.pause_count.incrementAndGet(); | |
225 while (MallocStressTest.phase != MallocStressTest.TestPhase.release) { | |
226 try { | |
227 synchronized(MallocStressTest.mallocd_memory) { | |
228 MallocStressTest.mallocd_memory.wait(10); | |
229 } | |
230 } catch (InterruptedException e) { | |
231 } | |
232 } | |
233 } | |
234 | |
235 private void quick_release() { | |
236 List<MallocMemory> free_list; | |
237 while (true) { | |
238 synchronized(MallocStressTest.mallocd_memory) { | |
239 if (MallocStressTest.mallocd_memory.isEmpty()) return; | |
240 int size = Math.min(MallocStressTest.mallocd_memory.size(), 5000); | |
241 List<MallocMemory> subList = MallocStressTest.mallocd_memory.subList(0, size); | |
242 free_list = new ArrayList<MallocMemory>(subList); | |
243 subList.clear(); | |
244 } | |
245 for (int index = 0; index < free_list.size(); index ++) { | |
246 MallocMemory mem = free_list.get(index); | |
247 MallocStressTest.whiteBox.NMTFree(mem.addr()); | |
248 } | |
249 } | |
250 } | |
251 | |
252 private void slow_release() { | |
253 try { | |
254 Thread.sleep(10); | |
255 } catch (InterruptedException e) { | |
256 } | |
257 synchronized(MallocStressTest.mallocd_memory) { | |
258 if (MallocStressTest.mallocd_memory.isEmpty()) return; | |
259 int n = Math.abs(random.nextInt()) % MallocStressTest.mallocd_memory.size(); | |
260 MallocMemory mem = mallocd_memory.remove(n); | |
261 MallocStressTest.whiteBox.NMTFree(mem.addr()); | |
262 MallocStressTest.mallocd_total -= mem.size(); | |
263 } | |
264 } | |
265 } | |
266 } |