欢迎光临散文网 会员登陆 & 注册

Java OOM 异常原因及解决方案有哪些?

2023-08-24 08:35 作者:Java一桶天下  | 我要投稿


对于 Java 的运行时数据区域而言,除了程序计数器外,其他几个区域都可能会出现 OutOfMemoryError 异常。

堆溢出

  • 通过 -Xms 参数设置堆内存最小值,-Xmx 设置堆内存最大值,比如 -Xms20m -Xmx20m

  • 解决方案:通过内存映像工具(如 Eclipse Memory Analyzer)对 Dump 出来的堆转存快照(使用参数 -XX:+HeapDumpOnOutOfMemoryError 获取)进行分析:

    • 如果溢出原因是内存泄漏,则分析如何让垃圾回收器对其进行回收(通过工具查看对象到 GC Roots 的引用链,找到泄露对象的引用路径,找到具体代码位置,分析如何写代码进行回收)。

    • 如果溢出问题不是内存泄漏,也就是内存中的对象必须存活,则需要增加堆参数(-Xms、-Xmx)或者检查代码逻辑是否存在问题(如是否存在某些对象生命周期过长、持有状态时间过长等)。

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

  • 通过 -Xss 参数设置栈容量,比如 -Xss128k

  • 在单线程条件下,由于 HotSpot 虚拟机不支持栈的动态扩展(其他的可能支持),使得线程运行时不会因为扩展而出现内存溢出的情况,只会因为栈容量无法容纳新的栈帧而出现 StackOverflowError 异常(栈帧过多 /栈容量太小)。 

  • 在多线程条件下,栈内存越大,那么能运行的线程越少(因为物理机的内存是固定的,且栈是线程私有的),因此在多线程条件下,如果运行大量的线程,也会出现 OOM 异常。(但是这样产生的内存溢出异常和栈空间是否足够并不存在任何直接的关系,主要取决于操作系统本身的内存使用状态)

方法区溢出

  • -XX:MaxMetaspaceSize 用于设置元空间的最大值。默认为-1,即不限制。

  • -XX:MetaSpaceSize 用于指定元空间的初始空间大小。

  • -XX:minMetaspaceFreeRation 用于在垃圾收集之后控制最小的元空间剩余容量的百分比,可减少因为元空间不足导致的垃圾收集的频率。


Java OOM 异常原因及解决方案有哪些?的评论 (共 条)

分享到微博请遵守国家法律