如何释放内存?
一段时间以来,我们的应用程序服务器一直面临内存不足错误。我们看到已用堆大小逐渐增加,直到最终达到可用堆大小。这种情况每 3 周发生一次,之后需要重新启动服务器来解决此问题。 通过分析堆转储,我们发现问题出在 JSP 中使用的对象上。
JSP 对象是否是 Appserver 内存问题的真正原因?我们如何释放 JSP 对象(使用 usebean 或其他标记实例化的对象)?
我们有一个具有 2 个节点和一个 IHS 的集群式 Websphere 应用程序服务器。
编辑:上述结果基于下面给出的堆转储和nativestderr日志分析,使用IBM支持助手
nativestd错误日志分析:
替代文本 http://saregos.com/wp-content/uploads/2010/03/chart.jpg
堆转储分析:
![替代文本][2]
显示直接支配者的堆转储分析(上图中的 hastable 条目向上 2 级)
![alt text][3]
最后一张图像显示直接支配者实际上是 JSP 中使用的对象。
EDIT2:更多信息可在 http://saregos.com/?p=43
We have been facing Out of Memory errors in our App server for sometime. We see the used heap size increasing gradually until finally it reaches the available heap in size. This happens every 3 weeks after which a server restart is needed to fix this.
Upon analysis of the heap dumps we find the problem to be objects used in JSPs.
Can JSP objects be the real cause of Appserver memory issues? How do we free up JSP objects (Objects which are being instantiated using usebean or other tags)?
We have a clustered Websphere appserver with 2 nodes and an IHS.
EDIT: The findings above are based on the heap-dump and nativestderr log analysis given below using the IBM support assistant
nativestd err log analysis:
alt text http://saregos.com/wp-content/uploads/2010/03/chart.jpg
Heap dump analysis:
![alt text][2]
Heap dump analysis showing the immediate dominators (2 levels up of hastable entry in the image above)
![alt text][3]
The last image shows that the immediate dominators are in fact objects being used in JSPs.
EDIT2: More info available at http://saregos.com/?p=43
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我首先会附加一个配置文件工具来告诉您这些占用所有内存的“对象”是什么。
Eclipse 有 TPTP,
或者有 JProfiler
或 JProbe。
其中任何一个都应该显示对象堆正在增加,并允许您检查它以查看堆上有什么。
然后搜索代码库以查找是谁创建了这些。
也许您有一个包含元素的缓存或树/地图对象,并且您只在这些对象上实现了“equals()”方法,并且需要实现“hashcode()”。
这将导致地图/缓存/树变得越来越大,直到倒下。
但这只是一个猜测。
JProfiler 将是我的第一个电话
Javaworld 有内存中内容的示例屏幕截图...
(来源:javaworld.com< /a>)
以及对象堆建立和清理的屏幕截图(因此锯边)
(来源:javaworld.com< /a>)
更新 ********************************************* ********
好吧,我看看...
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/哈希表 0xa8089170
40,539,000 [2,064] 511 java/util/Hashtable$Entry 数组
6,300,888 [40] 3 java/util/Hashtable$HashtableCacheHashEntry
I'd first attach a profile tool to tell you what these "Objects" are that are taking up all the memory.
Eclipse has TPTP,
or there is JProfiler
or JProbe.
Any of these should show the object heap creaping up and allow you to inspect it to see what is on the heap.
Then search the code base to find who is creating these.
Maybe you have a cache or tree/map object with elements in and you have only implemented the "equals()" method on these objects, and you need to implement "hashcode()".
This would then result in the map/cache/tree getting bigger and bigger till it falls over.
This is only a guess though.
JProfiler would be my first call
Javaworld has example screen shot of what is in memory...
(source: javaworld.com)
And a screen shot of object heap building up and being cleaned up (hence the saw edge)
(source: javaworld.com)
UPDATE *************************************************
Ok, I'd look at...
http://www-01.ibm.com/support/docview.wss?uid=swg1PK38940
Heap usage increases over time which leads to an OutOfMemory
condition. Analysis of a heapdump shows that the following
objects are taking up an increasing amount of space:
40,543,128 [304] 47 class
com/ibm/wsspi/rasdiag/DiagnosticConfigHome
40,539,056 [56] 2 java/util/Hashtable 0xa8089170
40,539,000 [2,064] 511 array of java/util/Hashtable$Entry
6,300,888 [40] 3 java/util/Hashtable$HashtableCacheHashEntry
手动触发垃圾收集并不能解决您的问题 - 它不会释放仍在使用的资源。
您应该使用分析工具(如 jProfiler)来查找泄漏。您可能使用将引用存储在运行时期间未释放的列表或映射中的代码 - 可能是静态引用。
Triggering the garbage collection manually doesn't solve your problem - it won't free resources that are still in use.
You should use a profiling tool (like jProfiler) to find your leaks. You problably use code that stores references in lists or maps that are not released during runtime - propably static references.
如果您在 Sun 6 JVM 下运行,请强烈考虑使用 JDK 中的 jvisualvm 程序来初步了解程序内部实际发生的情况。快照比较确实可以很好地帮助您进一步了解潜入的对象。
如果 Sun 6 JVM 不是一个选项,那么请调查您拥有哪些分析工具。尝试可以让你走得更远。
它可以是简单的东西,就像您在列表中收集的子字符串下面的巨大字符数组一样,例如内务处理。
If you run under the Sun 6 JVM strongly consider to use the jvisualvm program in the JDK to get an inital overview of what actually goes on inside the program. The snapshot comparison is really good to help you get further in which objects sneak in.
If Sun 6 JVM is not an option, then investigate which profiling tools you have. Trials can get you really far.
It can be something as simple as gigantic character arrays underlying a substring you are collecting in a list, for e.g. housekeeping.
我建议阅读Effective Java,第 2 章。遵循它以及分析器将帮助您识别应用程序产生内存泄漏的位置。
释放内存并不是解决大量内存消耗的方法。大量的内存消耗可能是由两件事造成的:
Xmx
、Xms
、XX:MaxHeapSize
等增加虚拟机内存。I suggest reading Effective Java, chapter 2. Following it, together with a profiler, will help you identify the places where your application produces memory leaks.
Freeing up memory isn't the way to solve extensive memory consumption. The extensive memory consumption may be a result of two things:
Xmx
,Xms
,XX:MaxHeapSize
,...至少据我所知,没有专门用于释放 JSP 中分配的对象的方法。我宁愿专注于查找应用程序代码中的实际问题并修复它,而不是调查此类选项。
一些可能有帮助的提示:
例如,您存储用户的某些内容或
请求具体到“应用程序”
范围(错误)?
应用程序服务器设置。
尝试查看堆大小有多少
随着不同的用户场景而增长:
获取堆转储,运行测试,让
会话数据超时,再抓取一个
转储,比较两者。那可能
让你知道堆上的对象来自哪里
编辑:检查丹尼尔提到的未释放的静态资源是另一件有价值的事情:)
There is no specific to free up objects allocated in JSPs, at least as far as I know. Rather than investigationg such options, I'd rather focus on finding the actual problem in your application codes and fix it.
Some hints that might help:
you e.g. storing something user or
request specific into "application"
scope (by mistake)?
appserver settings.
try to see by how much the heap size
grows with various user scenarios:
Grab a heapdump, run a test, let the
session data timeout, grab another
dump, compare the two. That might
give you some idea where do the objects on heap come from
EDIT: Checking for unreleased static resources that Daniel mentions is another worthwhile thing :)
据我了解,那些顶级内存消耗者是缓存存储和存储在其中的对象。也许您应该确保缓存在占用过多内存时释放对象。如果您只需要缓存活动对象,您可能需要使用弱引用。
As I understand those top-level memory-eaters are cache storage and objects stored in it. Probably you should make sure that your cache is going to free objects when it takes too much memory. You may want to use weak-ref if you need cache for live objects only.