如何释放记忆?

时间:2010-03-24 11:56:14

标签: java memory-leaks websphere out-of-memory

我们的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级)

![替代文字] [3]

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

EDIT2:http://saregos.com/?p=43

提供更多信息

6 个答案:

答案 0 :(得分:8)

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

Eclipse有TPTP, 或者有JProfiler 或JProbe。

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

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

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

JProfiler将是我的第一个电话

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

alt text http://www.javaworld.com/javaworld/jw-08-2003/images/jw-0822-profiler16.gif

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

alt text http://www.javaworld.com/javaworld/jw-08-2003/images/jw-0822-profiler19.gif

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

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

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

堆使用量随着时间的推移而增加,从而导致OutOfMemory 条件。分析堆转储显示以下内容 对象占用的空间越来越大:

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

答案 1 :(得分:7)

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

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

答案 2 :(得分:2)

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

如果无法选择Sun 6 JVM,请调查您拥有的分析工具。试炼可以让你走得很远。

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

答案 3 :(得分:2)

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

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

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

答案 4 :(得分:1)

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

一些可能有用的提示:

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

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

答案 5 :(得分:0)

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