如何释放记忆?

java memory-leaks websphere out-of-memory

4831 观看

6回复

1473 作者的声誉

我们的App服务器有一段时间以来一直面临Out of Memory错误。我们看到使用的堆大小逐渐增加,直到最终达到可用堆的大小。这种情况每3周发生一次,之后需要重新启动服务器才能解决此问题。在分析堆转储时,我们发现问题是JSP中使用的对象。

JSP对象能否成为Appserver内存问题的真正原因?我们如何释放JSP对象(使用usebean或其他标签实例化的对象)?

我们有一个具有2个节点和IHS的集群Websphere应用服务器。

编辑:上面的发现是基于下面给出的使用IBM支持助手的堆转储和nativestderr日志分析

nativestd错误日志分析:

alt text http://saregos.com/wp-content/uploads/2010/03/chart.jpg

堆转储分析:

![alt text] [2]

堆转储分析显示直接支配者(上图中可稳定条目的2级)

![alt text] [3]

最后一张图显示了直接支配者实际上是在JSP中使用的对象。

EDIT2:更多信息,请访问http://saregos.com/?p=43

作者: sarego 的来源 发布者: 2010 年 3 月 24 日

回应 (6)


7

2335 作者的声誉

决定

手动触发垃圾收集并不能解决您的问题 - 它不会释放仍在使用的资源。

您应该使用分析工具(如jProfiler)来查找泄漏。您可以使用代码来存储在运行时期间未发布的列表或映射中的引用 - 可能是静态引用。

作者: Daniel Bleisteiner 发布者: 29.03.2010 07:30

1

4876 作者的声誉

至少据我所知,没有特定的释放JSP中分配的对象。我宁愿专注于找到应用程序代码中的实际问题并修复它,而不是调查这些选项。

一些可能有用的提示:

  • 检查bean的范围。您是不是例如将某些用户或特定请求存储到“应用程序”范围内(错误地)?
  • 检查Web应用程序和应用程序服务器设置中的Web会话超时设置。
  • 你提到堆消耗逐渐增长。如果确实如此,请尝试查看堆大小随着各种用户场景增长的程度:抓住堆转储,运行测试,让会话数据超时,抓住另一个转储,比较两者。这可能会让你知道堆上的对象来自何处
  • 检查你的bean是否有任何明显的内存泄漏,当然:)

编辑:检查Daniel提到的未发布的静态资源是另一个有价值的事情:)

作者: david a. 发布者: 30.03.2010 01:47

8

3848 作者的声誉

我首先附上一个配置文件工具来告诉你这些“对象”占用了所有内存。

Eclipse有TPTP,或者有JProfiler或JProbe。

其中任何一个都应该显示对象堆刷新并允许您检查它以查看堆上的内容。

然后搜索代码库以查找创建这些代码的人员。

也许您有一个包含元素的缓存或树/地图对象,并且您只在这些对象上实现了“equals()”方法,并且您需要实现“hashcode()”。这将导致map / cache / tree变得越来越大,直到它倒下。这只是猜测。

JProfiler将是我的第一个电话

Javaworld有内存中的内容的示例屏幕截图...

替代文字
(来源:javaworld.com

并且对象堆构建和清理的屏幕截图(因此锯边缘)

替代文字
(来源:javaworld.com

更新*************************************************

好的,我看看......

http://www-01.ibm.com/support/docview.wss?uid=swg1PK38940

堆使用量随着时间的推移而增加,从而导致OutOfMemory条件。对heapdump的分析表明以下对象占用了越来越多的空间:

40,543,128 [304] 47班

com / ibm / wsspi / rasdiag / DiagnosticConfigHome 40,539,056 [56] 2 java / util / Hashtable 0xa8089170 40,539,000 [2,064] 511 java / util / Hashtable数组$ Entry 6,300,888 [40] 3 java / util / Hashtable $ HashtableCacheHashEntry

作者: jeff porter 发布者: 30.03.2010 01:57

2

58788 作者的声誉

如果您在Sun 6 JVM下运行,请考虑使用JDK中的jvisualvm程序来初步了解程序内部的实际情况。快照比较非常适合帮助您进一步了解哪些对象潜入。

如果Sun 6 JVM不是一个选项,那么请调查您拥有的分析工具。试验可以让你真的很远。

它可以像您在列表中收集的子字符串中的巨大字符数组一样简单,例如内务处理。

作者: Thorbjørn Ravn Andersen 发布者: 30.03.2010 01:59

2

499545 作者的声誉

我建议阅读Effective Java,第2章。在它之后,与分析器一起,将帮助您识别应用程序产生内存泄漏的位置。

释放内存不是解决大量内存消耗的方法。大量内存消耗可能是两件事的结果:

  • 没有正确编写代码 - 解决方案是正确编写它,以便它不会消耗超过需要的东西 - 有效的Java将在这里提供帮助。
  • 应用程序只需要这么多内存。然后,你应该增加使用VM的内存XmxXmsXX:MaxHeapSize,...
作者: Bozho 发布者: 31.03.2010 10:46

0

6604 作者的声誉

据我所知,那些顶级的内存消费者是缓存存储和存储在其中的对象。可能你应该确保你的缓存在占用太多内存时会释放对象。如果只需要活动对象的缓存,则可能需要使用weak-ref。

作者: ony 发布者: 04.04.2010 06:49
32x32