finalize只有在GC启动时才会调用,如果GC都没启动,那它就根本不会被调用了并不一定是程序结束GC就会启动。

解决方案 »

  1.   

    对,Java的垃圾回收不是变量用完马上就会调用的,实际的使用还是最好显式调用close()。
      

  2.   

    你在JavaBean中根本不应该保持Connection对象,应该在每次使用SQL语句之前从DataSource中获得并在使用完以后马上调用Close方法这样才是使用连接池的方法,实际上Close并不是真正的Close了连接,仅仅是放回了连接池的
      

  3.   

    不可能吧?
    我在tomcat的Log文件里确实看到,finalize被调用了.因为我的:System.out.println("关闭连接池!");
    在控制台显示了很多:关闭连接池!另外:
    我想不断的关闭连接:肯定要影响速度,我想在我的Session操作中,保持数据库的连接,这样可以省去打开数据库的大量时间.显示调用Close在什么地方呢?每个页面执行一次么?这样肯定是不对的.这样得的操作会是老牛拉破车,慢得受不了.不过还是感谢回复
    谢谢!
      

  4.   

    我以前就是采用这种方式,但是,连接最好时间的就是:
    try {
          ctx = new InitialContext();
          if (ctx == null) {
            throw new Exception("没有匹配的环境");
          }
          DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/fxhy");
          if (ds == null) {
            throw new Exception("没有匹配数据库");
          }      conn = ds.getConnection();
          stmt = conn.createStatement(); //ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
        }
        catch (Exception e) {
          System.out.print(e.getMessage());
        }
    如果每个连接都要获得一次,页面会慢得受不了。每个都获得肯定是不合理的。为什么不能保持连接到你不想用的时候再去掉呢?
      

  5.   

    不错,finalize()不是在每个javabean废弃之后就调用的,会话结束后你的连接javabean只是符合了回收的条件,并不一定会立即被回收。
    建议在每个页面中显式关闭连接,不会影响速度,用连接池的好处就在这里,因为实际上它与数据库的连接并没有变化,只有建立和数据库的连接才是费时的操作。
      

  6.   

    to kingfreng(东方岛主) :  谢谢您的回复!不过,我想问一下,你测试过么?
     
      我有很多连续对数据库操作的JSP页面,在当前用户操作的过程中,需要持续的对数据库的连接。  我开始采用每个页面都关闭打开数据库连接池的方式,速度慢的无法忍耐!
      因此我才采用这种把数据库连接做成Bean放到Session变量里面,保持对数据库的连接.这样的速度大大提高.  您说不会影响速度,是从什么角度说的呢?
      

  7.   

    数据库连接池就是解决楼主的问题的。如果你用Session保存连接,那么用连接池岂不是多此一举?
      

  8.   

    看来CSDN的专家不少!!可惜,真正做项目的感觉不是很多。大家都知道连接池的原理,认为Tomcat是万能的可以管理一切。
       
    但是,我不知道大家是否跟踪过,对数据库操作真正耗时间的什么地方?
    在JBuilderX中,对下列语句进行单步跟踪:
     
         DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/fxhy");
          if (ds == null) {
            throw new Exception("没有匹配数据库");
          }      conn = ds.getConnection();
      发现conn = ds.getConnection();出现非常明显的停顿,大概2秒钟!!!  如果大家都认为可以在每个页面另外从连接池中获取连接,那么我没有什么话说,也许大家的机器都是我机器速度的N倍!!!   另外:所有的操作,即使是速度很快连接池操作,采用页面间page/session/Application等的对象保留都是可以选择的,具体才有何种Scope都要经过分析。我采用跟踪发现,finalize其实是执行的,对连接的Close已经执行了。不过,如果我在调试过程中,点击调试的中断,Finalize就不会执行,因此会保留这些垃圾连接。同时我的整个网站中,对数据库的连接大概有几十次,每个页面都要有同时多次连接,而一个用户的页面操作都要剩余两个会话,采用Oracle的立即中断会话都关闭不了!  我期待专家能帮帮我!谢谢。
      

  9.   

    我还是觉得楼主的思路有问题!
    1、ds.getConnection()方法确实耗时间,所以才用连接池保存一定数量的连接,这些连接在使用时几乎不用重新建立连接了,因为第一次使用时会执行getConnection()方法,使用后只是放回连接池并没有关闭连接,所以不用每次都重新getConnection()。
    2、如果使用Session来保存连接对象的话,首先无法预知何时才能被垃圾回收器发现并回收,白白浪费资源;其次需要将连接对象在服务器和客户端传来传去;再次不利于层次清楚的设计。
    3、长期占用并不使用连接,使数据库连接数量增加,因为其它用户使用时必须重新建立连接,从长效上看,用Session方法来保存连接其实执行getConnection()方法的次数要远远多于使用连接池的方法。不知说的是否正确,希望大家讨论!
      

  10.   

    to  hq1305018(跃强):
       非常感谢您的回复!
     
       我想请教一下,我的连接池应该怎么写?可能Session会存在很多问题。你们都说不能用Session。好,我改了。   今天我用了一上午时间,我把所有的连接Bean都改成了Page,并且在每个页面数据库连接的最后,都加入了Close。   结果是:每一个对数据库的操作都要等到好几秒钟,有的甚至几十秒。   所谓的连接池的优越性根本就没有体现出来,我想知道,ds.getConnection()这一句只要你调用它,就会很耗费时间,请问大家是如何处理的?   我的连接池代码配置都在上面,请专家们看看为什么我的速度这么慢?而当我改回到Session方式后,速度飞快?
      

  11.   

    我想这个问题大家要换个角度考虑,首先,session是针对具体客户的,把数据库连接保存在session中对单个特定的客户来说速度当然很快,因为对他而言只需要建立一次连接,但是这样长期保持连接,对服务器来说压力很大,很简单,当客户量很大的时候由于连接池中的连接被每个客户占用没有释放,所以服务器要建立很多连接,速度会很慢,达到一定程度,所有客户的数据库连接都会很慢。我想很多人只是单重从学习和技术的角度考虑这个问题,而真正做项目的可能不多,但是所有的技术最终都要转化为生产力,要不然就没有什么意义了。连接池就是有这种商业性和他的实用性,否则就不会诞生。总的来说,连接池很有他的使用价值,这是一个商业价值很高的技术,在真正的项目运用中使用session保持数据库连接是不现实的,只能在特定的情况下适当的使用。
    请多多指教!
      

  12.   

    Tomcat:5.0.19 有连接池的bug;请用5.0.25版
      

  13.   

    非常感谢stone_q(qq)的回复。
    但是,我现在的问题是,如果不采用Session ,我的速度是不能被客户允许的。我在寻找折中的办法。to  fanciex(法西施<--) :
      我改成了5.0.26还是不行。你敢肯定5.0.25没问题么?如果确定可以,我就重新安装。