简体   繁体   English

可能的内存泄漏?

[英]Possible Memory Leak?

I've got a running java webapp, that I'm monitoring with visualVM . 我有一个正在运行的java webapp,我正在使用visualVM进行监控。

Here's the graph of the heap: 这是堆的图:

堆

The was tested with two sets of requests, one at 3:20 and the other at 4:40 aprox (they are represented in the graph as the only two peaks). 用两组请求测试,一组在3:20,另一组在4:40 aprox(它们在图中表示为唯一的两个峰)。

My question is: does this means I have a memory leak? 我的问题是:这是否意味着我有内存泄漏? I'm worried about the middle part where, although the GC runs, the heap stays in 250MB all the time. 我担心中间部分,尽管GC运行,堆仍然一直保持在250MB。

Thanks a lot for your insights. 非常感谢您的见解。

The first request at 3:20 caused some memory to be held, but notice that the GCs after the second request reclaimed most of it. 3:20的第一个请求导致了一些内存,但请注意第二个请求后的GC回收了大部分内存。 Also I think that major GC was performed only after the second request at 4:40. 另外我认为主要GC仅在4:40的第二次请求之后才执行。

It looks like there is no leak. 看起来没有泄漏。 My theory is that the request at 3:20 caused the young generation to fill up, and the resulting minor GC promoted some objects to older generation. 我的理论是,3:20的请求导致年轻一代填满,由此产生的次要GC将一些对象提升到老一代。 The next major GC, caused by the request at 4:40 cleaned most of those up. 由4:40的请求引起的下一个主要GC清除了大部分。

You can verify this by using a profiler to mark the heap before issuing the same request as the one at 3:20, forcing a full GC, and then checking what objects are lingering. 您可以使用分析器在发出与3:20处的请求相同的请求之前标记堆,强制执行完整的GC,然后检查哪些对象处于延迟状态来验证这一点。 I am not sure if VisualVM lets you (1) mark the heap and (2) force a full GC, but OptimizeIt used to do it. 我不确定VisualVM是否允许您(1)标记堆并且(2)强制使用完整的GC,但OptimizeIt曾经这样做过。

Are you saying there were no requests before 3:20? 你是说在3:20之前没有请求吗? If so, than I would say I don't see any evidence of a leak. 如果是这样,我会说我没有看到任何泄漏的证据。

I don't know your app, but it's typical (based on architecture/design) for some objects that hang around for the life of the JVM to become initialized when the app is used for the first time. 我不知道你的应用程序,但它是典型的(基于体系结构/设计)一些对象,它们会在第一次使用应用程序时初始化JVM的生命周期。

What JRE are you using? 您使用的JRE是什么? What heap/GC relevant parameters are passed to the application? 将哪些堆/ GC相关参数传递给应用程序?

The peak isn't bad (if there was more todo for the server it makes sense that the peak increases). 峰值并不差(如果服务器有更多的待办事项,那么峰值增加是有道理的)。 But what is looking not so good, that the level after 4:40 (when the load is low again) is higher as the level before load went up. 但是看起来不太好,4:40之后的水平(当负荷再次低时)随着负荷上升之前的水平而升高。 But it doesn't need to be... 但它不需要......

Now you should look into more detail, which objects or object-graphs are kept in heap. 现在您应该查看更多细节,哪些对象或对象图保存在堆中。 So do the same test run again including (with profiler): 所以再次进行相同的测试运行,包括(使用分析器):

  • take a heap snapshot before the load goes up 在负载上升之前获取堆快照
  • take a heap snapshot after the load goes down (be sure to do a manual GC trigger) 在负载下降后获取堆快照(确保执行手动GC触发器)

Now you should analyze the diffs and whether you see weird objects, which should have been garbaged. 现在你应该分析差异,以及你是否看到了奇怪的物体,这些物体本应该被涂抹。

JvisualVM allows you to force a garbage collection. JvisualVM允许您强制进行垃圾回收。

Try using that to see what happens. 尝试使用它来看看会发生什么。

What do you mean by memory leak here? 这里的内存泄漏是什么意思? I don't think any good JVM implementaiton like SUN would have such a crazy bug. 我认为任何像SUN这样的JVM实现都不会有这样一个疯狂的bug。 memory leak word is ideally used when you dont have reference to a memory location (zombie) or you dont have any possibility to reclaim it. 当你没有引用内存位置(僵尸)或者你没有任何回收它的可能性时,理想情况下使用内存泄漏字。 If you have wrong programming practice where you hold reference to objects which are no longer in use and they in larger scope (lifespan) then you eat up more memory not giving the GC an option to re-collect it. 如果你有错误的编程习惯,你持有对不再使用的对象的引用,并且它们在更大的范围内(生命周期),那么你会占用更多的内存而不给GC重新收集它的选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM