堆空间内存不足
我的应用程序当前消耗大量内存,因为它正在运行物理模拟。问题是,在第 51 次模拟时,Java 通常会因为堆空间内存不足而抛出错误(我的程序最终运行了数千次模拟)。
无论如何,我不仅可以增加堆空间,还可以修改我的程序,以便每次运行后都会清除堆空间,以便我可以运行任意数量的模拟?
编辑:谢谢大家。结果模拟器软件并没有在每次运行后清除信息,我将这些运行全部存储在 ArrayList 中。
My application currently consumes quite a lot of memory because it is running physics simulations. 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).
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
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
由于堆是在 Java 虚拟机启动时分配的,因此无法以编程方式动态增加堆。
但是,您可以使用此命令
将内存设置为 1024
,或者您可以设置最小最大
There is no way to dynamically increase the heap programatically since the heap is allocated when the Java Virtual Machine is started.
However, you can use this command
to set the memory to 1024
or, you can set a min max
如果您使用大量内存并面临内存泄漏,那么您可能需要检查是否使用大量 ArrayList 或 HashMap,其中每个数组都有许多元素。
ArrayList
被实现为动态数组。 Sun/Oracle 的源代码显示,当一个新元素插入到完整的 ArrayList 中时,会创建一个大小为原始数组 1.5 倍的新数组,并复制其中的元素。这意味着,除非您调用其trimToSize
方法,否则您可能会浪费所使用的每个ArrayList
中多达 50% 的空间。或者更好的是,如果您事先知道要插入的元素数量,则可以使用初始容量作为其参数来调用构造函数。我没有仔细检查
HashMap
的源代码,但乍一看似乎每个HashMap
中的数组长度必须是2的幂,使其成为另一个动态数组的实现。请注意,HashSet
本质上是HashMap
的包装器。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 orHashMap
s with many elements each.An
ArrayList
is implemented as a dynamic array. The source code from Sun/Oracle shows that when a new element is inserted into a fullArrayList
, a new array of 1.5 times the size of the original array is created, and the elements copied over. What this means is that you could be wasting up to 50% of the space in eachArrayList
you use, unless you call itstrimToSize
method. 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 eachHashMap
must be a power of two, making it another implementation of a dynamic array. Note thatHashSet
is essentially a wrapper aroundHashMap
.您可以使用多种工具来帮助诊断此问题。 JDK 包含 JVisualVM,它允许您附加到正在运行的进程并显示哪些对象可能会失去控制。 Netbeans 有一个工作得相当好的包装器。 Eclipse 有 Eclipse Memory Analyzer,这是我最常使用的一个,似乎可以更好地处理大型转储文件。还有一个命令行选项 -XX:+HeapDumpOnOutOfMemoryError 将为您提供该文件基本上是程序崩溃时进程内存的快照。您可以使用上述任何工具来查看它,它在诊断此类问题时确实有很大帮助。
根据程序的工作强度,这可能是 JVM 不知道何时是垃圾收集的好时机的简单情况,您也可以查看并行垃圾收集选项。
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. Netbeans has a wrapper around it that works fairly well. Eclipse has the Eclipse Memory Analyzer which is the one I use most often, just seems to handle large dump files a bit better. 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. 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.
我也遇到了同样的问题。我通过按照以下步骤进行构建来解决。
--> 右键单击项目,选择 RunAs -> 运行配置
选择您的项目作为 BaseDirectory。代替目标给出 eclipse:eclipse install
--> 在第二个选项卡中给出 -Xmx1024m 作为 VM 参数。
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 your project as BaseDirectory. In place of goals give eclipse:eclipse install
-->In the second tab give -Xmx1024m as VM arguments.
我想补充一点,这个问题与常见的Java内存泄漏类似。
当 JVM 垃圾收集器无法随着时间的推移清除 Java / Java EE 应用程序的“浪费”内存时,OutOfMemoryError: Java 堆空间 将是结果。
首先执行正确的诊断非常重要:
I would like to add that this problem is similar to common Java memory leaks.
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:
尝试添加 -Xmx 以获得更多内存(
java -Xmx1024M YourClass
),并且不要忘记停止引用不再需要的变量(内存泄漏)。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).您是否保留对不再需要的变量的引用(例如来自先前模拟的数据)?如果是这样,则存在内存泄漏。您只需要找到发生这种情况的位置,并确保在不再需要变量时删除对它们的引用(如果它们超出范围,这将自动发生)。
如果您实际上需要内存中先前模拟的所有数据,则需要增加堆大小或更改算法。
Are you keeping references to variables that you no longer need (e.g. data from the previous simulations)? If so, you have a memory leak. 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).
If you actually need all that data from previous simulations in memory, you need to increase the heap size or change your algorithm.
当所有对象不再被引用时,Java 应该为您清除堆空间。不过,它通常不会将其释放回操作系统,而是保留该内存供其内部重用。也许检查一下是否有一些未清除的数组或其他内容。
Java is supposed to clear the heap space for you when all of the objects are no longer referenced. It won't generally release it back to the OS though, it will keep that memory for it's own internal reuse. Maybe check to see if you have some arrays which are not being cleared or something.
不会。垃圾收集器会在需要时清除堆。您可以要求它运行(使用
System.gc()
),但不保证它一定会运行。首先尝试通过设置 -Xmx256m 来增加内存
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.First try increasing the memory by setting
-Xmx256m