gpt4 book ai didi

java - java 为什么要等这么久才能运行垃圾收集器?

转载 作者:IT老高 更新时间:2023-10-28 20:32:42 29 4
gpt4 key购买 nike

我正在构建一个 Java Web 应用程序,使用 Play! Framework .我在 playapps.net 上托管它.我一直对提供的内存消耗图表感到困惑。这是一个示例:

Heap Memory

该图表来自一段持续但名义上的 Activity 。我没有采取任何措施来触发内存下降,所以我认为这是因为垃圾收集器运行时几乎达到了允许的内存消耗。

我的问题:

  • 假设我的应用程序没有有内存泄漏对我来说公平吗,因为垃圾收集器在运行时似乎正确回收了所有内存?
  • (来自标题)为什么java要等到最后一秒才能运行垃圾收集器?随着内存消耗增长到图表的前四分之一,我发现性能显着下降。
  • 如果我上面的断言是正确的,那么我该如何解决这个问题?我在 SO 上阅读的其他帖子似乎反对对 System.gc() 的调用,范围从中立(“它只是运行 GC 的请求,因此 JVM 可能会忽略你”)到彻底反对(“依赖于 System.gc() 的代码从根本上被破坏了”)。还是我在这里偏离了基地,我应该在自己的代码中寻找导致这种行为和间歇性性能损失的缺陷?

更新
我已经在 PlayApps.net 上针对这个问题展开了讨论,并在此处提到了一些要点;特别是@Affe 关于完整 GC 设置的评论非常保守,@G_H 关于初始和最大堆大小设置的评论。

这是 link to the discussion ,不过很遗憾,您需要一个 playapps 帐户才能查看它。

我收到反馈后会在这里报告;非常感谢大家的回答,我已经从他们那里学到了很多东西!

分辨率
Playapps 支持仍然很棒,但对我没有太多建议,他们唯一的想法是,如果我广泛使用缓存,这可能会使对象的存活时间超过需要的时间,但事实并非如此。我仍然学到了很多东西(哇哦!),我给了@Ryan Amos 的绿色检查,因为我接受了他的建议,即每半天调用一次 System.gc(),目前效果很好。

最佳答案

任何详细的答案都将取决于您使用的垃圾收集器,但有些东西在所有(现代、sun/oracle)GC 中基本相同。

每次你看到图表中的使用量下降,那就是垃圾回收。释放堆的唯一方法是通过垃圾收集。问题是有两种类型的垃圾收集,次要的和完整的。堆被分成两个基本的“区域”。年轻有为。 (实际上有更多的子组。)任何在 Young 中占用空间并且在 Minor GC 出现以释放一些内存时仍在使用的东西,都将被“提升”为tenured。一旦某个东西跃入终身,它就会无限期地停留,直到堆没有可用空间并且需要进行完整的垃圾回收。

因此,对该图的一种解释是,您的年轻代相当小(默认情况下,在某些 JVM 上,它可能占总堆的一小部分),并且您要让对象“Activity ”相当长的时间。 (也许你在网络 session 中持有对它们的引用?)所以你的对象在被提升到永久空间之前是“幸存的”垃圾收集,在那里它们无限期地停留,直到 JVM 运行良好并且真正内存不足。

同样,这只是与您拥有的数据相符的一种常见情况。需要有关 JVM 配置和 GC 日志的完整详细信息才能真正确定发生了什么。

关于java - java 为什么要等这么久才能运行垃圾收集器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7114661/

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