简体   繁体   English

memory 之外的堆空间

[英]Heap space out of memory

My application currently consumes quite a lot of memory because it is running physics simulations.我的应用程序目前消耗了相当多的 memory,因为它正在运行物理模拟。 The issue is that consistently, at the 51st simulation, Java will throw an error usually because of a heap space out of memory (my program eventually runs thousands of simulations).问题是,在第 51 次模拟中,Java 通常会抛出错误,通常是因为 memory 之外的堆空间(我的程序最终运行了数千次模拟)。

Is there anyway I can not just increase the heap space but modify my program so that the heap space is cleared after every run so that I can run an arbitrary number of simulations?无论如何,我不仅可以增加堆空间,还可以修改我的程序,以便在每次运行后清除堆空间,以便我可以运行任意数量的模拟?

Edit: Thanks guys.编辑:谢谢各位。 Turns out the simulator software wasn't clearing the information after every run and I had those runs all stored in an ArrayList .结果是模拟器软件在每次运行后都没有清除信息,我将这些运行都存储在ArrayList中。

There is no way to dynamically increase the heap programatically since the heap is allocated when the Java Virtual Machine is started.由于堆是在 Java 虚拟机启动时分配的,因此无法以编程方式动态增加堆。

However, you can use this command但是,您可以使用此命令

java -Xmx1024M YourClass

to set the memory to 1024将 memory 设置为 1024

or, you can set a min max或者,您可以设置最小最大值

java -Xms256m -Xmx1024m YourClassNameHere

If you are using a lot of memory and facing memory leaks, then you might want to check if you are using a large number of ArrayList s or HashMap s with many elements each. If you are using a lot of memory and facing memory leaks, then you might want to check if you are using a large number of ArrayList s or HashMap s with many elements each.

An ArrayList is implemented as a dynamic array . ArrayList实现为动态数组 The source code from Sun/Oracle shows that when a new element is inserted into a full ArrayList , a new array of 1.5 times the size of the original array is created, and the elements copied over. Sun/Oracle 的源代码显示,当将新元素插入完整的ArrayList时,会创建一个大小为原始数组 1.5 倍的新数组,并将元素复制过来。 What this means is that you could be wasting up to 50% of the space in each ArrayList you use, unless you call its trimToSize method.这意味着您可能会浪费您使用的每个ArrayList中多达 50% 的空间,除非您调用它的trimToSize方法。 Or better still, if you know the number of elements you are going to insert before hand, then call the constructor with the initial capacity as its argument.或者更好的是,如果您事先知道要插入的元素数量,则使用初始容量作为参数调用构造函数。

I did not examine the source code for HashMap very carefully, but at a first glance it appears that the array length in each HashMap must be a power of two, making it another implementation of a dynamic array.我没有仔细检查HashMap的源代码,但乍一看似乎每个HashMap中的数组长度必须是 2 的幂,使其成为动态数组的另一种实现。 Note that HashSet is essentially a wrapper around HashMap .请注意, HashSet本质上是HashMap的包装器。

There are a variety of tools that you can use to help diagnose this problem.您可以使用多种工具来帮助诊断此问题。 The JDK includes JVisualVM that will allow you to attach to your running process and show what objects might be growing out of control. JDK 包含JVisualVM ,它允许您附加到正在运行的进程并显示哪些对象可能会失去控制。 Netbeans has a wrapper around it that works fairly well. Netbeans 周围有一个运行良好的包装器。 Eclipse has the Eclipse Memory Analyzer which is the one I use most often, just seems to handle large dump files a bit better. Eclipse 有 Eclipse Memory 分析器,这是我最常用的分析器,只是似乎更好地处理大型转储文件。 There's also a command line option, -XX:+HeapDumpOnOutOfMemoryError that will give you a file that is basically a snapshot of your process memory when your program crashed.还有一个命令行选项, -XX:+HeapDumpOnOutOfMemoryError ,它将为您提供一个文件,该文件基本上是程序崩溃时您的进程 memory 的快照。 You can use any of the above mentioned tools to look at it, it can really help a lot when diagnosing these sort of problems.你可以使用上面提到的任何工具来查看它,它在诊断这类问题时真的很有帮助。

Depending on how hard the program is working, it may be a simple case of the JVM not knowing when a good time to garbage collect may be, you might also look into the parallel garbage collection options as well.根据程序的工作强度,可能是 JVM 不知道何时是垃圾收集的好时机的简单案例,您也可以查看并行垃圾收集选项。

I also faced the same problem.I resolved by doing the build by following steps as.我也遇到了同样的问题。我按照以下步骤进行构建解决了。

-->Right click on the project select RunAs ->Run configurations -->右键项目select RunAs ->运行配置

Select your project as BaseDirectory. Select 您的项目作为 BaseDirectory。 In place of goals give eclipse:eclipse install代替目标给 eclipse:eclipse 安装

-->In the second tab give -Xmx1024m as VM arguments. --> 在第二个选项卡中,将 -Xmx1024m 指定为 VM arguments。

I would like to add that this problem is similar to common Java memory leaks.我想补充一点,这个问题类似于常见的 Java memory 泄漏。

When the JVM garbage collector is unable to clear the "waste" memory of your Java / Java EE application over time, OutOfMemoryError: Java heap space will be the outcome. When the JVM garbage collector is unable to clear the "waste" memory of your Java / Java EE application over time, OutOfMemoryError: Java heap space will be the outcome.

It is important to perform a proper diagnostic first:首先执行正确的诊断很重要:

  • Enable verbose:gc .启用详细:gc This will allow you to understand the memory growing pattern over time.这将使您了解 memory 随时间的增长模式。
  • Generate and analyze a JVM Heap Dump .生成并分析JVM 堆转储 This will allow you to understand your application memory footprint and pinpoint the source of the memory leak(s).这将使您能够了解您的应用程序 memory 封装并查明 memory 泄漏的来源。
  • You can also use Java profilers and runtime memory leak analyzer such as Plumbr as well to help you with this task.您还可以使用 Java 分析器和运行时 memory 泄漏分析器(例如Plumbr )来帮助您完成此任务。

Try adding -Xmx for more memory ( java -Xmx1024M YourClass ), and don't forget to stop referencing variables you don't need any more (memory leaks).尝试添加 -Xmx 以获得更多 memory ( java -Xmx1024M YourClass ),并且不要忘记停止引用您不再需要的变量(内存泄漏)。

Are you keeping references to variables that you no longer need (eg data from the previous simulations)?您是否保留了对不再需要的变量的引用(例如来自先前模拟的数据)? If so, you have a memory leak.如果是这样,您有 memory 泄漏。 You just need to find where that is happening and make sure that you remove the references to the variables when they are no longer needed (this would automatically happen if they go out of scope).您只需要找到发生这种情况的位置并确保在不再需要变量时删除对变量的引用(如果它们 go 超出范围,这将自动发生)。

If you actually need all that data from previous simulations in memory, you need to increase the heap size or change your algorithm.如果您确实需要 memory 中先前模拟的所有数据,则需要增加堆大小或更改算法。

Java is supposed to clear the heap space for you when all of the objects are no longer referenced.当不再引用所有对象时,Java 应该为您清除堆空间。 It won't generally release it back to the OS though, it will keep that memory for it's own internal reuse.它通常不会将其释放回操作系统,但它会保留 memory 以供其内部重用。 Maybe check to see if you have some arrays which are not being cleared or something.也许检查一下你是否有一些 arrays 没有被清除或其他东西。

No. The heap is cleared by the garbage collector whenever it feels like it.不会。垃圾收集器会在需要时清除堆。 You can ask it to run (with System.gc() ) but it is not guaranteed to run.您可以要求它运行(使用System.gc() )但不能保证运行。

First try increasing the memory by setting -Xmx256m首先尝试通过设置-Xmx256m增加 memory

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

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