java.lang.OutOfMemoryError:Java堆空间
当JVM无法分配内存来创建对象时,将引发java.lang.OutOfMemoryError。
Java OutOfMemoryError是一个错误,并且在运行时发生。
java.lang.OutOfMemoryError
顾名思义,当Java运行时内存不足时,会发生" OutOfMemoryError"。
在这种情况下,垃圾回收器无法释放程序所需的更多空间,因此会引发错误。
导致java.lang.OutOfMemoryError
的主要原因有两个:
- 不良的编程-无限循环,无法通过关闭资源等方式清除内存等
- 内存不足– Java运行的内存少于所需的内存。
Java OutOfMemoryError –不良的编程示例
让我们看一个示例代码,该代码将抛出java.lang.OutOfMemoryError:Java堆空间,因为该程序进入无限循环,并且正在创建对象但未收集垃圾。
因此,最终JVM将耗尽内存。
package com.theitroad.exceptions; import java.util.ArrayList; import java.util.List; import java.util.Random; public class JavaOutOfMemoryErrorExample { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Random random = new Random(); while (true) list.add(random.nextInt()); } }
执行以上代码后,一段时间后它将引发以下异常。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.base/java.lang.Integer.valueOf(Integer.java:1050) at com.theitroad.exceptions.JavaOutOfMemoryErrorExample.main(JavaOutOfMemoryErrorExample.java:15)
这是一个编程不佳的例子,但是好消息是,异常堆栈跟踪清楚地指示我们寻找发生此错误的代码。
但是有时问题可能出在程序的其他区域,在那种情况下,我们将需要Java分析器(例如VisualVM)的帮助来确定大部分内存在何处分配以及如何对其进行优化。
Java OutOfMemoryError –低内存示例
让我们看另一个例子,其中由于没有为程序正确执行分配足够的内存而导致" OutOfMemoryError"。
public class JavaOutOfMemoryErrorExample { public static void main(String[] args) { Integer[] array = new Integer[1000*1000*100]; System.out.println("Done"); } }
让我们看看当我们在JVM最大内存限制为32 MB的程序之上运行时会发生什么。
$javac JavaOutOfMemoryErrorExample.java $java -Xmx32m JavaOutOfMemoryErrorExample Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at JavaOutOfMemoryErrorExample.main(JavaOutOfMemoryErrorExample.java:5)
如我们所见,程序中没有错,我们在非常低的内存上运行它。
让我们尝试通过将JVM内存增加到256MB然后再增加512 MB来解决此OutOfMemoryError问题。
$java -Xmx256m JavaOutOfMemoryErrorExample Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at JavaOutOfMemoryErrorExample.main(JavaOutOfMemoryErrorExample.java:5) $java -Xmx512m JavaOutOfMemoryErrorExample Done $
因此,当我们提供足够的内存来运行它时,我们的程序似乎运行良好。
除非您在非常低的内存上运行,否则增加JVM的内存是解决该问题的快速解决方案。
如果您已经在高JVM内存(例如2GB或者更多)上运行,则应查看应用程序代码以对其进行优化,并查看线程转储和Java Profiler输出,以了解您的应用程序为何需要较高的内存,以及是否可以减少内存。