我正在使用 Play! Framework 构建 Java web 应用,并将其托管在 playapps.net 上。我一直在研究有关内存消耗的提供的图表,这是一个示例:
该图来自于一段持续但正常的活动期间。我没有执行任何操作触发内存下降,因此我认为这是因为垃圾收集器运行了,因为它几乎达到了允许的内存消耗。
我的问题:
- 我是否可以认为我的应用程序没有内存泄漏,因为当垃圾收集器运行时,所有内存都被正确回收了?
- (从标题) 为什么 Java 要等到最后一刻才运行垃圾收集器?随着内存消耗增长到图表的前四分之一,我看到了明显的性能下降。
- 如果我上面的说法是正确的,那么我该如何解决这个问题?我在 Stack Overflow 上读到的其他帖子似乎反对调用
System.gc()
,从中立的("这只是运行 GC 的请求,因此 JVM 可能会忽略你")到彻底反对的("依赖于System.gc()
的代码基本上是有缺陷的")。或者我说错了,我应该寻找自己代码中引起此行为和间歇性性能损失的缺陷?
更新:
我已在 PlayApps.net 上开启了一次讨论,指向这个问题并提到了这里的一些要点;特别是 @Affe 的评论关于完整 GC 的设置非常保守,以及 @G_H 的评论关于初始堆大小和最大堆大小的设置。
这里是一篇讨论链接,不过需要一个playapps账户才能查看。
当我得到反馈后,我会在这里报告。非常感谢大家的回答,我已经从中学到了很多!
解决方法
Playapps的支持人员非常好,但他们没有太多建议。他们唯一的想法是,如果我经常使用缓存,可能会使对象的生命周期比必要的长,但事实并非如此。我仍然学到了很多(呼啦哇啦!),我给@Ryan Amos打了勾,因为我采纳了他的建议,每半天调用一次System.gc()
,现在它正常运行。