JVM内存溢出示例

来源:互联网 发布:手机数据太多如何删除 编辑:程序博客网 时间:2024/05/21 07:00

1Java 堆溢出

下面的程中我们限制Java 堆的大小为20MB,不可扩展(将堆的最小值-Xms 

数与最大值-Xmx 参数设置为一样即可避免堆自动扩展),通过参数-XX:+HeapDump

OnOutOfMemoryError 可以让虚拟机在出现内存溢出异常时Dump 出当前的内存堆转储

快照以便事后进行分析。

参数设置如下




package com.yhj.jvm.memory.heap;

 

import java.util.ArrayList;

import java.util.List;

 

/**

 * @Described:堆溢出测试

 * @VM args:-verbose:gc -Xms20M -Xmx20M -XX:+PrintGCDetails

 * @author YHJ create at 2011-11-12 下午07:52:22

 * @FileNmae com.yhj.jvm.memory.heap.HeapOutOfMemory.java

 */

public class HeapOutOfMemory {

 

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 下午07:52:18

     */

    public static void main(String[] args) {

       List<TestCase> cases = new ArrayList<TestCase>();

       while(true){

           cases.add(new TestCase());

       }

 

    }

 

}

/**

 * @Described:测试用例

 * @author YHJ create at 2011-11-12 下午07:55:50

 * @FileNmae com.yhj.jvm.memory.heap.HeapOutOfMemory.java

 */

class TestCase{

   

}


ava 堆内存的OutOfMemoryError异常是实际应用中最常见的内存溢出异常情况。出现Java 堆内

存溢出时,异常堆栈信息“java.lang.OutOfMemoryError”会跟着进一步提示“Java heap

space”

要解决这个区域的异常,一般的手段是首先通过内存映像分析工具(如Eclipse

Memory Analyzer)对dump 出来的堆转储快照进行分析,重点是确认内存中的对象是

否是必要的,也就是要先分清楚到底是出现了内存泄漏(Memory Leak)还是内存溢

出(Memory Overflow)。图2-5 显示了使用Eclipse Memory Analyzer 打开的堆转储快

照文件。

如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots 的引用链。于是就

能找到泄漏对象是通过怎样的路径与GC Roots 相关联并导致垃圾收集器无法自动回收

它们的。掌握了泄漏对象的类型信息,以及GC Roots 引用链的信息,就可以比较准确

地定位出泄漏代码的位置。

如果不存在泄漏,换句话说就是内存中的对象确实都还必须存活着,那就应当检查

虚拟机的堆参数(-Xmx -Xms),与机器物理内存对比看是否还可以调大,从代码上

检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期

的内存消耗。

以上是处理Java 堆内存问题的简略思路,处理这些问题所需要的知识、工具与经验

在后面的几次分享中我会做一些额外的分析。

2java栈溢出

package com.yhj.jvm.memory.stack;

/**

 * @Described:栈层级不足探究

 * @VM args:-Xss128k

 * @author YHJ create at 2011-11-12 下午08:19:28

 * @FileNmae com.yhj.jvm.memory.stack.StackOverFlow.java

 */

public class StackOverFlow {

   

   

    private int i ;

   

    public void plus() {

       i++;

       plus();

    }

 

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 下午08:19:21

     */

    public static void main(String[] args) {

       StackOverFlow stackOverFlow = new StackOverFlow();

       try {

           stackOverFlow.plus();

       } catch (Exception e) {

           System.out.println("Exception:stack length:"+stackOverFlow.i);

           e.printStackTrace();

       } catch (Error e) {

           System.out.println("Error:stack length:"+stackOverFlow.i);

           e.printStackTrace();

       }

 

    }

 

}

3、常量池溢出(常量池都有哪些信息,我们在后续的JVM类文件结构中详细描述)

 

package com.yhj.jvm.memory.constant;

 

import java.util.ArrayList;

import java.util.List;

 

/**

 * @Described:常量池内存溢出探究

 * @VM args : -XX:PermSize=10M -XX:MaxPermSize=10M

 * @author YHJ create at 2011-10-30 下午04:28:30

 * @FileNmae com.yhj.jvm.memory.constant.ConstantOutOfMemory.java

 */

public class ConstantOutOfMemory {

 

    /**

     * @param args

     * @throws Exception

     * @Author YHJ create at 2011-10-30 下午04:28:25

     */

    public static void main(String[] args) throws Exception {

       try {

           List<String> strings = new ArrayList<String>();

           int i = 0;

           while(true){

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

           }

       } catch (Exception e) {

           e.printStackTrace();

           throw e;

       }

 

    }

 

}

4、方法去溢出

package com.yhj.jvm.memory.methodArea;

 

import java.lang.reflect.Method;

 

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

 

/**

 * @Described:方法区溢出测试

 * 使用技术 CBlib

 * @VM args : -XX:PermSize=10M -XX:MaxPermSize=10M

 * @author YHJ create at 2011-11-12 下午08:47:55

 * @FileNmae com.yhj.jvm.memory.methodArea.MethodAreaOutOfMemory.java

 */

public class MethodAreaOutOfMemory {

 

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 下午08:47:51

     */

    public static void main(String[] args) {

       while(true){

           Enhancer enhancer = new Enhancer();

           enhancer.setSuperclass(TestCase.class);

           enhancer.setUseCache(false);

           enhancer.setCallback(new MethodInterceptor() {

              @Override

              public Object intercept(Object arg0, Method arg1, Object[] arg2,

                     MethodProxy arg3) throws Throwable {

                  return arg3.invokeSuper(arg0, arg2);

              }

           });

           enhancer.create();

       }

    }

 

}

/**

 * @Described:测试用例

 * @author YHJ create at 2011-11-12 下午08:53:09

 * @FileNmae com.yhj.jvm.memory.methodArea.MethodAreaOutOfMemory.java

 */

class TestCase{

   

}

5、直接内存溢出

package com.yhj.jvm.memory.directoryMemory;

 

import java.lang.reflect.Field;

 

import sun.misc.Unsafe;

 

/**

 * @Described:直接内存溢出测试

 * @VM args: -Xmx20M -XX:MaxDirectMemorySize=10M

 * @author YHJ create at 2011-11-12 下午09:06:10

 * @FileNmae com.yhj.jvm.memory.directoryMemory.DirectoryMemoryOutOfmemory.java

 */

public class DirectoryMemoryOutOfmemory {

 

    private static final int ONE_MB = 1024*1024;

    private static int count = 1;

 

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 下午09:05:54

     */

    public static void main(String[] args) {

       try {

           Field field = Unsafe.class.getDeclaredField("theUnsafe");

           field.setAccessible(true);

           Unsafe unsafe = (Unsafe) field.get(null);

           while (true) {

              unsafe.allocateMemory(ONE_MB);

              count++;

           }

       } catch (Exception e) {

           System.out.println("Exception:instance created "+count);

           e.printStackTrace();

       } catch (Error e) {

           System.out.println("Error:instance created "+count);

           e.printStackTrace();

       }

 

    }

 

}


0 0
原创粉丝点击