JVM虚拟机内存溢出

本节内容参考书籍:深入理解Java虚拟机

另外,我们讲解的虚拟机为java的 HotSpot JVM,其他虚拟机不讲解。

一、堆内存溢出

     1、设置eclipse中的相关参数。

           -Xms:堆的最小值

           -Xmx:堆的最大值      (这两个值设置一样,可避免对自动扩展)

     

    2、相关代码

          java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。

    demo演示:
    /**
     * 堆溢出
     */
    static class OOMObject{
        
    }
    public static void main (String[] args){
        System.out.println("测试堆溢出");
        List<OOMObject> list = new ArrayList<OOMObject>();
        
        while(true){
            list.add(new OOMObject());
        }
    }

   3、结果

   

   4、分析:

         一般的手段是先通过内存影像工具(如Eclipse Memory Analyzer)对Dump出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,也就是要分清楚到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)

       (1)如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链。于是就能找到泄漏对象是通过怎么样的路径与GC Roots引用链的信息,就可以比较准确地定位出泄漏代码的位置。

       (2)如果不存在泄漏,换句话说,就是内存中的对象确实都还必须存活着,那就应当检查虚拟机的对参数(-Xmx -Xms),与物理内存对比看是否还可以调大,从代码上检查:

            a)是否存在某些对象生命周期过长

            b)持有状态时间过长

            c)尝试减少程序运行期的内存消耗


二、虚拟机栈和本地方法栈溢出

   1、设置eclipse中的相关参数。

              -Xss128k

             说明一点:我们java用的HotSpot虚拟机中,并不区分虚拟机栈和本地方法栈。因此,对于HotSpot来说,虽然-Xoss(设置本地方法栈)参数存在,但实际上是无效的,

    2、相关代码

      /**
     * 栈溢出
     */

    private  int stackLength = 1;


    public void stackLeak() {
        stackLength++;
        stackLeak();
    }

    public static void main(String[] args) {
        JVMOutOfMemoryTest outOfMemoryTest = new JVMOutOfMemoryTest();
        try {
            outOfMemoryTest.stackLeak();
        } catch (Throwable e) {
            // TODO: handle exception
            System.out.println("stack length------------------:"+outOfMemoryTest.stackLength);
            throw e;
        }
    }

    3、结果

      Java虚拟机中定义了两种规范:

     (1)如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出栈溢出异常

     (2)如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出内存溢出异常

  


    4、分析

        如果使用虚拟机默认参数,栈深度在大多数情况下达到1000~2000完全没有问题,对于正常的方法调用(包括递归),这个深度应该完全够用。但是,如果是建立过多线程导致的内存溢出,在不能减少线程数或者更换64为虚拟机的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值