我一直在使用多个模块在 Java 上开展这个项目。很长一段时间以来,我偶尔会收到“java:Out Of Memory”错误!我对这个“流行”错误很陌生,想知道解决此类错误的一般方法。
此外,是否有行业接受的标准工具来帮助找出此类错误的原因?我项目中的模块包括来自第三方
的每分钟轮询(使用 Web 服务)、多线程等。但是,这只是一个指针,我寻求一种通用方法,而不是针对我的项目非常具体的方法。
谢谢。
5 回答
有时您只是有一个使用大量内存的类,您需要增加堆大小或制定更节省空间的算法。其他时候它是一个泄漏,你需要尊重对象。
- 运行
jvisualvm
(它包含在 JDK 中)。 - 连接到您的进程并尝试在注意堆大小的同时重新创建内存不足错误。
- 当内存变大时执行堆转储。按大小搜索最大的物体——通常这会给你带来罪魁祸首。
- 查看依赖项以查看包含引用的内容。如果是内存泄漏,请确保取消引用不需要的对象。
如果不能增加可用内存,则必须减少消耗。
不要保留对执行时不需要的对象的引用(例如可以动态重新加载的数据),如果有必要,请重新设计流程(例如,不要并行处理所有对象并按顺序执行)以减少需要当时的记忆。垃圾收集应该为您完成其余的工作。
特别是如果您将大数据对象加载到内存中,请尽可能考虑使用流式处理方法。例如,如果您想通过它进行搜索,您不需要将整个文件加载到内存中。你可以一步一步来。
除了架构问题之外,您还可能遇到泄漏:保留对不再需要的对象的无意引用。由于它们被引用,垃圾收集器无法释放内存,并且您有时会耗尽内存。这可能是 OutOfMemoryExceptions 的#1 原因,它通常与static
类的引用有关,因此在您第一次接触类后static
通常不会卸载s。互联网上有很多关于查找/修复这些的文章,例如How to Fix Memory Leaks in Java
我知道的一种工具是MAT
您可能有内存泄漏。找到它是一个挑战。Netbeans 有一些工具可以帮助您分析 VM。您可以在项目运行时分析您的项目并查看男性使用情况。Apache JMeter 也可以作为插件使用,或者您可以单独运行它。JMeter.apache.org
如果您经常遇到 OOM,请使用正确的选项启动 java,获取堆转储并使用 jhat 或 eclipse 中的内存分析器进行分析(http://www.eclipse.org/mat/)
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump file>