java.lang.OutOfMemoryError:Java堆空间

Yat*_*oel 94 java multithreading heap-memory out-of-memory

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

java.lang.OutOfMemoryError: Java heap space
Run Code Online (Sandbox Code Playgroud)

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

  1. 据我所知,堆空间仅由实例变量占用.如果这是正确的,那么为什么在运行正常一段时间之后发生此错误,因为在创建对象时分配了实例变量的空间.

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

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

Tho*_*ens 99

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

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


Osc*_*Ryz 25

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

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

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
Run Code Online (Sandbox Code Playgroud)

java -Xmx2g 为您的应用分配2 GB的ram作为最大值

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

3.-这取决于计划.尝试点内存泄漏.这个问题很难回答.最近,您可以使用JConsole进行配置文件,以尝试找出您的内存的位置


Jam*_*ack 8

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

我发现使用visualgc来观察内存模型的不同部分是如何填满的,以确定要更改的内容很有用.

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

精细!我将给JVM提供1G的RAM.

尝试更准确地了解自己在做什么,从长远来看,你可能会发现程序更好.

要确定内存泄漏的位置,您可以使用单元测试,通过测试测试之前的内存以及之后,如果有太大的更改,那么您可能想要检查它,但是,您需要在测试仍在运行时进行检查.


Ada*_*ski 6

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

-Xmx256M
Run Code Online (Sandbox Code Playgroud)


use*_*609 6

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

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

那么你也可以通过使用以下方法增加堆大小:java -Xmx2g http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html


Rav*_*abu 6

  1. 据我所知,堆空间仅由实例变量占用.如果这是正确的,那么为什么在运行正常一段时间之后发生此错误,因为在创建对象时分配了实例变量的空间.

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

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

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

是.有关更多详细信息,请查看此oracle 文章.

设置堆大小有两个参数:

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

-Xmx : ,设置最大堆大小

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

这取决于您的应用程序.

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

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

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

来自oracle 文章的重要说明

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

可能的原因:

  1. 配置不当(不分配足够的内存)
  2. 应用程序无意中持有对象的引用,这可以防止对象被垃圾回收
  3. 过度使用终结器的应用程序.如果类具有finalize方法,则该类型的对象在垃圾收集时不会回收它们的空间.如果终结器线程无法跟上最终化队列,则Java堆可能会填满,并且会抛出这种类型的OutOfMemoryError异常.

另外,使用更好的垃圾收集算法(CMSG1GC)

看看这个问题,了解G1GC


DKS*_*ore 5

  1. 在大多数情况下,代码未经过优化.释放您认为不再需要的物体.避免每次在循环中创建对象.尝试使用缓存.我不知道你的应用程序是怎么做的.但在编程中,正常生活的一条规则也适用

    预防胜于治疗."不要创建不必要的对象"