您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

「OOM」Java heap space原因与解决

时间:2020-08-27 16:54:13  来源:  作者:

JVM的OOM分为多种情况,下面会针对JAVA.lang.OutOfMemoryError: Java heap space这种情况讲解一下发生的原因与解决方案。

在JAVA应用启动时,会限制应用的使用空间。也就说,任何一个JAVA应用,都只能使用有限的内存空间。

JAVA的内存空间在JDK7及以前划分为堆与永久代。在JDK8之后移除了永久代,采用元空间来代替。

在启动时,通过指定JVM参数:`-Xmx` 来设置可使用的最大堆大小。如果没有显式的设置,则系统上默认为物理内存的1/4(根据物理内存的不同情况有不同的分配规则。但是普遍可以认为是1/4)。

发生java.lang.OutOfMemoryError: Java heap space异常时,代表着应用尝试从堆上申请一个区域时,堆没有可配的空间。(注:可能有可使用的物理内存,但是没有已经达到了JAVA应用可分配的内存大小)

JVM是很智能的,在即将发生OOM时,会进行一次FullGC以回收可回收的对象来释放空间。如果FullGC之后还是没有可满足大小的空间分配,才抛出java.lang.OutOfMemoryError: Java heap space。

java.lang.OutOfMemoryError: Java heap space正常是怎么发生的呢?

  • 突发高峰期:程序在正常的用户量和一定数据量时运行正常。但是,在某个高峰时导致超出预期阈值,内存存活对象使用空间的量超出最大堆,并且无法回收。
  • 内存泄露: 由于编程错误导致应用程序不再需要的对象(数据)一直被持有引用,导致无法被回收。随着时间的推移,泄露的内存对象占用了所有的可用堆空间。

分配合理的足够内存

最简单的解决方法就给JVM分配足够大的内存来满足运行程序的需求。

但是,需要注意在内存泄漏的情况下,分配再大的内存也只是推迟了java.lang.OutOfMemoryError: Java heap space的发生。

而且,加大了JVM堆内存,也会增加在GC时的暂停时间(STW),影响程序的吞吐量,增加延迟。

如何分配一个合理的内存空间,是需要针对GC进行优化的。也就是常说的JVM调优。

JVM调优可以参考:「JVM」GC——调优介绍

那么,如何调整通过分配JAVA堆空间来解决问题呢?

首先,需要了解以下这些问题:

  1. 哪些对象占用了大量的堆空间
  2. 在哪些代码中创建了这些对象

上述的问题可以通过JVM自身的jmap来dump出运行时的堆栈信息。然后通过如:MAT,JProfiler,jconsole等空间来进行内存对象占用的跟踪。

MAT使用可以参考:[JVM] MAT进阶使用

当然,这种方式是比较原始的方式。建议通过如:Plumbr等JVM监控工具来跟踪问题。

「OOM」Java heap space原因与解决

Plumbr的报告信息

以上图的监控举例简要说明一下如何适当的进行堆空间的大小分配。

上图所示中,可以得到如下信息:

  • 所有相关对象的整个GCRoot引用
  • 内存消耗最多的对象:
「OOM」Java heap space原因与解决

 

  • 这些对象在代码中的分配位置:
「OOM」Java heap space原因与解决

 

根据上述的信息, 我们可以得到这样的猜想:

这个程序的需要的运行空间超过248MB,并且是无法在一定时间内释放被回收。那么,按JVM调优的思路,建议分配的最大堆大小为:老年代活跃数据大小 * 3~4倍。

所以,我们第一次调整时,可以分配:248 * 4 = 992。

由于堆大小的无法确认,所以第一次调整直接调整为:-Xmx1024m。

单位:

-Xmx1024 即配置1024b = 1kb

-Xmx1024k 即配置1mb

-Xmx1024m 即配置1gb

-Xmx1g 即配置1gb

建议:

在配置-Xmx时,应该将-Xms也配置成相同大小。避免JVM需要动态调整堆空间大小带来的性能影响。



Tags:Java heap space   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
JVM的OOM分为多种情况,下面会针对java.lang.OutOfMemoryError: Java heap space这种情况讲解一下发生的原因与解决方案。在JAVA应用启动时,会限制应用的使用空间。也就说,任何...【详细内容】
2020-08-27  Tags: Java heap space  点击:(105)  评论:(0)  加入收藏
▌简易百科推荐
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(11)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(12)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(10)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(10)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(14)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(17)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(21)  评论:(0)  加入收藏
一、概述观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察...【详细内容】
2021-12-13  唯一浩哥    Tags:Java   点击:(16)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条