zhoujuan520
2008-07-02 16:39
浏览 300
已采纳

为什么我用hibernate创建的对象不被垃圾回收(即使会话过期也不消失)

为什么Hibernate创建的对象不被销毁呢?
如图(1)先用hibernate查询,创建了36(TMain.java)个对象
然后再用jdbc查询如图(2)创建了37(TMain2.java)个对象
系统设置会话过期时间为2分钟
会话过期后如图(3)jdbc创建的对象消失了36个,而hibrenate创建的对象一个也没有消失,并且可以看到CGLIB代理对象也没有消失
这是为什么?小弟不才,没有仔细读过hibernate源代码,对其中原因不明。希望各位帮助解惑,版主请别删贴。
[img]http://yourgame.iteye.com/upload/picture/pic/17123/074d52d8-3774-394b-8a7b-ce26f889dfee.jpg[/img]
图(1)
[img]http://yourgame.iteye.com/upload/picture/pic/17121/5c4baf23-28b2-3216-82fc-35f9a23f37ad.jpg[/img]
图(2)
[img]http://yourgame.iteye.com/upload/picture/pic/17119/c15ade7d-a0c3-3c25-8afa-962b5eab0c64.jpg[/img]
图(3)
WEB.xml
[code="xml"]<?xml version="1.0" encoding="UTF-8"?>


service
org.test.Service


service
/servlet/service


<!-- 这里为了测试,设置session国企时间为2分钟 -->
2


[/code]

Hibernate.cfg.xml (hibernate 配置文件)
[code="xml"]
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">


sa
jdbc:jtds:sqlserver://127.0.0.1:1433/fast
org.hibernate.dialect.SQLServerDialect
jtds
yourgame
net.sourceforge.jtds.jdbc.Driver
true



[/code]

Service.java
[code="java"]
package org.test;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Session;

@SuppressWarnings("serial")
public class Service extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String method = request.getParameter("method");
    List list = null;
    if (method.equals("hibernate")) { // 判断查询的方式
        list = this.hibernate(request, response);
    }
    if (method.equals("jdbc")) {
        list = this.jdbc(request, response);
    }
    request.setAttribute("list", list); //将查询的结果集放入request中
    request.getRequestDispatcher("/index.jsp").forward(request, response);

}

/**
 * 2008-7-1-上午11:05:41
 * 
 * 功能:通过Hibernate来查询对象返回集合
 * 
 */
private List hibernate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Session session = HibernateUtils.getSession();
    session.beginTransaction();
    List list = session.createQuery("from TMain").list();
    session.getTransaction().commit();
    HibernateUtils.closeSession(session);
    return list;
}

/**
 * 2008-7-1-上午11:06:20
 * 
 * 功能:通过jdbc查询对象返回集合,Utils.list()方法将结果集封装成javabean
 * 
 */
private List jdbc(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    return Utils.list(new TMain2(), "t_main", null, new Conn());
}

}
[/code]
TMain.java (这个javabean用户Hibernate映射)
[code="java"]package org.test;

public class TMain implements java.io.Serializable {
private Integer id;
private String uuid;
其他字段和setter,getter() 略………

TMain2.java(和TMain.java 一样,这个javabean用于jdbc结果集封装)
[/code]

[b]问题补充:[/b]
package com.bjsxt.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {

private static SessionFactory factory;

private HibernateUtils() {

}

static {
    Configuration cfg = new Configuration().configure();
    factory = cfg.buildSessionFactory();
}

public static SessionFactory getSessionFactory() {
    return factory;
}

public static Session getSession() {
    return factory.openSession();
}

public static void closeSession(Session session) {
    if (session != null) {
        if (session.isOpen()) {
            session.close();
        } 
    }
}

}

[b]问题补充:[/b]
请问wangxin0072000

您指的是不是spring的OpenSessionInView ???
[b]问题补充:[/b]
请问wangxin0072000:
OpenSessionInView 的作用就是把hiernate的Session保持到页面或者说保持到请求完成后再关闭吗?
[b]问题补充:[/b]
请问请问wangxin0072000:
我按照您说的调用System.gc();

效果可以,但是还有一些对象没有消失,org.test.TMain$$BulkBeanByCGLIB$$6d008257
org.test.TMain$$FastClassByCGLIB$$2519251b
org.test.Service
org.test.TMain
以上类的实例都还存在一个实例不被回收,请问这是什么原因呢?
[b]问题补充:[/b]
请问wangxin0072000
按照您说的调用System.gc()方法很凑效,对象大部分都消失了
但是还有四个实例不被回收
分别是
org.test.TMain (1个)
org.test.Service (1个)
org.test.TMain$$FastClassByCGLIB$$2519251b (1个)
org.test.TMain$$BulkBeanByCGLIB$$6d008257 (1个)

无论我调用多少次System.gc() 这些对象也不会被回收
请您帮助

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 邀请回答

6条回答 默认 最新

  • wangxin0072000 2008-07-02 21:16
    最佳回答

    那么有可能是垃圾回收器一直没有回收。你试试手动回收一下。
    见:
    [code="java"]public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String method = request.getParameter("method");

    List list = null;

    if (method.equals("hibernate")) { // 判断查询的方式

    list = this.hibernate(request, response);

    }

    if (method.equals("jdbc")) {

    list = this.jdbc(request, response);

    }

    if (method.equals("gc")) {

    System.gc( );
    list=new ArrayList();

    }
    request.setAttribute("list", list); //将查询的结果集放入request中

    request.getRequestDispatcher("/index.jsp").forward(request, response);

    }  [/code] 
    

    之后等用hibernate测完之后,用method=gc为参数再来一次。之后再看看。

    评论
    解决 无用
    打赏 举报
查看更多回答(5条)

相关推荐 更多相似问题