日期:2014-05-18  浏览次数:20643 次

hibernate中sessionfactory的关闭机制?
我在java应用中使用hibernate连接数据库,不使用spring托管,遇到mysql超时自动断开问题。我百度了一下相关问题的解答,绝大部分是使用连接池,另外的解答是每次连接的时候都创建新的sessionfactory。

经过一天的大量实验,我现在有如下疑问:

在不使用连接池的情况下,也就是只用hibernate的默认连接池的情况下:

我每次数据库操作都创建新的sessionfactory对象,这个方法是能使用的。但是sessionfactory是重量级组件,每次创建非常占内存,因此我实验了一下,用一个for循环,创建3000个sessionfactory对象,发现果然内存直线上升,大概占用了200M左右的内存。我机器上的mysql最大连接数是100,当sessionfactory的数量超过mysql的最大连接时,后面创建的sessionfactory都无法进行数据库操作,但是依旧可以创建,并且占用大量内存。

代码如下:
public void test(){
Configuration cfg = new Configuration().configure();
ArrayList<SessionFactory> al = new ArrayList<SessionFactory>();

for (int i = 0; i < 3000; i++) {

SessionFactory sf = cfg.buildSessionFactory();
          


}


因此,我尝试在每一次创建sessionfactory后,再使用sessionfactory.close()方法将其立即关闭。如此尝试3000次循环后,连接不仅断开了,而且内存几乎没有增加,似乎是sessionfactory对象被回收了。

代码如下:
public void test(){
Configuration cfg = new Configuration().configure();
ArrayList<SessionFactory> al = new ArrayList<SessionFactory>();

for (int i = 0; i < 3000; i++) {
SessionFactory sf = cfg.buildSessionFactory();     
sf.close();
}


我的问题来了:

第一个问题,如果我将每次循环中的sessionfactory对象存入一个arraylist,之后调用了close()方法,连接虽然被断开,但是内存依旧明显增加,也就是似乎sessionfactory对象没有被回收,依旧占用内存。这是为什么呢?是存入arraylist中,系统就不会回收了么?

代码如下:
public void test(){
Configuration cfg = new Configuration().configure();
ArrayList<SessionFactory> al = new ArrayList<SessionFactory>();
for (int i = 0; i < 3000; i++) {
SessionFactory sf = cfg.buildSessionFactory();
            sf.close();
            al.add(sf);
}


第二个问题,如果我在close()之后,再打印出sessionfactory对象的内存地址,依旧可以显示,但是内存没有增加,连接也断开了,似乎是sessionfactory对象被回收了,但是那样为什么还能打印出sessionfactory对象的内存地址呢?

代码如下:
public void test(){
Configuration cfg = new Configuration().configure();
ArrayList<SessionFactory> al = new ArrayList<SessionFactory>();

for (int i = 0; i < 3000; i++) {

SessionFactory sf = cfg.buildSessionFactory();
            sf.close();
           
            System.out.println(i+":"+sf);            
       



}


第三个问题,这个sessionfactory的close()方法,究竟谁是销毁对象,还是单单断开连接?如果是销毁对象,为什么还能读出它的内存地址呢?如果只是断开连接,为什么内存不会增加呢?