java.lang.OutOfMemoryError:Java堆空间

我正在执行multithreading程序时出现以下错误

java.lang.OutOfMemoryError: Java heap space 

上述错误发生在其中一个线程中。

  1. 根据我的知识,堆空间仅由实例variables占用。 如果这是正确的,那么为什么这个错误在运行正常之后发生,因为在创build对象时分配了实例variables的空间。

  2. 有没有办法增加堆空间?

  3. 我应该对我的程序做些什么改变,以便占用更less的堆空间?

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

但是,我会build议分析您的应用程序,找出为什么你的堆大小正在被吃掉。 NetBeans包含一个非常好的分析器 。 我相信它使用jvisualvm下的jvisualvm 。 使用分析器,您可以尝试查找正在创build多个对象的位置,对象何时被垃圾收集等等。

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

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

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

java -Xmx2g将2千兆字节的RAM分配给你的应用程序

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

3.这取决于程序。 尝试现货内存泄漏。 这个问题很难回答。 最近你可以使用JConsole进行configuration文件,试图找出你的内存在哪里

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

我发现使用visualgc来观察内存模型的不同部分是如何填充的,以确定要改变的是什么。

很难确定哪部分内存被填满了,因此visualgc,因为你可能想要改变那些有问题的部分,而不是仅仅说,

精细! 我会给1G的RAM给JVM。

试着更准确地说明你正在做什么,从长远来看,你可能会发现程序更好。

要确定内存泄漏的位置,你可以使用unit testing,通过testingtesting之前和之后的内存,如果有太大的变化,那么你可能需要检查它,但是,你需要当你的testing仍在运行时做检查。

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

 -Xmx256M 

你可以通过下面的程序来获得你的堆内存大小。

 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

  1. 在大多数情况下,代码没有被优化。 释放你认为不需要的东西。 每次避免在循环中创build对象。 尝试使用caching。 我不知道你的应用程序在做什么。 但在编程中,正常生活的一个规则也适用

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

  1. 根据我的知识,堆空间仅由实例variables占用。 如果这是正确的,那么为什么这个错误在运行正常之后发生,因为在创build对象时分配了实例variables的空间。

这意味着您在一段时间内不断在应用程序中创build更多的对象。 新的对象将被存储在堆内存中,这就是堆内存增长的原因。

堆不仅包含实例variables。 它将存储所有非原始数据types(对象)。 这些对象的生命周期可能很短(方法块)或长(直到在你的应用程序中引用该对象)

  1. 有没有办法增加堆空间?

是。 看看这篇oracle 文章的更多细节。

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

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

-Xmx:,它设置最大的堆大小

  1. 我应该对我的程序做些什么改变,以便占用更less的堆空间?

这取决于你的应用程序。

  1. 根据您的应用程序要求设置最大堆内存

  2. 不要在您的应用程序中造成内存泄漏

  3. 如果您在应用程序中发现内存泄漏,请使用MAT , Visual VM , jconsole等分析工具帮助find根本原因。find根本原因后,修复泄漏。

来自oracle 文章的重要说明

原因:详细信息Java堆空间表示对象无法在Java堆中分配。 这个错误并不一定意味着内存泄漏。

可能的原因:

  1. 不正确的configuration (不分配足够的内存)
  2. 应用程序无意中持有对对象的引用,这可以防止对象被垃圾收集
  3. 过度使用终结器的应用程序。 如果一个类有一个finalize方法,那么这个types的对象在垃圾回收时没有回收空间。 如果终结器线程跟不上终止队列,那么Java堆可能会被填满,这种types的OutOfMemoryErrorexception将被抛出

在不同的说明中,使用更好的垃圾收集algorithm( CMSG1GC

为了理解G1GC,看看这个问题

  1. 局部variables位于堆栈上。 堆空间被对象占用。

  2. 您可以使用-Xmx选项。

  3. 基本上堆空间用完每次你分配一个新的对象与new和释放对象不再引用一段时间后。 因此,请确保不要保留对不再需要的对象的引用。

不,我想你正在考虑堆栈空间。 堆空间被对象占用。 增加它的方法是-Xmx256m,用命令行上所需的数量replace256。

在NetBeans中,进入'运行'工具栏, – >'设置项目configuration' – >'自定义' – >'运行'其popup窗口 – >'VM选项' – >填写'-Xms2048m -Xmx2048m”。 它可以解决堆大小的问题。