首先报OOM的原因无外乎有两大类:一类是堆空间不足,另一类是元空间不足(直接内存)
一、堆空间不足
1、内存泄漏问题导致
内存泄漏:是指在堆空间中一直有引用链引用着某些对象。导致对象不能被垃圾收集。
解决办法:如果是内存泄漏,课进一步通过工具查看泄漏对象到GC Roots 的引用链。于是就能找到泄漏对象是通过的路径与GC Roots 相关链并导致垃圾收集器无法自动回收它们的。掌握了泄漏对象的类型信息,以及GC Roots引用链的信息,就可以比较准确定位出泄漏代码的位置。
2、内存溢出导致
1) 如果不是内存泄漏,换句话说就是内存中的对象确实都是还必须存活着,栈中都还有引用。那就应当检查虚拟机的堆参数(-Xms和-Xmx),与机器物理内存对比看是否还可以调大堆内存大小,从代码上检查是否存在某些对象生命周期过长(静态修饰)、持有状态时间过长的情况,尝试减少程序运行期内存消耗。
2) 调节堆内存大小的参数:-Xms600m -Xmx600m,中英文之间没有空格
参数表示含义:将堆空间的初始化内存大小设置为600兆,最大堆空间内存大小设置为600兆。
另外;通常情况我们都是将两者大小设置为一样,这这样就避免初始堆空间不足而去不断申请扩内存或者降低内存这个过程,因为这个过程会耗时,有一定的开销。
3) 初始堆空间默认大小是物理内存的1 / 64(-Xms),最大堆空间默认大小是物理内存1 / 4(-Xmx)。
3、参数设置:
1)将Modules指定为JDK1.8(看你使用的是)
2)Java Complier 也设置为JDK1.8
3)进入Run添加参数设置,-Xms600m -Xmx600m
二、元空间(方法区)不足
首先我们都知道JDK1.8之后,方法区落地实现就是元空间。元空间的内存是不在JVM中的,而是在直接内存中,由于直接内存在Java堆外,因此它的大小不会直接受限于-Xmx指定的堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。
另外:由于元空间的垃圾是很难于被收集的,因为元空间的垃圾回收成本较高,又不受JVM内存回收管理,所以元空间的内存大小设置就显得尤为重要。
1、JDK1.7报异常为:OutofMemoryError:PermGen space
JDK1.7解决办法:设置参数 -XX:PerSize=?m -XX:MaxPermSize=?m
2、JDK1.8报异常为:OutofMemoryError:Metaspace
JDK1.8解决办法:设置参数 -XX:MetaspaceSize=500m -XX:MaxMetaspaceSize=500m
参数表示含义:将元空间的初始化内存大小设置为500兆,最大元空间内存大小设置为500兆。
另外;通常情况我们都是将两者大小设置为一样,这这样就避免初始元空间不足而去不断申请扩内存或者降低内存这个过程,因为这个过程会耗时,有一定的开销。
元空间的内存大小设置与堆空间设置类似,就是参数不同而已。默认元空间内存大小与堆空间内存大小相同。
有用点个关注,手留余香! ???? ???? ????