Java内存溢出异常(二)

    OutOfMemoryError简称OOM   java.lang.OutOfMemoryError:Java heap space

    1. 除了程序计数器外,其他几个区域均会出现内存溢出情况。

    2. 虚拟机栈如果动态扩展栈空间的情况下获取不到内存同样会发生内存溢出。

    堆内存溢出的场景:堆用于存储对象实例,只要不断创建对象,并保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象(垃圾回收算法可达性分析),那么对象达到一定数量后超过最大的容量限制就会产生内存溢出。

    堆初始化的值,也就是最小的默认值-Xms设置。

    当内存不够就会再次申请,申请上限可通过-Xmx设置。

    内存溢出的时候可以使用-XX:HeapDumpOutOfMemoryError参数Dump当前内存堆转出快照进行分析,可以设置 -XX:HeapDumpPath可以指定快照文件路径。

    堆内存溢出一般先通过内存映像分析工具(如Memory Analyzer)堆Dump出来的堆转出快照进行分析,重点分析是内存泄漏还是内存溢出的问题。

    内存泄漏(Memory Leak):申请后的内存无法进行回收,长时间内存泄漏会造成内存溢出,通过分析工具可以找到泄漏对象的类型信息及GC Roots引用链,可以比较精准的定位出现泄漏代码的位置。

    内存溢出(OutOf Memory):无法继续申请内存。如不是上述内存泄漏导致的,可以设置虚拟机的堆参数-Xms-Xmx,或者从代码上检查是否存在某些对象生命周期过长等情况尝试减少程序运行期的内存消耗。

    虚拟机栈和本地方法栈溢出 java.lang.StackOverflowError

    在HotSport中并不区分虚拟机栈与本地方法栈,因此对于HotSport来说,只能设置-Xss参数设定。

    虚拟机栈存在的两种异常,前面一章描述过:

    1. 栈溢出StackOverflowError:线程请求的栈深度大于虚拟机所允许的最大深度;

    2. 内存溢出OutOfMemoryError:虚拟机栈可以动态扩展的时候,无法获取到更多的内存空间;

    栈异常常见的情况:

    1. 方法递归调用。

    2. 方法内定义大量变量,增大此方法中栈帧的本地变量表的长度。

    当多线程的情况下,就要考虑系统能够分配的资源,虚拟机中占用资源主要在于最大堆、最大方法区、其余基本就是栈的内存了。程序计数器很少可以忽略不记。

    当无法分配过多的内存,而需要大量线程执行的情况下,就需要考虑减少最大堆、最大方法区的容量来换取更多的线程执行。

    方法区和运行时常量池溢出 java.lang.OutOfMemoryError:PermGen Space

    参数-XX:PermSize和-XX:MaxPermSize设置方法区的最大最小存储

    之前描述过String.intern()方法会将该字符串添加到字符串常量池,当然常量池比作的是Set集合。

    方法区用于存储Class的相关信息、类命、访问修饰符、常量池、字段描述、方法描述等。当运行时产生大量的类区填满方法区、或大量的常量池数据,直至内存不够都会产生内存溢出。

    大量的反射、动态代理以及spring等框架使用的cglib这类字节码实现的类增强技术,都会需要更多的方法区来保证动态生成的class可以加载入内存;

    还有大量的jsp或动态产生的jsp文件(Jsp第一次运行时需要编译为Java类)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值