如何处理Java EE中的内存泄漏?
正如我在网络上的某个地方发现的那样,以下项目可能会导致内存泄漏。例如:
- ResultSets 和 Statement 对象
- DataLists
- Collections
- 静态变量和类
- Singletons
- HttpSession 和 HttpRequest
我的 JSF 应用程序中的托管 bean 大部分是 @ViewScoped
,所以我认为离开视图后,GC 有足够的信息可以释放数据列表、对象等。但它还没有或不完全:
我只是手动关闭休眠会话(最后使用),但仅此而已。其余的事情我对 GC 抱有期望。
你能告诉我,
- 如何找到哪些具体对象留在内存中?
- 如何手动离开视图后释放对象?像析构函数之类的东西..?
- 处理内存泄漏的最佳实践是什么?
As I've found somewhere on web, following items can lead to memory leaks. For example:
- ResultSets and Statement objects
- DataLists
- Collections
- Static variables and classes
- Singletons
- HttpSession and HttpRequest
Managed beans in my JSF application are mostly @ViewScoped
, so I thought that after leaving the view, GC has enough informations to release datalists, objects, and so on. But it hasn't or not completelly:
I'm just closing hibernate sessions manually (using finally), but that's all. The rest of things I've expected from GC.
Could you tell me,
- how to find which concrete objects are staying in memory?
- how to release objects after leaving a view manually? something like destructor..?
- what are the best practices in handle memory leaks?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我们在项目中使用了 yourkit (http://www.yourkit.jsp)。 yourkit.com/eap/index.jsp )分析器。我发现用户界面非常友好。
您可以连接到您的 Web 应用程序并了解对象增长情况以及增长率如何。
探查器可帮助您追踪每个对象的起源。因此,您可以找出持有对非垃圾收集对象的引用的父对象。
请注意:
当您加载了 Java 集合并使用完毕后,请分配
collectionObject=null
。我们注意到,即使列表超出了范围,它也不会被垃圾回收,直到它被设置为 null。在循环中创建对象。
跨类引用的对象。这些对象往往会保留在系统中,直到所有引用都被释放。
字符串连接(
String a = b+s
)的成本非常非常高!重载 HTTP 会话
We, in our project, have used yourkit ( http://www.yourkit.com/eap/index.jsp ) profiler. I found the user interface very friendly.
You can connect to your web application and find out the object growth and how the growth rate is.
The profiler helps you trace each object to the the origin. You can hence figure out the parent object that is holding a reference to the object that is not garbage collecting.
Watch out for:
When you have a loaded java collection and are done with it, assign
collectionObject=null
. we noticed that even though the list went out of scope , it was not getting garbage collected until it was set to null.Objects being created in a loop.
objects being referenced across classes. these objects tend to stay in the system until all the references are released.
String concatenations(
String a = b+s
) are very very costly !Overloading HTTP Session
JHat,Eclipse MAT 可能会有所帮助。甚至,JConsole 还提供了有关内存泄漏的足够线索,或者至少提供了有关占用所有 RAM 的内容的线索。
JHat, Eclipse MAT can be helpful. Even, JConsole gives enough clues about memory leaks -- or at least what's hogging all of your RAM.
您应该使用可用的 java 分析器之一。有很多。所有分析器都允许存储快照并比较快照。因此,您应该在开始时存储快照,然后使用您的应用程序执行一些场景,然后再次存储快照并进行比较。你将得到所有不能被GC删除的对象及其引用。然后尝试分析谁持有这些对象的引用以及如何修复该错误。
You should use one of available java profilers. There are a lot. All profilers allow to store snapshot and compare snapshots. So, you should store snapshot in the beginning, then perform some scenario with your application, then store snapshot again and compare. You will get all objects that cannot be removed by GC and their references. Then try to analyze who is holding references to these objects and how to fix the bug.
首先,恕我直言,这不是真正的内存泄漏。 GC时不时的会释放内存。也许你应该向我们展示更长时间的报告。也许某物拿着物体的时间太长了。要查看参考,您可以使用 JProfiler,例如 此处。也尝试 Eclipse Memory Analyzer 自动报告。我认为您应该尝试调整垃圾收集。要查找内存泄漏,请查看此响应 如何查找 Java 内存泄漏
First of all IMHO this is NOT real memmory leak. GC releases memmory from time to time. Maybe you should show us report from longer time. Maybe sth is holding objects too long. To look at references, you can use JProfiler like here. Try Eclipse Memory Analyzer automatic reports too. I think you should try tuning Garbage Collection. And for finding memmory leak look at this response How to find a Java Memory Leak