Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 5293|回复: 0

对Java OutOfMemory异常的探究

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-19 14:08:06 | 显示全部楼层 |阅读模式

    Java堆溢出

    虚拟机参数:

    -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

    将堆的最小值和最大值都限制成为20M,-XX:+HeapDumpOnOutOfMemoryError出现内存异常时令java虚拟机Dump堆内存转储快照

    代码

     1 import java.util.*;
     2 
     3 /**
     4  * Created by zcy on 2017/6/11.
     5  */
     6 public class TestHeapMemory {
     7 
     8     static class OOMObject{
     9 
    10     }
    11 
    12     public static void main(String[] args){
    13         List<OOMObject> list = new ArrayList<OOMObject>();
    14         while (true){
    15             list.add(new OOMObject());
    16         }
    17     }
    18 }

    运行出现异常:

    java.lang.OutOfMemoryError: Java heap space
    Dumping heap to java_pid9392.hprof ...
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:3210)
        at java.util.Arrays.copyOf(Arrays.java:3181)
        at java.util.ArrayList.grow(ArrayList.java:261)
        at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
        at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
    Heap dump file created [28361944 bytes in 0.134 secs]
        at java.util.ArrayList.add(ArrayList.java:458)
        at TestHeapMemory.main(TestHeapMemory.java:15)

    为了查看实时堆的使用情况,我们可以安装VisualVM Launcher。

    安装请参考http://www.oschina.net/translate/setting-up-visualvm-in-under-5-minutes

    使用VisualVM Launcher调试程序(需要在程序中sleep延时),发现堆内存一路上涨,最后崩掉了。

    查看dump file,绝大多数内存都被数组占用了

    要解决Heap的OutOfMemory,一般的手段是使用内存映像分析工具,分析堆转储文件,重点是确认内存中的对象是否是必要的,也就是要先分清楚到底是出现了内存泄露还是内存溢出。

    如果是内存泄露,可以进一步使用工具查看到GC Roots的引用链。于是就能找到泄露对象是通过怎样的路径与GC Roots相关联,导致GC无法自动回收。

    如果每个对象都有必要存活着,那么应该检查堆参数(-Xms和-Xmx)是否还可以调大

     

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

    两种异常:

    • StackOverFlow异常:线程请求的栈深度大于虚拟机允许的最大深度。
    • OutOfMemory异常:虚拟机扩展栈时无法申请到足够的内存空间。

    虚拟机参数:

    -Xss128k

    代码:

     1 /**
     2  * Created by zcy on 2017/6/11.
     3  */
     4 public class TestStackOF {
     5 
     6     private static int stackLength = 0;
     7 
     8     public static void stackLeak() throws InterruptedException {
     9         stackLength++;
    10         stackLeak();
    11     }
    12 
    13     public static void main(String args[]) throws Throwable {
    14         try{
    15             TestStackOF.stackLeak();
    16         }
    17         catch (Throwable e){
    18             System.out.println("stack length is: " + stackLength);
    19             throw e;
    20         }
    21     }
    22 }

    运行结果:

    stack length is: 1102
    Exception in thread "main" java.lang.StackOverflowError
        at TestStackOF.stackLeak(TestStackOF.java:9)
        at TestStackOF.stackLeak(TestStackOF.java:10)
        at TestStackOF.stackLeak(TestStackOF.java:10)
        at TestStackOF.stackLeak(TestStackOF.java:10)
            ...

    最后总结一下:

    • 对于StackOverFlow异常:栈深度(1000-2000)绝大多数情况下都够用了。有错误堆栈可以阅读。
    • 如果由于建立线程过多导致的内存溢出,可以减少堆容量和每个进程的栈容量换取更多的线程。

     

    方法区和运行时常量池溢出

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-5 07:48 , Processed in 0.062028 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表