我有一个正在运行的java webapp,我正在使用 visualVM 进行监控。
这是堆的图表:
测试了两组请求,一组在3:20,另一组在4:40 aprox(它们在图中表示为唯一的两个峰值)。
我的问题是:这是否意味着我有内存泄漏?我担心中间部分,尽管GC运行,堆仍然一直保持在250MB。
非常感谢您的见解。
答案 0 :(得分:5)
3:20的第一个请求导致一些内存被保留,但请注意第二个请求后的GC回收了大部分内存。此外,我认为主要GC仅在4:40的第二次请求之后执行。
看起来没有泄漏。我的理论是,3:20的请求导致年轻一代填满,由此产生的次要GC将一些对象提升到老一代。由4:40请求引起的下一个主要GC清除了大部分内容。
您可以使用分析器在发出与3:20处的请求相同的请求之前标记堆,强制执行完整的GC,然后检查哪些对象处于延迟状态来验证这一点。我不确定VisualVM是否允许您(1)标记堆并且(2)强制使用完整的GC,但OptimizeIt曾经这样做。
答案 1 :(得分:0)
你是说3:20之前没有请求吗?如果是这样,我会说我没有看到任何泄漏的证据。
我不知道您的应用程序,但对于某些在JVM生命周期中闲置的对象,通常会(基于体系结构/设计)在第一次使用该应用程序时进行初始化。
答案 2 :(得分:0)
你使用什么JRE?将哪些堆/ GC相关参数传递给应用程序?
峰值并不差(如果服务器有更多的待办事项,那么峰值增加是有道理的)。但是看起来不太好,4:40之后的水平(当负荷再次低时)随着负荷上升之前的水平而升高。但它不需要......
现在您应该查看更多细节,哪些对象或对象图保存在堆中。所以再次进行相同的测试运行,包括(使用分析器):
现在你应该分析差异,以及你是否看到应该被劫持的奇怪物体。
答案 3 :(得分:0)
JvisualVM允许您强制进行垃圾回收。
尝试使用它来查看会发生什么。
答案 4 :(得分:-1)
这里的内存泄漏是什么意思?我认为任何像SUN这样的JVM实现都不会有这样一个疯狂的bug。当你没有引用内存位置(僵尸)或者你没有任何回收它的可能性时,理想情况下使用内存泄漏字。如果你有错误的编程习惯,你持有对不再使用的对象的引用,并且它们在更大的范围内(生命周期),那么你会占用更多的内存而不给GC重新收集它。