Java 如何释放内存?

Java 如何释放内存?,java,memory-leaks,websphere,out-of-memory,Java,Memory Leaks,Websphere,Out Of Memory,一段时间以来,我们的应用服务器一直面临内存不足错误。我们看到使用的堆大小逐渐增加,直到最终达到可用堆的大小。这种情况每3周发生一次,之后需要重新启动服务器以修复此问题。 通过对堆转储的分析,我们发现问题在于JSP中使用的对象 JSP对象是否是Appserver内存问题的真正原因?我们如何释放JSP对象(使用usebean或其他标记实例化的对象) 我们有一个具有2个节点和一个IHS的集群WebSphereAppServer 编辑:以上发现基于下面使用IBM support assistant给出的

一段时间以来,我们的应用服务器一直面临内存不足错误。我们看到使用的堆大小逐渐增加,直到最终达到可用堆的大小。这种情况每3周发生一次,之后需要重新启动服务器以修复此问题。 通过对堆转储的分析,我们发现问题在于JSP中使用的对象

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

我们有一个具有2个节点和一个IHS的集群WebSphereAppServer

编辑:以上发现基于下面使用IBM support assistant给出的堆转储和nativestderr日志分析

nativestd错误日志分析:

堆转储分析:

!![备选案文][2]

堆转储分析显示直接支配者(上图中hastable项的上两级)

!![备选案文][3]

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


EDIT2:有关详细信息,请访问

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


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

至少据我所知,没有特定的方法来释放JSP中分配的对象。与其研究这些选项,我更愿意专注于发现应用程序代码中的实际问题并加以解决

一些可能有帮助的提示:

  • 检查bean的范围。不是 例如,存储用户或用户的某物 请求特定于“应用程序” 范围(错误)
  • 检查web应用程序中的web会话超时设置,然后重试 appserver设置
  • 您提到了堆消耗逐渐增长。如果确实如此, 尝试查看堆的大小 随着各种用户场景的增长: 抓起一个heapdump,运行一个测试,让 会话数据超时,获取另一个 转储,比较两者。那可能 让您了解堆上的对象来自何处
  • 检查您的bean是否存在任何明显的内存泄漏,请确保:)

编辑:检查Daniel提到的未发布的静态资源是另一件值得做的事情:)

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

Eclipse有TPTP, 或者有一个JProfiler 或者JProbe

其中任何一个都应该显示对象堆正在破裂,并允许您检查它以查看堆上有什么

然后搜索代码库以查找谁在创建这些代码

可能您有一个缓存或树/映射对象,其中包含元素,并且您只在这些对象上实现了“equals()”方法,您需要实现“hashcode()”。 这将导致映射/缓存/树变得越来越大,直到它倒下。 不过这只是一个猜测

JProfiler将是我的第一个电话

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


(来源:)

以及对象堆堆积和清理的屏幕截图(因此是锯边)


(来源:)

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

好的,我会看看

堆使用率会随着时间的推移而增加,这会导致内存不足 条件对heapdump的分析表明: 对象正在占用越来越多的空间:

40543128[304]47类

com/ibm/wsspi/rasdiag/diagnosticsconfighome 40539056[56]2 java/util/Hashtable 0xa8089170 40539000[2064]511 java/util/Hashtable$Entry数组
6300888(40)3 java/UTIL/HASTABLE $ HASTABECALACHEAJECTION< /P> < P>如果您在Sun下运行,JVM强烈考虑使用JDK中的JVisualVM程序来对程序中实际发生的内容进行初步概述。快照比较非常有助于进一步了解哪些对象潜入其中

如果Sun 6 JVM不是一个选项,那么调查您有哪些评测工具。试炼可以让你走得更远

它可以是一些简单的东西,比如你正在列表中收集的子字符串下面的巨大字符数组,例如内务管理。

我建议阅读。接下来,再加上一个探查器,将帮助您识别应用程序产生内存泄漏的地方

释放内存不是解决大量内存消耗的方法。大量内存消耗可能是由两方面造成的:

  • 未正确编写代码-解决方案是正确编写代码,这样就不会消耗超过需要的代码-高效的Java将在这方面有所帮助
  • 应用程序只需要这么多内存。然后您应该使用
    Xmx
    Xms
    XX:MaxHeapSize

据我所知,这些顶级内存读取程序是缓存存储和其中存储的对象。可能您应该确保缓存在占用太多内存时释放对象。如果只需要对活动对象进行缓存,则可能需要使用弱引用。

我想起了一个与未预编译的JSP部署相关的旧内存泄漏问题。sun编译器内存泄漏,JSP被引用时正在动态编译,这最终导致内存不足错误。解决方案是在部署之前预编译JSP。但是在我们的例子中,堆耗尽是渐进的。内存将在3周内用完。这看起来不像是预编译问题。此外,我们会在3周前预编译我们的JSPs3——不管应用程序中做了什么?你用过定时器相关的东西吗?听起来像是一个没有正确发布的周期性操作。如果您使用的是最新版本的Java,请确保使用附带的VisualVM进行评测。。。您可以拍摄以下对象的快照: