[英]java.lang.OutOfMemoryError: Java heap space
我在执行多线程程序时收到以下错误
java.lang.OutOfMemoryError: Java heap space
上述错误发生在其中一个线程中。
据我所知,堆空间仅由实例变量占用。 如果这是正确的,那么为什么在运行良好一段时间后会出现此错误,因为在创建 object 时分配了实例变量的空间。
有没有办法增加堆空间?
我应该对我的程序进行哪些更改,以便它占用更少的堆空间?
如果要增加堆空间,可以在命令行上使用java -Xms<initial heap size> -Xmx<maximum heap size>
。 默认情况下,这些值基于 JRE 版本和系统配置。 您可以 在 Java 网站上找到 有关 VM 选项的更多信息。
但是,我建议您分析您的应用程序以找出您的堆大小被占用的原因。 NetBeans 包含一个非常好的分析器。 我相信它在jvisualvm
下使用了jvisualvm
。 使用探查器,您可以尝试查找创建多个对象的位置、对象何时被垃圾回收等。
1.- 是的,但它几乎是指您的程序使用的整个内存。
2.- 是的,请参阅 Java VM 选项
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
IE
java -Xmx2g
为您的应用程序分配最大 2 GB 的内存
但是你应该先看看你是否没有内存泄漏。
3.- 这取决于程序。 尝试发现内存泄漏。 这个问题会很难回答。 最近你可以使用 JConsole 来分析你的内存去哪里
您可能想查看此站点以了解有关 JVM 中内存的更多信息: http : //developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage
我发现使用visualgc来观察内存模型的不同部分是如何填充的,以确定要更改的内容很有用。
很难确定内存的哪一部分被填满,因此visualgc,因为您可能只想更改有问题的部分,而不仅仅是说,
美好的! 我会给 JVM 1G 的内存。
尝试更准确地了解您正在做什么,从长远来看,您可能会发现该程序更适合它。
要确定内存泄漏可能在哪里,您可以为此使用单元测试,通过测试测试之前和之后的内存,如果变化太大,那么您可能需要检查它,但是,您需要在您的测试仍在运行时进行检查。
您可以通过以下程序获取堆内存大小。
public class GetHeapSize {
public static void main(String[] args) {
long heapsize = Runtime.getRuntime().totalMemory();
System.out.println("heapsize is :: " + heapsize);
}
}
那么相应地,您也可以使用以下方法增加堆大小:java -Xmx2g http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
要增加堆大小,您可以在启动 Java 时使用 -Xmx 参数; 例如
-Xmx256M
- 据我所知,堆空间仅被实例变量占用。 如果这是正确的,那么为什么在运行良好一段时间后会发生此错误,因为在创建对象时分配了实例变量的空间。
这意味着您将在一段时间内连续在应用程序中创建更多对象。 新对象将存储在堆内存中,这就是堆内存增长的原因。
堆不仅包含实例变量。 它将存储所有非原始数据类型(对象)。 这些对象的生命周期可能很短(方法块)或很长(直到该对象在您的应用程序中被引用)
- 有没有办法增加堆空间?
是的。 请查看这篇 oracle 文章以了解更多详细信息。
设置堆大小有两个参数:
-Xms: ,设置初始和最小堆大小
-Xmx: ,设置最大堆大小
- 我应该对我的程序进行哪些更改,以便它占用更少的堆空间?
这取决于您的应用程序。
根据您的应用程序要求设置最大堆内存
不要在您的应用程序中造成内存泄漏
如果您在应用程序中发现内存泄漏,请借助MAT 、Visual VM 、 jconsole等分析工具找到根本原因。找到根本原因后,修复泄漏。
oracle 文章中的重要说明
原因:Java 堆空间的详细消息指示无法在 Java 堆中分配对象。 此错误不一定意味着内存泄漏。
可能的原因:
另一方面,使用更好的垃圾收集算法( CMS或G1GC )
看看这个问题以了解 G1GC
在大多数情况下,代码没有优化。 释放那些您认为不再需要的对象。 避免每次都在循环中创建对象。 尝试使用缓存。 我不知道你的申请进展如何。 但在编程中,一条正常生活的规则也适用
预防胜于治疗。 “不要创建不必要的对象”
局部变量位于堆栈上。 堆空间被对象占用。
您可以使用-Xmx
选项。
基本上,每次你用new
分配一个新对象时,堆空间都会用完,并在该对象不再被引用后释放一段时间。 因此,请确保不要保留对不再需要的对象的引用。
不,我认为您正在考虑堆栈空间。 堆空间被对象占用。 增加它的方法是-Xmx256m,将256替换为您在命令行上需要的数量。
为避免该异常,如果您使用 JUnit 和 Spring,请尝试在每个测试类中添加它:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
在netbeans中,转到“运行”工具栏,-->“设置项目配置”-->“自定义”-->弹出窗口的“运行”-->“VM选项”-->填写“-Xms2048m” -Xmx2048m'。 它可以解决堆大小问题。
我已经尝试了所有解决方案,但上述解决方案没有任何效果
解决方案:在我的情况下,我使用的是 4GB RAM,由于 RAM 使用率达到 98%,因此如果内存不可用,则所需的数量。 也请查找此问题。如果出现此类问题,请升级 RAM,它会正常工作。
希望这会节省一些人的时间
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.