我在执行多线程程序时遇到以下错误

java.lang.OutOfMemoryError: Java heap space


上面的错误发生在一个线程中。


据我所知,堆空间仅由实例变量占用。如果这是正确的,那么为什么在运行一段时间后会出现此错误,因为在创建对象时会分配实例变量的空间。
有什么方法可以增加堆空间?我对程序进行了设置,以便它将占用更少的堆空间?


评论

检查stackoverflow.com/questions/37335/…

#1 楼

如果要增加堆空间,可以在命令行上使用java -Xms<initial heap size> -Xmx<maximum heap size>。默认情况下,这些值基于JRE版本和系统配置。您可以在Java网站上找到有关VM选项的更多信息。

但是,我建议对应用程序进行性能分析,以找出为什么吃掉了您的堆大小。 NetBeans包含一个非常好的分析器。我相信它会在引擎盖下使用jvisualvm。使用探查器,您可以尝试查找在哪里创建了许多对象,何时收集了对象的垃圾等等。

评论


我正在使用Netbeans,但我不知道如何使用事件探查器。我想了解更多有关探查器的信息,以便可以使用它来查找应用程序中的内存泄漏。

– Yatendra Goel
09年10月20日在18:00

我在NetBeans站点(profiler.netbeans.org)上的页面上添加了一个链接,该页面具有有关概要文件的非常好的文档,从最基础的到更高级的用法。

–托马斯·欧文斯(Thomas Owens)
09-10-20在18:03

缺省值随Java版本而变化,最好在您的答案中包含此信息。

– Dariusz
16年5月6日在8:07

只是解决了类似的问题,并首先尝试:java -jar division.jar -Xmx512m -Xms512m-这给了我相同的错误,但是当我这样做时:java -Xmx512m -Xms512m -jar division.jar-一切都很好。因此,参数的顺序也很重要。

–hipokito
16年5月21日在12:15

@hipokito将jar文件作为args []传递到jar文件的main()方法之后的参数

–阿苏
17年4月11日在15:09

#2 楼

1.-是的,但是它几乎是指程序使用的整个内存。

2.-是的,请参阅Java VM选项

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size




java -Xmx2g分配2 GB的RAM作为最大内存到您的应用程序

,但是您应该先看看是否没有内存泄漏。

3.-取决于程序。尝试点内存泄漏。这个问题将很难回答。最近,您可以使用JConsole进行概要分析,以尝试找出内存的存放位置

评论


而其中(true);)

– Gal Bracha
2014年12月8日22:52

#3 楼

您可能希望查看此站点以了解有关JVM中内存的更多信息:
http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

我发现使用visualgc观察内存模型的不同部分如何填充,以确定要更改的内容非常有用。

很难确定内存的哪一部分被填充,因此是visualgc,因为您可能只想更改有问题的零件,而不是仅仅说


好!我将为JVM提供1G的RAM。 >
要确定内存泄漏的位置,您可以对此进行单元测试,方法是在测试之前和之后测试什么是内存,如果变化太大,则可能需要检查一下,但是,您需要在测试仍在运行时进行检查。

#4 楼

要增加堆大小,可以在启动Java时使用-Xmx参数。例如

-Xmx256M


#5 楼

您可以通过下面的程序获取堆内存大小。

public class GetHeapSize {
    public static void main(String[] args) {
        long heapsize = Runtime.getRuntime().totalMemory();
        System.out.println("heapsize is :: " + heapsize);
    }
} 


然后您还可以使用以下方法来增加堆大小:
java -Xmx2g
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

#6 楼



据我所知,堆空间仅被实例变量占用。如果这是正确的,那么为什么在运行一段时间后会出现此错误,因为在创建对象时会为实例变量分配空间。



这意味着您正在创建在一段时间内,您的应用程序中会有更多对象。新对象将存储在堆内存中,这就是堆内存增长的原因。
堆不仅包含实例变量。它将存储所有非原始数据类型(对象)。这些对象的寿命可能很短(方法块)或很长(直到在您的应用程序中引用了对象)



有什么方法可以增加堆空间? br />


是的。请查看此oracle文章以获取更多详细信息。

有两个用于设置堆大小的参数:

-Xms :,用于设置初始和最小堆大小

-Xmx:设置最大堆大小



我应该对程序进行哪些更改,以便它可以占用更少的堆空间?



这取决于您的应用程序。


根据您的应用程序要求设置最大堆内存
不要在应用程序中导致内存泄漏
如果在应用程序中发现内存泄漏,请找到借助MAT,Visual VM,jconsole等性能分析工具确定根本原因。一旦找到根本原因,请修复漏洞。 />原因:详细消息Java堆空间指示无法在Java堆中分配对象。此错误并不一定意味着内存泄漏。


可能的原因:




配置不正确(未分配足够的内存)
应用程序无意间保留了对对象的引用,这防止了对象被垃圾回收
过度使用终结器的应用程序。如果类具有finalize方法,则该类型的对象在垃圾回收时不会回收其空间。如果终结器线程无法跟上终结器队列的速度,则Java堆可能会填满,并且会抛出此类OutOfMemoryError异常。

另外,请使用更好的垃圾回收算法(CMS或G1GC)

看看这个问题以了解G1GC

#7 楼



在大多数情况下,代码没有得到优化。释放那些您认为不再需要的对象。避免每次在循环中创建对象。尝试使用缓存。我不知道您的应用程序运行状况如何。但是在编程中,同样适用正常生活的一条规则

预防胜于治疗。 “不要创建不必要的对象”



#8 楼


局部变量位于堆栈上。堆空间已被对象占用。
您可以使用-Xmx选项。
每次使用new分配新对象时,基本上都会用完堆空间,并在不再引用该对象后释放一段时间。因此,请确保不要保留对不再需要的对象的引用。


#9 楼

不,我认为您正在考虑堆栈空间。堆空间被对象占用。增加它的方法是-Xmx256m,用您在命令行上需要的数量替换256。

#10 楼

为避免该异常,如果您使用的是JUnit和Spring,请尝试将其添加到每个测试类中:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)


#11 楼

在netbeans中,转到“运行”工具栏->“设置项目配置”->“自定义”->“运行”其弹出的窗口->“ VM Option”->填写“ -Xms2048m -Xmx2048m'。它可以解决堆大小问题。