【问题标题】:Memory Leak on enum class枚举类的内存泄漏
【发布时间】:2012-08-01 01:58:43
【问题描述】:

我们有一个常量类,它在枚举类中有一个 jsps/servlet 列表。此类从控制器 servlet 中用作重定向。这个特定的类总是在内存分析器中显示为泄漏可疑。

我在这里粘贴来自控制器 servlet 的代码:

 protected void forwardPage(Page jspPage, boolean checkTrail, HttpServletRequest request, HttpServletResponse response) {
 String temp;
 String str = new String();

 str = jspPage.name();

Page page1 =  Page.valueOf(Page.class,str);
    try {
        temp = page1.getFileName();
        getServletContext().getRequestDispatcher(temp).forward(request, response);  
    } catch (Exception se) {
    } finally { 
        page1 = null;
        jspPage = null;
        str = null;
        temp = null;
    }

页面本身是一个枚举类,代码如下..

UPDATE_PROFILE_CONFIRM("/WEB-INF/jsp/login/updateProfileConfirm.jsp", "确认您的个人资料") 公共字符串 getTitle() {

    return this.title;
}


public String getFileName() {
    return this.fileName;
}

public void setFileName(String newFileName) {
    this.fileName = newFileName;
}

我无法理解的是为什么这个类应该泄漏?一旦我删除 Page 的引用并直接重定向,问题似乎就消失了。没有框架,简单的 servlet-jsp 框架。应用服务器是 Tomcat 6 和 JDK 6。

【问题讨论】:

  • 为什么用new String()初始化String str?为什么不让它String pageName = jspPage.name(); 或者就此而言,为什么将它作为一个变量拉出来呢? jspPage.name() 是非常好的自我说明文档。
  • 好吧..这是真的,但我不认为这本身会导致任何泄漏。
  • “这个特定的类总是在内存分析器中显示为泄漏嫌疑人。”您指的是 Page 枚举吗?它是否告诉您堆中有多少个实例?
  • 还有,你为什么要把一个Page作为参数,然后把它改成字符串再转回Page呢?这样做毫无意义。
  • @SimoneGianni 是的,它抱怨 Page Enum 它告诉我总共有 301 个实例,每个实例大小为 44,总大小为 13,244

标签: java jsp tomcat6 memory-leaks


【解决方案1】:

我怀疑由于枚举有 301 个值,因此该枚举的 301 个实例总是在 ram 中,这是正常的,因为这些实例静态链接到枚举类。这不是泄漏,这就是枚举的工作方式。

内存分析器只是告诉您有 13,244 个字节无法回收,这可能会显示为泄漏,但事实并非如此。奇怪的是它不知道枚举,可能根本没想到一个枚举有301个包含很多字节的值,通常枚举有几个元素,存储的值有限,但是有一个像这样的枚举并没有错你的“页面”。

【讨论】:

  • 问题是,当我删除此页面引用并从高频 servlet 之一直接使用转发到 jsp 页面时,系统似乎表现良好?
  • 这可能是因为枚举没有在其他任何地方使用(?)然后它不会被类加载器加载。
  • @TonyLâmpada 你认为调用这个类作为初始化的一部分会对此产生影响吗?
猜你喜欢
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-13
相关资源
最近更新 更多