24 package nsk.share.gc.gp; |
24 package nsk.share.gc.gp; |
25 |
25 |
26 import java.io.IOException; |
26 import java.io.IOException; |
27 import java.io.PrintWriter; |
27 import java.io.PrintWriter; |
28 import java.io.StringWriter; |
28 import java.io.StringWriter; |
|
29 import java.lang.invoke.*; |
29 import java.util.*; |
30 import java.util.*; |
30 import nsk.share.gc.gp.array.*; |
31 import nsk.share.gc.gp.array.*; |
31 import nsk.share.gc.gp.string.*; |
32 import nsk.share.gc.gp.string.*; |
32 import nsk.share.gc.gp.list.*; |
33 import nsk.share.gc.gp.list.*; |
33 import nsk.share.gc.gp.tree.*; |
34 import nsk.share.gc.gp.tree.*; |
192 */ |
193 */ |
193 public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor) { |
194 public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor) { |
194 return eatMemory(stresser, gp, initialFactor, minMemoryChunk, factor, OOM_TYPE.ANY); |
195 return eatMemory(stresser, gp, initialFactor, minMemoryChunk, factor, OOM_TYPE.ANY); |
195 } |
196 } |
196 |
197 |
|
198 static int numberOfOOMEs = 0; |
|
199 |
|
200 /** |
|
201 * Minimal wrapper of the main implementation. Catches any OOM |
|
202 * that might be thrown when rematerializing Objects when deoptimizing. |
|
203 * |
|
204 * It is Important that the impl is not inlined. |
|
205 */ |
|
206 |
|
207 public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) { |
|
208 try { |
|
209 // Using a methodhandle invoke of eatMemoryImpl to prevent inlining of it |
|
210 MethodHandles.Lookup lookup = MethodHandles.lookup(); |
|
211 MethodType mt = MethodType.methodType( |
|
212 int.class, |
|
213 ExecutionController.class, |
|
214 GarbageProducer.class, |
|
215 long.class, |
|
216 long.class, |
|
217 long.class, |
|
218 OOM_TYPE.class); |
|
219 MethodHandle eat = lookup.findStatic(GarbageUtils.class, "eatMemoryImpl", mt); |
|
220 return (int) eat.invoke(stresser, gp, initialFactor, minMemoryChunk, factor, type); |
|
221 } catch (OutOfMemoryError e) { |
|
222 return numberOfOOMEs++; |
|
223 } catch (Throwable t) { |
|
224 throw new RuntimeException(t); |
|
225 } |
|
226 } |
|
227 |
197 /** |
228 /** |
198 * Eat memory using given garbage producer. |
229 * Eat memory using given garbage producer. |
199 * |
230 * |
200 * Note that this method can throw Failure if any exception |
231 * Note that this method can throw Failure if any exception |
201 * is thrown while eating memory. To avoid OOM while allocating |
232 * is thrown while eating memory. To avoid OOM while allocating |
209 * @param minMemoryChunk determines when to stop |
240 * @param minMemoryChunk determines when to stop |
210 * @param factor factor to divide the array size by. A value of 0 means that method returns after first OOME |
241 * @param factor factor to divide the array size by. A value of 0 means that method returns after first OOME |
211 * @param type of OutOfMemory Exception: Java heap space or Metadata space |
242 * @param type of OutOfMemory Exception: Java heap space or Metadata space |
212 * @return number of OOME occured |
243 * @return number of OOME occured |
213 */ |
244 */ |
214 public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) { |
245 |
215 int numberOfOOMEs = 0; |
246 public static int eatMemoryImpl(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) { |
|
247 numberOfOOMEs = 0; |
216 try { |
248 try { |
217 byte[] someMemory = new byte[200000]; //200 Kb |
249 byte[] someMemory = new byte[200000]; //200 Kb |
218 try { |
250 try { |
219 Runtime runtime = Runtime.getRuntime(); |
251 Runtime runtime = Runtime.getRuntime(); |
220 long maxMemory = runtime.maxMemory(); |
252 long maxMemory = runtime.maxMemory(); |