解决Java内存泄漏的一般策略?
Posted
技术标签:
【中文标题】解决Java内存泄漏的一般策略?【英文标题】:General strategy to resolve Java memory leak? 【发布时间】:2010-12-01 04:55:09 【问题描述】:我有一个在本地运行的独立程序,它是一个 24/7 运行的服务器类型程序。最近我发现它有内存泄漏,现在我们唯一的解决方案是每4小时重新启动一次。查找此内存泄漏的最佳方法是什么?我们应该使用哪种工具和方法?
【问题讨论】:
【参考方案1】:如果您使用 Sun 的 Java 并且至少使用 Java 6 update 10(即最新版本),那么请尝试在您的程序运行的同一台机器上从 JDK 运行 jvisualvm,并附加到它并启用分析。
这很可能是最简单的开始方式。
【讨论】:
上次我检查时,最新的更新是 16... :-) 不过不确定 VisualVM 是什么时候引入的。这么新吗? JVisualVM 是在 1.6.0_07 中添加到 JDK 中的,我相信。 启动 VisualVM。从列表中选择正在运行的进程。右键单击并选择堆转储。让它运行一会儿。捕获另一个堆转储。然后使用 File > Compare Memory Snapshots 查看发生了什么变化。【参考方案2】:当谈到寻找内存问题时,我使用 SAP Memory Analyzer Eclipse Memory Analyser (MAT),一个 Heap Dump 分析工具。
内存分析器提供了一个通用工具包来分析 Java 堆转储。除了堆遍历和快速计算保留大小之外,Eclipse 工具还报告泄漏嫌疑和内存消耗反模式。应用程序的主要领域是内存不足错误和高内存消耗。
该项目由 SAP 发起,现已开源,现在称为Eclipse Memory Analyser。查看Getting Started 页面,尤其是Finding Memory Leaks 部分(我将其粘贴在下面,因为我修复了一些链接):
首先运行leak report 以自动检查内存泄漏。
此博客详情How to Find a Leaking Workbench Window。
内存分析器是在 SAP 成长起来的。那时,克鲁姆在博客上写了Finding Memory Leaks with SAP Memory Analyzer。内容仍然相关!
对于堆转储分析(和内存泄漏),这可能是您可以获得的(即使是为了钱)最好的工具。
PS:我不为 SAP/IBM/Eclipse 工作,我只是一个非常快乐的 MAT 用户,有积极的反馈。
【讨论】:
【参考方案3】:您需要memory profiler。我建议尝试Netbeans profiler。
【讨论】:
【参考方案4】:您可以查找 JMX 和 Java 附带的 jconsole 应用程序。您可以获得一些开箱即用的有趣统计数据,向您的类添加一些简单的工具可以提供更多。
【讨论】:
【参考方案5】:如前所述,jvisualvm 是一种很好的入门方式,但是一旦您知道泄漏了什么,您可能需要找到对我推荐 jmap 和 jhat 的相关对象的引用,例如
jmap -dump:live,file=heap.dump.out,format=b <pid>
和
jhat heap.dump.out
其中
【讨论】:
【参考方案6】:一种方法是定期进行堆转储,然后对类的实例计数进行趋势分析,以尝试找出哪些对象始终被创建但未被收集。
另一种方法是关闭应用程序的某些部分以尝试缩小问题所在。
看看像 jmap 和 jhat 这样的工具。
【讨论】:
【参考方案7】:您需要尝试捕获 Java 堆转储,它是 Java 进程的内存打印。 这是内存消耗优化和查找内存泄漏的关键过程。
Java 堆转储是诊断与内存相关的问题的重要对象,包括 java.lang.OutOfMemoryError、垃圾收集问题和内存泄漏,这些都是 Java Web 开发过程的一部分
为了清楚起见,堆转储包含在拍摄快照的瞬间堆中的 Java 类和对象等信息。
为此,您需要运行jmap -dump:file=myheap.bin <program pid>
。
要了解有关如何捕获 Java 热转储的更多信息,请查看:https://javatutorial.net/capture-java-heap-dump
【讨论】:
以上是关于解决Java内存泄漏的一般策略?的主要内容,如果未能解决你的问题,请参考以下文章