简体   繁体   English

java.lang.OutOfMemoryError: Java 堆空间

[英]java.lang.OutOfMemoryError: Java heap space

I am getting the following error on execution of a multi-threading program我在执行多线程程序时收到以下错误

java.lang.OutOfMemoryError: Java heap space

The above error occured in one of the threads.上述错误发生在其中一个线程中。

  1. Upto my knowledge, Heap space is occupied by instance variables only.据我所知,堆空间仅由实例变量占用。 If this is correct, then why this error occurred after running fine for sometime as space for instance variables are alloted at the time of object creation.如果这是正确的,那么为什么在运行良好一段时间后会出现此错误,因为在创建 object 时分配了实例变量的空间。

  2. Is there any way to increase the heap space?有没有办法增加堆空间?

  3. What changes should I made to my program so that It will grab less heap space?我应该对我的程序进行哪些更改,以便它占用更少的堆空间?

If you want to increase your heap space, you can use java -Xms<initial heap size> -Xmx<maximum heap size> on the command line.如果要增加堆空间,可以在命令行上使用java -Xms<initial heap size> -Xmx<maximum heap size> By default, the values are based on the JRE version and system configuration.默认情况下,这些值基于 JRE 版本和系统配置。 You can find out more about the VM options on the Java website .您可以 在 Java 网站上找到 有关 VM 选项的更多信息

However, I would recommend profiling your application to find out why your heap size is being eaten.但是,我建议您分析您的应用程序以找出您的堆大小被占用的原因。 NetBeans has a very good profiler included with it. NetBeans 包含一个非常好的分析器 I believe it uses the jvisualvm under the hood.我相信它在jvisualvm下使用了jvisualvm With a profiler, you can try to find where many objects are being created, when objects get garbage collected, and more.使用探查器,您可以尝试查找创建多个对象的位置、对象何时被垃圾回收等。

1.- Yes, but it pretty much refers to the whole memory used by your program. 1.- 是的,但它几乎是指您的程序使用的整个内存。

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

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

Ie IE

java -Xmx2g assign 2 gigabytes of ram as maximum to your app java -Xmx2g为您的应用程序分配最大 2 GB 的内存

But you should see if you don't have a memory leak first.但是你应该先看看你是否没有内存泄漏。

3.- It depends on the program. 3.- 这取决于程序。 Try spot memory leaks.尝试发现内存泄漏。 This question would be to hard to answer.这个问题会很难回答。 Lately you can profile using JConsole to try to find out where your memory is going to最近你可以使用 JConsole 来分析你的内存去哪里

You may want to look at this site to learn more about memory in the JVM: http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage您可能想查看此站点以了解有关 JVM 中内存的更多信息: http : //developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

I have found it useful to use visualgc to watch how the different parts of the memory model is filling up, to determine what to change.我发现使用visualgc来观察内存模型的不同部分是如何填充的,以确定要更改的内容很有用。

It is difficult to determine which part of memory was filled up, hence visualgc, as you may want to just change the part that is having a problem, rather than just say,很难确定内存的哪一部分被填满,因此visualgc,因为您可能只想更改有问题的部分,而不仅仅是说,

Fine!美好的! I will give 1G of RAM to the JVM.我会给 JVM 1G 的内存。

Try to be more precise about what you are doing, in the long run you will probably find the program better for it.尝试更准确地了解您正在做什么,从长远来看,您可能会发现该程序更适合它。

To determine where the memory leak may be you can use unit tests for that, by testing what was the memory before the test, and after, and if there is too big a change then you may want to examine it, but, you need to do the check while your test is still running.要确定内存泄漏可能在哪里,您可以为此使用单元测试,通过测试测试之前和之后的内存,如果变化太大,那么您可能需要检查它,但是,您需要在您的测试仍在运行时进行检查。

You can get your heap memory size through below programe.您可以通过以下程序获取堆内存大小。

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

then accordingly you can increase heap size also by using: java -Xmx2g http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html那么相应地,您也可以使用以下方法增加堆大小:java -Xmx2g http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

To increase the heap size you can use the -Xmx argument when starting Java;要增加堆大小,您可以在启动 Java 时使用 -Xmx 参数; eg例如

-Xmx256M
  1. Upto my knowledge, Heap space is occupied by instance variables only.据我所知,堆空间仅被实例变量占用。 If this is correct, then why this error occurred after running fine for sometime as space for instance variables are alloted at the time of object creation.如果这是正确的,那么为什么在运行良好一段时间后会发生此错误,因为在创建对象时分配了实例变量的空间。

That means you are creating more objects in your application over a period of time continuously.这意味着您将在一段时间内连续在应用程序中创建更多对象。 New objects will be stored in heap memory and that's the reason for growth in heap memory.新对象将存储在堆内存中,这就是堆内存增长的原因。

Heap not only contains instance variables.堆不仅包含实例变量。 It will store all non-primitive data types ( Objects).它将存储所有非原始数据类型(对象)。 These objects life time may be short (method block) or long (till the object is referenced in your application)这些对象的生命周期可能很短(方法块)或很长(直到该对象在您的应用程序中被引用)

  1. Is there any way to increase the heap space?有没有办法增加堆空间?

Yes.是的。 Have a look at this oracle article for more details.请查看这篇 oracle 文章以了解更多详细信息。

There are two parameters for setting the heap size:设置堆大小有两个参数:

-Xms: , which sets the initial and minimum heap size -Xms: ,设置初始和最小堆大小

-Xmx: , which sets the maximum heap size -Xmx: ,设置最大堆大小

  1. What changes should I made to my program so that It will grab less heap space?我应该对我的程序进行哪些更改,以便它占用更少的堆空间?

It depends on your application.这取决于您的应用程序。

  1. Set the maximum heap memory as per your application requirement根据您的应用程序要求设置最大堆内存

  2. Don't cause memory leaks in your application不要在您的应用程序中造成内存泄漏

  3. If you find memory leaks in your application, find the root cause with help of profiling tools like MAT ,Visual VM , jconsole etc. Once you find the root cause, fix the leaks.如果您在应用程序中发现内存泄漏,请借助MATVisual VMjconsole等分析工具找到根本原因。找到根本原因后,修复泄漏。

Important notes from oracle article oracle 文章中的重要说明

Cause: The detail message Java heap space indicates object could not be allocated in the Java heap.原因:Java 堆空间的详细消息指示无法在 Java 堆中分配对象。 This error does not necessarily imply a memory leak.此错误不一定意味着内存泄漏。

Possible reasons:可能的原因:

  1. Improper configuration ( not allocating sufficiant memory)配置不当(没有分配足够的内存)
  2. Application is unintentionally holding references to objects and this prevents the objects from being garbage collected应用程序无意中持有对对象的引用,这会阻止对象被垃圾收集
  3. Applications that make excessive use of finalizers.过度使用终结器的应用程序。 If a class has a finalize method, then objects of that type do not have their space reclaimed at garbage collection time.如果一个类有一个 finalize 方法,那么该类型的对象在垃圾回收时不会回收它们的空间。 If the finalizer thread cannot keep up, with the finalization queue, then the Java heap could fill up and this type of OutOfMemoryError exception would be thrown .如果终结器线程跟不上终结队列,那么 Java 堆可能会填满,并且会抛出这种类型的 OutOfMemoryError 异常

On a different note, use better Garbage collection algorithms ( CMS or G1GC )另一方面,使用更好的垃圾收集算法( CMSG1GC

Have a look at this question for understanding G1GC看看这个问题以了解 G1GC

  1. In most of the cases, the code is not optimized.在大多数情况下,代码没有优化。 Release those objects which you think shall not be needed further.释放那些您认为不再需要的对象。 Avoid creation of objects in your loop each time.避免每次都在循环中创建对象。 Try to use caches.尝试使用缓存。 I don't know how your application is doing.我不知道你的申请进展如何。 But In programming, one rule of normal life applies as well但在编程中,一条正常生活的规则也适用

    Prevention is better than cure.预防胜于治疗。 "Don't create unnecessary objects" “不要创建不必要的对象”

  1. Local variables are located on the stack.局部变量位于堆栈上。 Heap space is occupied by objects.堆空间被对象占用。

  2. You can use the -Xmx option.您可以使用-Xmx选项。

  3. Basically heap space is used up everytime you allocate a new object with new and freed some time after the object is no longer referenced.基本上,每次你用new分配一个新对象时,堆空间都会用完,并在该对象不再被引用后释放一段时间。 So make sure that you don't keep references to objects that you no longer need.因此,请确保不要保留对不再需要的对象的引用。

No, I think you are thinking of stack space.不,我认为您正在考虑堆栈空间。 Heap space is occupied by objects.堆空间被对象占用。 The way to increase it is -Xmx256m, replacing the 256 with the amount you need on the command line.增加它的方法是-Xmx256m,将256替换为您在命令行上需要的数量。

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

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

In netbeans, Go to 'Run' toolbar, --> 'Set Project Configuration' --> 'Customise' --> 'run' of its popped up windo --> 'VM Option' --> fill in '-Xms2048m -Xmx2048m'.在netbeans中,转到“运行”工具栏,-->“设置项目配置”-->“自定义”-->弹出窗口的“运行”-->“VM选项”-->填写“-Xms2048m” -Xmx2048m'。 It could solve heap size problem.它可以解决堆大小问题。

I have tried all Solutions but nothing worked from above solutions我已经尝试了所有解决方案,但上述解决方案没有任何效果

Solution : In My case I was using 4GB RAM and due to that RAM usage comes out 98% so the required amount if Memory wasn't available.解决方案:在我的情况下,我使用的是 4GB RAM,由于 RAM 使用率达到 98%,因此如果内存不可用,则所需的数量。 Please do look for this also.If such issue comes upgrade RAM and it will work fine.也请查找此问题。如果出现此类问题,请升级 RAM,它会正常工作。

Hope this will save someone Time希望这会节省一些人的时间

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM