java.lang.OutOfMemoryError:Java堆空间

时间:2020-02-23 14:36:40  来源:igfitidea点击:

当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输出,以了解您的应用程序为何需要较高的内存,以及是否可以减少内存。