JVM运行时内存溢出以及解决办法

JVM有哪些运行时数据区

JVM运行时数据区有程序计数器、本地方法栈+虚拟机栈、堆、元数据区、直接内存。

其中只有程序计数器不是内存溢出,其他的都有可能会产生内存溢出。

栈内存溢出

当方法的调用深度过深,可能会导致栈内存溢出。

一般是发生在递归调用的场景中,没有定义好递归基导致的栈内存溢出。

创建线程内存溢出

当内存不够,创建线程也会导致内存溢出。因为每个新的线程都需要占用一定的内存。

  • 解决办法
    查看操作系统是否有使用线程数的限制。不要随意创建线程,使用线程池来对线程进行管理,创建新的线程池时,也进行仔细的评估,是否有创建线程池的必要。

堆内存溢出

堆中加载了大量的对象,或者有超大对象,或者有很多内存泄露,就会产生堆内存溢出。

当有超大对象时,可以采用分批处理的方式解决,减少单次处理的对象的大小。

有些开发会在数据库中查询大量的数据,然后在内存中进行过滤,这种情况可以通过在查询时,通过sql进行提前过滤,避免查询大量的数据。

内存泄露,就需要避免内存泄露,比如,避免使用过多的全局变量,尽量使用局部变量,如果非要使用全局变量,就需要在使用后及时清理。在使用ThreadLocal时,里面的值如果不使用了,及时调用ThreadLocal的remove方法,避免内存泄露。

直接内存溢出

直接内存一般是用来做文件IO或者网络IO的内存,是直接向操作系统申请内存,大小限制只跟操作系统剩余内存有关,但是也可以指定直接内存大小,当指定了直接内存大小,而程序又申请了非常大的直接内存空间,没有及时清理时,就会发生直接内存溢出。

在使用ByteBuffer中的allocateDirect()的时候会用到,很多javaNIO(像netty)的框架中被封装为其他的方法,出现该问题时会抛出java.lang.OutOfMemoryError: Direct buffer memory异常。

如果你在直接或间接使用了ByteBuffer中的allocateDirect方法的时候,而不做clear的时候就会出现类似的问题。

元空间内存溢出

元空间默认大小只跟操作系统的内存大小有关,是直接向操作系统申请内存,默认没有限制,但是最好配置一下,避免整个操作系统都收到影响。

元空间存储的是类字节码文件相关的信息。当系统代码本身很多,或者引用的第三方包很多,或者通过动态代码生成了很多动态的类的字节码,就会导致元空间溢出。

所以需要我们慎用第三方包,移除不需要的第三方包,对于生成大量生成动态类的框架,做好压力测试。

垃圾回收超时内存溢出

当垃圾回收时间超过一定的比例时,就会触发这个异常,这个比例可以通过JVM启动参数进行调节。(具体的参数可以查看poe记录)

  • 解决办法
    减少对象的生命周期,避免内存泄露。

系统杀死进程内存溢出

在描述该问题之前,先熟悉一点操作系统的知识:操作系统是建立在进程的概念之上,这些进程在内核中作业,其中有一个非常特殊的进程,称为"内存杀手(Out of memory killer)"。当内核检测到系统内存不足时,OOM killer被激活,检查当前谁占用内存最多然后将该进程杀掉。

一般Out of memory:Kill process or sacrifice child错会在当可用虚拟虚拟内存(包括交换空间)消耗到让整个操作系统面临风险时,会被触发。在这种情况下,OOM Killer会选择"流氓进程"并杀死它。

虽然增加交换空间的方式可以缓解Java heap space异常,还是建议最好的方案就是升级系统内存,让java应用有足够的内存可用,就不会出现这种问题。

参考

JVM内存溢出的几种方式与解决方法

相关推荐
流星52112211 小时前
GC 如何判断对象该回收?从可达性分析到回收时机的关键逻辑
java·jvm·笔记·学习·算法
JanelSirry11 小时前
我的应用 Full GC 频繁,怎么优化?
jvm
JH307311 小时前
jvm,tomcat,spring的bean容器,三者的关系
jvm·spring·tomcat
DKPT15 小时前
JVM直接内存和堆内存比例如何设置?
java·jvm·笔记·学习·spring
siriuuus15 小时前
JVM 垃圾收集器相关知识总结
java·jvm
小满、17 小时前
什么是栈?深入理解 JVM 中的栈结构
java·jvm·1024程序员节
百花~1 天前
JVM(Java虚拟机)~
java·开发语言·jvm
每天进步一点点dlb1 天前
JVM中的垃圾回收算法和垃圾回收器
jvm·算法
漫漫不慢.2 天前
蓝桥杯-16955 岁月流转
java·jvm·蓝桥杯
boy快快长大2 天前
【JVM】线上JVM堆内存报警,占用超90%
jvm