我们的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
提供更多信息答案 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。在它之后,与分析器一起,将帮助您识别应用程序产生内存泄漏的位置。
释放内存不是解决大量内存消耗的方法。大量内存消耗可能是两件事的结果:
Xmx
,Xms
,XX:MaxHeapSize
,... 答案 4 :(得分:1)
至少据我所知,没有特定的释放JSP中分配的对象。我宁愿专注于找到应用程序代码中的实际问题并修复它,而不是调查这些选项。
一些可能有用的提示:
编辑:检查Daniel提到的未发布的静态资源是另一个有价值的事情:)
答案 5 :(得分:0)
据我所知,那些顶级的内存消耗者是缓存存储和存储在其中的对象。可能你应该确保你的缓存在占用太多内存时会释放对象。如果只需要实时对象的缓存,则可能需要使用weak-ref。