内存溢出7 内存溢出场景模拟
内存溢出场景模拟
Java Method Stack 栈溢出实验什么时候会让 Java Method Stack 栈溢出啊?栈的基本特点就是 FILO(First In Last Out) 如果 in 的太多而 out 的太少 就好 overflow 了 而 Java Method Stack 的功能就是保存每一次函数调用时的 现场 即为入栈 函数返回就对应着出栈 所以函数调用的深度越大 栈就变得越大 足够大的时候就会溢出 所以模拟 Java Method Stack 溢出 只要不断递归调用某一函数就可以
程序源码
// Author Poechant // Blog /poechant // Email zhognchao ustc# (# >@)
// Args verbose gc Xss K
package sinosuperman main
public class Test {
private int stackLength =
public void stackOverflow() { ++stackLength stackOverflow() }
public static void main(String[] args) throws Throwable { Test test = new Test()
try { test stackOverflow() } catch (Throwable e) { System out println( stack length + test stackLength) throw e }运行结果
stack length Exception in thread main java lang StackOverflowError at sinosuperman main Test stackOverflow(Test java )
at sinosuperman main Test stackOverflow(Test java )
……
Java Method Stack 内存溢出实验Heap 内存溢出
堆是用来存储对象的 当然对象不一定都存在堆里(由于逃逸技术的发展) 那么堆如果溢出了 一定是不能被杀掉的对象太多了 模拟 Heap 内存溢出 只要不断创建对象并保持有引用存在即可
程序源码
// Author Poechant // Blog /poechant // Email zhongchao ustc# (# >@)
// Args verbose gc Xmx m Xms m
package sinosuperman main
import java util ArrayList import java util List
public class Test {
private static class HeapOomObject { }
public static void main(String[] args) { List<HeapOomObject> list = new ArrayList<HeapOomObject>() while (true) { list add(new HeapOomObject()) }运行结果
[GC K > K( K) secs] [GC K > K( K) secs] [GC K( K) secs] [Full GC K > K( K) secs] [Full GC K > K( K) secs] [GC K( K) secs] [Full GC K > K( K) secs] [Full GC K > K( K) secs] [Full GC K > K( K) secs] [GC K( K) secs] [Full GC K > K( K) secs] [Full GC K > K( K) secs] [Full GC K > K( K) secs] Exception in thread main java lang OutOfMemoryError Java heap space at sinosuperman main Test main(Test java )
Method Area 内存溢出也就是 Non heap 是用来存储 Object Class Data 常量 静态变量 JIT 编译后的代码等 如果该区域溢出 则说明某种数据创建的实在是太多了 模拟的话 可以不断创建新的 class 直到溢出为止
以下代码使用到 cglib jar 和 asm all jar
程序源码
package sinosuperman main
import java lang reflect Method
import net sf cglib proxy Enhancer import net sf cglib proxy MethodInterceptor import net sf cglib proxy MethodProxy

public class Test { static class MethodAreaOomObject { } public static void main(String[] args) { while(true){ Enhancer enhancer = new Enhancer() enhancer setSuperclass(MethodAreaOomObject class) enhancer setUseCache(false) enhancer setCallback(new MethodInterceptor() { public Object intercept(Object obj Method method Object[] args MethodProxy proxy) throws Throwable { return proxy invoke(obj args) } }) enhancer create() }运行结果
Exception in thread main re CodeGenerationException java lang reflect InvocationTargetException——>null at re AbstractClassGenerator create(AbstractClassGenerator java )
at net sf cglib proxy Enhancer createHelper(Enhancer java )
at net sf cglib proxy Enhancer create(Enhancer java )
at sinosuperman main Test main(Test java )
Caused by java lang reflect InvocationTargetException at sun reflect GeneratedMethodAccessor invoke(Unknown Source)
at sun reflect DelegatingMethodAccessorImpl invoke(DelegatingMethodAccessorImpl java )
at java lang reflect Method invoke(Method java )
at re ReflectUtils defineClass(ReflectUtils java )
at re AbstractClassGenerator create(AbstractClassGenerator java )
…… more Caused by java lang OutOfMemoryError PermGen space at java lang ClassLoader defineClass (Native Method)
at java lang ClassLoader defineClassCond(ClassLoader java )
at java lang ClassLoader defineClass(ClassLoader java )
…… more Runtime Constant Pool in Method Area 内存溢出在运行时产生大量常量就可以实现让 Method Area 溢出的目的 运行是常量可以用 String 类的 intern 方法 不断地产生新的常量
程序源码
package sinosuperman main
import java util ArrayList import java util List
public class Test { public static void main(String[] args) { List<String> list = new ArrayList<String>() int i = while (true) { list add(String valueOf(i++) intern()) }运行结果
Exception in thread main java lang OutOfMemoryError PermGen space at java lang String intern(Native Method)
at sinosuperman main Test main(Test java )
lishixinzhi/Article/program/Java/hx/201311/26375