锁定老帖子 主题:java线程死锁与内存溢出
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-01-08
使用ArrayList会内存溢出,被楼主雷到了。
使用Connection这个也被楼主雷到了。 开源框架倒在楼主的脚下。 |
|
返回顶楼 | |
发表时间:2009-01-08
有些连接池中取出来的连接,在使用完后也是需要close的
这个close不是真正的close,而是将连接还给连接池 一般的连接池都是延迟一段时间(一般会有几分钟至几十分钟不等)才自动回收 这样也会造成连接池认为自己没有可用连接了,从而死锁 |
|
返回顶楼 | |
发表时间:2009-01-08
public static DDConnectionBroker broker = null;
静态的,真不能随便用;尤其静态变量; |
|
返回顶楼 | |
发表时间:2009-01-09
最后修改:2009-01-09
看了楼主的代码,感觉以楼主的水平,自己做个这个还是很冒险的。
看的有些晕,为什么要把Connection和Statement作为成员变量呢??Connection和Statement是那个broker来管理的吧? 你这样把它们做成成员变量,这个Data就是“有状态的”了,在多线程的情况下容易出问题。 我还是没明白为什么同时获取连接时会死锁,再看看。 这个: # try{ # # Conn = broker.getConnection(); # stmt=Conn.createStatement(); # }catch(Exception ex){ # ex.printStackTrace(); # //cf.close(); # } 如果stmt=Conn.createStatement(); 这一句抛出异常了,那上面的Conn是不是就没人管了?出异常后不释放掉么? 还有你的那个加sychronized的办法,你确定是什么原因造成的么? 在getConnection和connClose前面加上sychronized关键字,只会对同一个Data实例加上锁,对于多个Data实例没效果。不过看前面你说的Data是个单例的,那就不存在多个实例的情况了——但没见过单例这么写的,别人再用这个代码时,通过读你的代码,是怎么也想不到这个Data要求是单例的。 Data只有一个实例,那相应的Conn也一直只有一份儿(至少是你能持有的只有一个)——这是我们用连接池的目的么??那把Conn也声明成static好了,反正全局只用一个。 把下面这个留言好好看看吧! 引用 repsihWDX
我指的是你的Data类是不是单例。 如果是单例,那么虽然您的broker是不会重复的,但您每次都从新从broker里面拿连接,但又没传到外面用,赋予了您在单例的data中的那个Connection引用。 那么,如果原来Connection那个引用已经持有了一个连接实例,它在哪儿被关闭呢? 另外, # se.printStackTrace(); # System.out.println( se.getMessage() ); # System.out.println( "Could not construct a broker, quitting." ); 我现在再见到这种写法,属实感觉别扭。我们都用log来输出了。还什么printStackTrace(),System.out呢…… |
|
返回顶楼 | |
发表时间:2009-01-09
System.out会占用大量IO,对性能是隐患.
lz自己写连接池,用来学习练手是好的,真正项目中绝对不要用,否则会死的很难看 就lz贴的代码问题太多,把dbcp的代码看看对照一下就知道了,连接池不是这么简单的. |
|
返回顶楼 | |
发表时间:2009-01-11
看一下common pool的源代码,肯定有所帮助。
|
|
返回顶楼 | |
发表时间:2009-01-12
LZ,你太牛逼了
|
|
返回顶楼 | |
发表时间:2009-01-12
你这个叫连接池?
你这个情况叫死锁? 其实根本就是线程不安全,导致很多连接没有正常关掉(连接的引用也丢失了,所以永远关不掉),接着再开连接就全部只能等待了。 死锁是不同同步块嵌套了才有可能产生的。你原来的代码一个同步都没有怎么可能死锁... |
|
返回顶楼 | |
发表时间:2009-01-13
谁最开始就写高质量的代码?
楼主,你的代码质量的确很成问题,大家都喷了,我就不喷了。。。。。 现在有两个修改办法: 1.这个比较累,建议你使用DBCP或者C3P0配合Hibernate或者IBatis重写你的程序。 2.将你connetion从成员变量中干掉,并使用synchronized同步你的方法和变量。。。这个是丑陋中的稍微不丑陋的一点方法。 算了,你还是按方法1来吧。。。。 |
|
返回顶楼 | |
发表时间:2009-01-13
repsihWDX 写道 # try{
# # Conn = broker.getConnection(); # stmt=Conn.createStatement(); # }catch(Exception ex){ # ex.printStackTrace(); # //cf.close(); # } 1.无finally,不关连接。try中的东西出异常你的这个connection费了。 2.如果这个类是单例的,你每次都是在从你的broker中拿连接,但原来你这个单例中如果持有另外的connection,则那个connection在没有关闭的情况下成了无主废人。 3.如果不是单例的,那么broker就被创建多次,我不知道你这个broker是个什么,但如果是连接池,那么每个新的实例会占用你initConnection中设置的数量的连接。 不错,还有在异常处理中,最好也调用你得connClose(); |
|
返回顶楼 | |