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

java.lang.OutOfMemoryError: Java heap space

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

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

  2. 有什么办法可以增加堆空间吗?

  3. 我应该对我的程序进行哪些更改才能占用更少的堆空间?

有帮助吗?

解决方案

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

但是,我建议对您的应用程序进行分析,以找出堆大小被占用的原因。NetBeans 有一个 非常好的分析器 包含在其中。我相信它使用 jvisualvm 在引擎盖下。使用探查器,您可以尝试查找创建许多对象的位置、对象何时被垃圾回收等等。

其他提示

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

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

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

IE

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

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

3.- 这取决于程序。尝试发现内存泄漏。这个问题就很难回答了。最近,您可以使用 JConsole 进行分析,尝试找出您的内存去向

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

我发现它很有用 视觉GC 观察内存模型的不同部分如何填充,以确定要更改的内容。

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

美好的!我会给 JVM 分配 1G RAM。

尝试更准确地了解您正在做的事情,从长远来看,您可能会发现该程序更适合它。

要确定内存泄漏可能在哪里,您可以使用单元测试,通过测试测试之前和之后的内存情况,如果变化太大,那么您可能需要检查它,但是,您需要在测试仍在运行时进行检查。

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

-Xmx256M

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

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

那么相应地,您也可以通过使用以下方法来增加堆大小:java-Xmx2ghttp://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

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

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

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

  1. 有什么办法可以增加堆空间吗?

是的。看看这个神谕 文章 更多细节。

设置堆大小有两个参数:

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

-XMX:, ,它设置最大堆大小

  1. 我应该对我的程序进行哪些更改才能占用更少的堆空间?

这取决于您的应用程序。

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

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

  3. 如果您在应用程序中发现内存泄漏,请借助分析工具(例如 , 可视化虚拟机 , 控制台 ETC。一旦找到根本原因,就修复泄漏。

甲骨文的重要说明 文章

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

可能的原因:

  1. 配置不当 (没有分配足够的内存)
  2. 应用程序无意中保留了对对象的引用,这会阻止对象被垃圾收集
  3. 过度使用终结器的应用程序。如果一个类具有 Finalize 方法,则该类型的对象在垃圾收集时不会回收其空间。 如果终结器线程无法跟上终结队列,那么 Java 堆可能会被填满,并且会抛出此类 OutOfMemoryError 异常.

另一方面,使用更好的垃圾收集算法( 内容管理系统 或者 G1GC)

看看这个 问题 为了理解G1GC

  1. 在大多数情况下,代码没有经过优化。释放那些您认为不再需要的对象。避免每次都在循环中创建对象。尝试使用缓存。我不知道你的应用程序进展如何。但在编程中,日常生活中的一条规则也适用

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

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

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

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

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

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

为了避免该异常,如果您使用 JUnit 和 Spring,请尝试在每个测试类中添加以下内容:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top