gpt4 book ai didi

java - 如何判断java应用程序是否接近内存不足

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:13:56 27 4
gpt4 key购买 nike

我的简单目标:监视 Java 应用程序的内存使用情况,以便在应用程序即将抛出 OutOfMemoryError 时收到警告。

是的,说起来很简单,但是想出一个正确的解决方案似乎非常复杂。一些复杂的因素是:

  • 有不同的堆区域,每个区域都可以抛出 OutOfMemoryError:
    • permgen 空间,它有自己的大小限制(通过 -XX:MaxPermSize= 设置)
    • 整体堆空间(通过-Xmx设置)
  • VM 可能会在进行垃圾收集之前分配几乎所有的堆。如果应用程序使用了大量的软引用,那么实际上这肯定会发生。因此,高堆分配百分比并不意味着应用程序即将抛出 OutOfMemoryError
  • 如果 System.gc() 保证 VM 会回收所有可能可回收的对象(未引用和/或弱引用的对象),那就太好了,但事实并非如此。因此调用 System.gc() 然后调用 Runtime.freeMemory() 是不可靠的。
  • 排队等候完成的对象会占用内存,但(通常)在完成后会被释放。因此,终结器线程是否已经到达它们会影响(明显的)内存使用(VM 是否将终结器作为抛出 OOM 之前的最后绝望行为运行?Doesn't look like it.)
  • native 代码也会占用内存,过多地使用它会导致 OOM(在我的特定应用程序中这不太可能发生,但确实会增加整体情况的复杂性)。

那么什么是回答这个问题的可靠方法:我的 Java 应用程序会抛出 OutOfMemoryError 吗?

换句话说,假设应用程序版本 X 运行良好并且没有内存泄漏,但是版本 X + 1 有一个缓慢的无法识别的内存泄漏。我希望在版本 X + 1 抛出 OutOfMemoryError 之前收到此监控的警报,但我希望完全相同的监控不会为版本 X 提供误报。可能需要进行一些调整设置此监控 - 没关系。

一个可能的答案可能是这样的:在过去的 N 次“完整”GC 运行中,GC 运行后立即堆利用率的最大值是多少?如果此值超过分配内存总量的 X%,则发出警报。

我们的想法是用简单的数字(例如百分比,甚至是低、中或高)来确定“应用程序内存使用情况”,然后监控该值。

jstat命令提供了很多相关信息,问题是将其归结为一个简单的答案,并避免由上面列出的复杂因素引起的误报(或否定)。

最佳答案

如果您观察长时间运行的应用程序的内存图(例如,使用 jconsole 等工具收集),您会看到典型的锯齿模式:内存使用率攀升,然后 GC 回到基线,并且然后它再次爬升。对于健康的应用程序,峰谷位于两条直线上。但是,对于泄漏的应用程序,基线会上升。这才是您真正需要注意的:如果每次连续的 GC 都比上一次的效率低,那么丹麦的某些东西已经烂掉了。

关于java - 如何判断java应用程序是否接近内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16988054/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com