美文网首页
内存溢出测试

内存溢出测试

作者: 小兽_e1ba | 来源:发表于2019-06-13 14:32 被阅读0次

    内存溢出测试(OutOfMemoryError)

    Java堆溢出

    /**

    * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

    */

    publicclassHeapOOM{

    staticclassOOMObject{}

    publicstaticvoidmain(String[] args){

    System.out.println("test");

    Listlist=newArrayList<>();

    while(true){

    list.add(newOOMObject());

    }

    }

    }

    结果:

    java.lang.OutOfMemoryError:Javaheapspace

    Dumpingheaptojava_pid3404.hprof...

    Heapdumpfilecreated[22045981 bytes in 0.663 secs]

    分析:

    内存泄露

    导致GC无法自动回收

    分析与GC Roots 相关联的路径

    内存溢出

    检查虚拟机堆参数(-Xmx与-Xms)

    虚拟机栈与本地方法栈溢出

    /**

    * VM Args: -Xss128k

    */

    publicclassStackOverFlow{

    privateintstackLength  =1;

    publicvoidstackLeak(){

    stackLength ++;

    stackLeak();

    }

    publicstaticvoidmain(String[] args){

    StackOverFlow oom =newStackOverFlow();

    try{

    oom.stackLeak();

    }catch(Throwable e){

    System.out.println("stack length:"+oom.stackLength);

    throwe;

    }

    }

    }

    结果:

    Exceptioninthread"main"java.lang.StackOverflowError

    stacklength:2271

    atcom.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:9)

    atcom.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:10)

    atcom.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:10)

    atcom.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:10)

    以下省略.....

    方法区和运行时常量溢出

    /**

    * VM Args -XX:PermSize=10M -XX:MaxPermSize=10M

    * jdk1.6以前的版本,常量池分配在永久代,可以使用以上的参数来限值方法区的大小。

    * jdk1.7以后逐步 ”去永久代“

    */

    publicclassRuntimeConstantPoolOOM{

    publicstaticvoidmain(String[] args){

    //使用List保持着常量池引用,避免Full GC回收常量池行为

    Listlist=newArrayList<>();

    inti =0;

    while(true){

    //intern()方法的作用是如果常量池中有则返回,如果没有则放入常量池再返回

    list.add(String.valueOf(i++).intern());

    }

    }

    }

    结果:

    Exceptioninthread"main"java.lang.OutOfMemoryError:PermGenspace

    atjava.lang.String.intern(Nativemethod)

    atcom.laowang.vm.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:10)

    引申:String.intern()返回引用测试

    publicclassStringIntern{

    publicstaticvoidmain(String[] args){

    String str1 =newStringBuilder("计算机").append("软件").toString();

    System.out.println(str1.intern() == str1);

    String str2 =newStringBuilder("ja").append("va").toString();

    System.out.println(str2.intern() == str2);

    }

    }

    结果:

    jdk1.6:falsefalse

    jdk1.7:truefalse

    分析:

    jdk1.6:

    intern()方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中实例的引用

    StringBuilder创建的字符串实例在堆上

    不是同一个引用,所以都是false

    jdk1.7:

    intern()方法不会复制实例,只是在常量池中记录首次出现的实例引用

    是同一个引用

    方法区OOM代码

    /**

    * VM Args -XX:PermSize=10M -XX:MaxPermSize=10M

    * 同样在jdk1.7以后没有效果

    * 在jdk1.6以前会出现OOM

    */

    publicclassJavaMethodAreaOOM{

    publicstaticvoidmain(finalString[] args){

    while(true){

    Enhancer enhancer =newEnhancer();

    enhancer.setSuperclass(OOMObject.class);

    enhancer.setUseCache(false);

    enhancer.setCallback(newMethodInterceptor() {

    publicObjectintercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)throwsThrowable{

    returnmethodProxy.invokeSuper(objects,args);

    }

    });

    enhancer.create();

    }

    }

    staticclassOOMObject{

    }

    }

    结果:

    Causedby:java.lang.OutOfMemoryError:PermGenspace

    atjava.lang.ClassLoader.defineClass1(NativeMethod)

    atjava.lang.ClassLoader.defineClassCond(ClassLoader.java:632)

    atjava.lang.ClassLoader.defineClass(ClassLoader.java:616)

    ... 8more

    本机直接内存溢出

    直接内存可以使用-XX:MaxDirectMemorySize指定

    默认与Java堆最大值(-Xms指定)一样

    /**

    * VM Args: -Xmx20M -XX:MaxDirectMemorySize=10M

    */

    publicclassDirectMemoryOOM{

    privatestaticfinalint_1MB =1024*1024;

    publicstaticvoidmain(String[] args) throws Exception{

    Field unsafeField = Unsafe.class.getDeclaredFields()[0];

    unsafeField.setAccessible(true);

    Unsafeunsafe= (Unsafe)unsafeField.get(null);

    while(true){

    unsafe.allocateMemory(_1MB);

    }

    }

    }

    结果:

    Exceptioninthread"main"java.lang.OutOfMemoryError

    atsun.misc.Unsafe.allocateMemory(NativeMethod)

    atcom.laowang.vm.DirectMemoryOOM.main(DirectMemoryOOM.java:18)

    -END-

    相关文章

      网友评论

          本文标题:内存溢出测试

          本文链接:https://www.haomeiwen.com/subject/ychsfctx.html