内存泄漏检测
我不认识喜欢调查Java堆转储的人。
它们包含的信息太多,以至于确定JVM内存泄漏的原因就像大海捞针。
而且,检查生产系统中的Java堆转储可能会让您无意中拥有个人身份信息,如果处理不当,这些信息可能会让您陷入各种隐私行为的麻烦中,这会使整个文件感觉具有放射性。
如果不是因为这样做几乎是修复JVM中Java内存泄漏的唯一方法,我想说检查Java堆转储根本不值得这么麻烦。或者至少在Java Flight Recorder引入旧的Object Sample事件之前,这是唯一的方法。
基于Java飞行记录器JFR的JVM堆分析
下面是Java飞行记录器的旧对象示例事件的工作方式。
开始录制时,会跟踪Java堆中固定数量的对象。Java堆对象的跟踪属性包括:
- 对象分配开始时间
- 对象的持续时间
- 关联事件线程
- 上次已知堆大小使用情况
- 对象类型
- 垃圾收集根GC ROOT
可以通过调整旧的对象队列站点来调整Flight Recorder跟踪的Java堆上的对象数:
-XX:FlightRecordingOptions=old-object-queue-size=512
JMC任务控制内存泄漏检测
当Java堆上的被跟踪对象被垃圾收集时,它将从样本中移除并添加一个新对象。随着时间的推移,导致内存泄漏的对象更有可能被跟踪。JVM Flight Recorder运行的时间越长,跟踪内存泄漏导致的对象的可能性就越大。
此外,这些导致Java内存泄漏的对象存在的时间越长,消耗的内存越多,在Java任务控制中检查JVM飞行记录时,它们的存在就越明显。
此外,Java任务控制中的规则引擎能够识别哪些长时间运行的Java堆对象最有可能导致JVM内存泄漏。
请注意,Java飞行记录器在设计用于触发内存泄漏的示例应用程序上运行后,Java任务控制立即指示通过旧对象示例事件监视的对象可能是罪魁祸首:
在录制过程中,堆上的实时设置似乎以每秒192 KiB的速度增加。
分析参考树发现1个泄漏候选。主要候选人是java.util.Hashtable
此链引用的$Entry[]
:
java.util.Hashtable.table
se.hirt.jmc.tutorial.memleak.Leak$DemoThread.table
Java堆上的活动对象
除了最初的自动分析之外,Java Mission Control还将提供一个列表,指示堆上所有活动项的大小,以及内存中所有活动对象的列表。如您所见,在不需要求助于JVM堆转储的情况下,可以很容易地识别出Java内存泄漏。
内存泄漏检测最佳实践
显然,内存泄漏检测示例中的示例是一个简单的示例。要在更复杂的示例中识别有问题的对象,请遵循以下内存泄漏检测最佳实践:
- 长时间运行Java飞行记录器。
- 这会增加违规对象的更改以进行采样。
- 查看JVM上消耗内存最多的对象
- 看看JVM上占用内存最多的对象
- 取消JVM启动时分配的对象的优先级。进程初始化会产生很多噪音。
- 在飞行记录器运行过程中分配的对象比在开始或结束时分配的对象更有可能是罪魁祸首
- 监视Java类加载器外部引用的守护进程线程
- 添加自定义触发器以在满足某些内存消耗阈值时启动Java Flight Recorder
- 通过编写自定义飞行记录器事件并在潜在问题点启动它们,将遥测添加到Java应用程序中
- 在内存问题成为严重程度为1的生产问题之前,要积极主动地监控应用程序
注意:
- 静态变量
- 缓存的数据
- 长运行线程
JVM飞行记录仪JFR与任务控制JMC
jvm flight recorder和JDK任务控制提供了各种高级特性,允许开发人员排除Java内存泄漏问题,而无需检查复杂的Java堆转储。熟悉这些功能强大的评测和监视工具,解决Java性能问题将不再是一项繁琐的任务。
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/1152.html
暂无评论