OOM发生的可能(深入理解Java虚拟机读书笔记)

一、堆溢出

1. 堆用于存储对象的实例,-Xms参数表示堆容量的最小值,-Xmx表示堆容量的最大值。当这两个参数值相同时,表明该堆不可以进行动态扩展。我们可以通过-XX: +HeapDumpOnOutOfMemoryError让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便分析。

2. 首先通过内存印象分析工具对Dump出的堆转储快照进行分析,确认异常属于内存泄漏还是内存溢出。

3. 如果是内存泄漏,则需要进一步查看泄漏对象到GC Roots的引用链,查找出泄漏对象与GC Root如何相关联导致垃圾收集器无法回收,从而准确定位出泄漏代码的位置。

4. 如果不是,就检查堆参数,与机器物理内存对比看是否可以调大,从代码上检查是否存在某些对象生命周期过长、持有时间状态过长的情况,尝试减少程序运行期的内存消耗。

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

1. 在Hotspot虚拟机中,虽然存在-Xoss参数设置本地方法栈大小,但栈容量实际只由-Xss确定。栈抛出异常有两种:StackOverflowError异常和OutOfMemoryError异常。但本质上其实是对一种事情的两种描述,因为栈空间不足时,有两种可能,内存太小或使用的栈空间太大。

2. 在该书中提到,“单个线程下,无论是由于栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机都是抛出StackOverflowError异常”,但如果不限于但线程,而是不断建立线程会抛出内存溢出的异常。针对这种情况,可以考虑减少最大堆(Xmx)和减少栈容量来换取更多的线程。

你可能感兴趣的:(OOM发生的可能(深入理解Java虚拟机读书笔记))