Java.lang.outofmemoryerror: java heap space

2025年5月6日 | 阅读 6 分钟

错误本身的名称就表明这是一个内存不足的错误,当 JVM 无法在堆内存中分配对象时,就会抛出此类错误。因此,在本节中,我们将讨论 Java.lang.outofmemory 错误、堆空间以及如何修复该错误。

Java 中的堆空间是什么

Java 编程语言 中,用户创建一个对象,该对象就存储在 Java 的堆区域中。Java 限制 Java 应用程序只能使用有限的内存。JVM 架构由基本工具和库组成,空间区域分为两个不同的部分,即 **堆空间和 Permgen(也称为永久代)**。因此,当启动 JVM 时,会设置堆空间和永久代的大小。

什么是 Java.lang.outofmemoy 错误

Java 虚拟机 发现没有足够的内存来存储堆空间中的对象时,就会抛出错误,因此,JVM 会抛出错误,表明由于没有更多空间用于存储,因此无法分配该对象。在 Java 编程语言中,抛出 OutOfMemoryError 意味着:

  • 用户正在做一些错误的事情,这意味着用户试图处理大量数据或长时间持有对象。
  • 此类内存错误也意味着发生了用户无法处理的问题,例如缓存字符串的第三方库或部署后不进行清理的应用程序服务器。
  • 有时,它也可能意味着此错误与堆上的对象无关。当无法满足本地分配时,也可能由本地库代码抛出,例如,如果交换空间不足。

导致 outofmemory 错误的程序

下面的程序代码

程序片段

Java.lang.outofmemoryerror: java heap space

输出

Java.lang.outofmemoryerror: java heap space

什么原因导致 Java.lang.outofmemory 错误?

JVM 抛出 outofmemory 错误的原因如下:

  1. 糟糕的编程方法:发生此类错误可能意味着无法在 Java 堆中分配对象。不一定总是意味着内存泄漏。也可能是配置问题,即应用程序指定的堆大小或默认堆大小不足。在其他情况下,对于长期运行的应用程序,错误可能表明应用程序无意中保留了对对象的引用,从而阻止了对象被垃圾回收。因此,它等同于内存泄漏。这是因为应用程序调用的 API(应用程序编程接口)也可能无意中持有对象引用。
  2. 数据使用:几乎所有 Java 应用程序都设计为在特定时间内处理一定数量的用户。如果用户数量(用户限制)超过了,并且阈值变得比预期值更高,则操作将终止,并抛出 java.lang.outofmemory 错误。
  3. 内存泄漏:由于使用了糟糕的编程方法,可能会导致大量内存消耗,结果导致 Java 堆空间中留下一些对象。泄露的对象几乎消耗了 JVM 中的所有内存,因此没有更多内存供其他对象存储。结果,JVM 抛出 Java.lang.outofmemory 错误。
  4. 内存不足:这也是 Java.lang.outofmemory 错误的原因,因为如果系统为 JVM 执行代码的内存较少,我们可以增加系统大小以弥补内存。因此,如果 JVM 找不到足够的内存来执行代码并存储对象,它就会触发 Java.lang.outofmemory 错误,表明没有剩余空间分配新对象。
  5. 过度使用 finalizer:如果应用程序中的类具有 finalize 方法,则此类对象在垃圾回收(GC)期间无法获得其空间,并且在垃圾回收后,这些对象将被排队以便以后进行 finalization。在 Java 中,finalizer 是通过一个用于服务 finalization 队列的守护线程执行的。如果发现 finalizer 线程无法跟上 finalization 队列,堆空间可能会完全填满,并会抛出 Java.lang.outofmemory 错误。

修复 Java.lang.outofmemory 错误

一旦我们了解了导致此错误发生的原因,就可以修复此错误,并且在错误解决后,JVM 将成功地将对象存储在 Java 堆空间中。要修复错误,可以根据导致 Java.lang.outofmemory 错误的具体原因采取相应的解决方案。

解决方案 1:解决此错误的简单方法是增加 JVM 堆空间的内存大小。要增加堆空间的大小,请使用“-Xmx” Java 选项来解决 out-of-memory 错误。此配置将为应用程序提供 1024 的堆空间。但是,增加堆大小并不能解决应用程序在 JVM 上运行时出现的所有必要错误(例如内存泄漏)。此外,增加堆空间还会增加 GC 暂停的时间,这会影响应用程序的延迟或吞吐量。这是一个解决方案,但并非总是有效的解决方案。要增加堆大小

  1. 如以下所示,打开 Eclipse IDE 的 eclipse.ini 文件
    Java.lang.outofmemoryerror: java heap space
  2. 现在,如下所示,根据您的系统要求更改 Xmx 值
    Java.lang.outofmemoryerror: java heap space
  3. 重新启动 Eclipse IDE,堆大小将增加。

要正确解决此错误,需要检测导致该错误的这部分代码。

解决方案 2:与其尝试增加 JVM 的堆大小但仍然遇到错误,不如查找可能发生的内存泄漏。要在 Eclipse 中检查内存泄漏,可以使用 Eclipse Memory Analyzer(称为 MAT,用于查找内存泄漏并减少内存消耗)或任何其他工具来分析堆转储。虽然查找内存泄漏是一项艰巨的任务,但它是一种很好的方法。

用于检测和修复错误的工具

Java.lang.outofmemory 错误需要通过识别占用内存的对象以及这些对象耗尽的内存量来修复。了解这一点很重要,为此,我们需要使用一些可用的 Java 工具来实现这一点。可能,以下工具可用于分析堆并了解问题:

  1. MAT (Eclipse Memory Analyzer):它是一个 Eclipse 基金会,用于分析 Java 堆转储。该工具用于查找代码中的内存泄漏以及类加载器泄漏。它还有助于最大限度地减少内存消耗。MAT 工具可以用来分析包含数百万个对象的堆转储,并且还有助于检测内存泄漏的罪魁祸首。用户可以从 Eclipse 官方网站 https://www.eclipse.org/mat/downloads.php 下载 MAT 分析器,并将其集成到 Eclipse IDE 中。MAT 工具的快照如下所示
    Java.lang.outofmemoryerror: java heap space
  2. Visualgc:Visualgc 的首字母缩写是 **Visual Garbage Collection Monitoring Tool**,可以附加到已检测的热点 JVM。Visualgc 的主要目标是以图形方式表示所有关键数据,包括类加载器、JVM 编译器性能数据和垃圾回收。此外,目标 JVM 由其虚拟机标识符标识,该标识符也称为 VMID。要在系统中下载 Visualgc,请先下载 jvmstat,它会附带 Visualgc。下载 jvmstat 的链接是:https://www.oracle.com/java/technologies/jvmstat.html
    下载 jvmstat 的快照
    Java.lang.outofmemoryerror: java heap space

因此,通过这种方式,可以识别 Java.lang.out of memory: java heap space 错误,并通过遵循这些指定的选项来解决。