tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM

标签     
作者:luolaluola 发表时间:2007年03月18日 16:28 回复此消息回复
原贴网址: http://www.jdon.com/jivejdon/thread/31174.html

为什么用jprofilter监视器得到的堆使用情况呈现一定的频率,堆示图显示规则锯齿状。一开始任务管理器显示所有进程内存500多m,过了一会儿任务管理器显示的内存使用数一直在增加,而任务管理器显示tomcat的内存保持在380m,但是系统所有进程内存已经1000多m,5~6个小时后之后系统提示虚拟内存不足,tomcat档掉!

服务器硬件环境:内存:512m,cpu P42.8双核
os:window server2003, database:sqlserver2000 (sp4)
tomcat5.5(-Xms128m -Xmx392m)

服务器监视器:JPROFILTER

客户端测试工具:jemter2.2 开一个线程组 里面有个80个线程,每隔4秒启动80个线程,也就是每个线程之间的间隔是4/80,http请求数10个



这个主题共有 28 回复 / 21 2
re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月18日 16:33 回复
luolaluola 发表文章: 20/ 注册时间: 2005年04月20日 14:20
补充一下,在系统还有显示虚拟内存之前,一直很稳定~~~ 速度很快,我通过jmeter查看到 平均值:2300-3050之间,偏离:1700左右
[该贴被bingochen于2007年03月18日 16:49修改过]
[该贴被bingochen于2007年03月18日 16:51修改过]

回复:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 10:26 回复
banq 发表文章: 10027/ 注册时间: 2002年08月03日 17:08
>5~6个小时后之后系统提示虚拟内存不足,tomcat档掉!
这表示你的应用程序存在内存泄漏,就是JVM垃圾回收机制无法回收你的对象了,需要全面check你的程序,可以通过JPROFILTER定位哪个类占用内存最多,问题就可能出在那里。

相关理论讨论:
jsp+javabean能否满足同时100人使用?
http://www.jdon.com/article/30437.html

回复:回复:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 11:13 回复
aa123456789 发表文章: 1/ 注册时间: 2007年03月19日 11:12
测试
[该贴被aa123456789于2007年03月19日 11:14修改过]

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 12:05 回复
Coolyu0916 发表文章: 195/ 注册时间: 2007年04月23日 11:29
可以参考一下gc的收取规则
通常来说约晚分配的内存越早回收,也就是尽量减少引用的次数,引用了之后就没不能立即回收了。

回复:re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 13:25 回复
luolaluola 发表文章: 20/ 注册时间: 2005年04月20日 14:20
哦,可能是这个原因,我的测试代码思路是这样的,

从连接池中取得连接,通过调用存储过程,查询返回ResultSet 然后通过ResultSetMetaData.getColumnCount()取得Column的长度,通过长度建立String[],一个数据行是一个String[],循环读取ResultSet,把数据行写入String[],然后把String[]写入Arraylist<String[]>,最后释放Conn,Statement,ResultSet 然后返回ArrayList,把返回的rrayList值提交给一个xml生成类,生成xml类,把ArrauList clear()掉,然后输出xml, 当并发量大的话,循环建立 new String[] 可能会耗资源

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 14:08 回复
luolaluola 发表文章: 20/ 注册时间: 2005年04月20日 14:20
依照上面的方式,我发现往ArrayList里面加String[]对象,当ArrayList做clear() 和 付NULL操作时,String[]对象并没有被释放,不知道是不是这个原因引起的

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 20:49 回复
Coolyu0916 发表文章: 195/ 注册时间: 2007年04月23日 11:29
不明白为什么要先写入ArrayList然后再变成xmldoc那??
不能从Result直接变么??

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 21:22 回复
luolaluola 发表文章: 20/ 注册时间: 2005年04月20日 14:20
按照banq的意思 用了jprofilter进行跟踪 发现一个对象占用太多内存,而且实例数超多,一直增加 一次增加几百个实例

com.microsoft.jdbc.vprt.SSLexTableRowEntry 这个类 不知道什么原因,谁能提供些资料

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 21:31 回复
Coolyu0916 发表文章: 195/ 注册时间: 2007年04月23日 11:29
最后释放Conn,Statement,ResultSet ??
是不是顺序反了??

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月19日 21:39 回复
luolaluola 发表文章: 20/ 注册时间: 2005年04月20日 14:20
先释放resultset 然后释放CallableStatement,最后释放connection

回复:re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月21日 09:03 回复
banq 发表文章: 10027/ 注册时间: 2002年08月03日 17:08
前面的ArrayList确认是否释放了,是否执行clear了,需要通过记录跟踪,还要确定clear的ArrayList是否就是塞入String[]的ArrayList

关于>SSLexTableRowEntry
很可能是连接没有释放,打开数据库连接和关闭连接必须在一个方法中完成,这样才安全,不能跨方法,关闭连接是否是在finally语句中.

是否使用数据库连接池?怎样使用的?是使用容器服务器自己的连接池,还是第三方,如果是第三方,是否经过成熟应用.

是否JDBC事务设置不正确,JDBC有四个事务隔离级别,READ_UNCOM READ_COM等,Oracle缺省的是READ_COM,所以Oracle很少有数据库连接死锁现象,SQL-server缺省不是很清楚,估计和sysbase一样是第三个事务隔离,虽然安全,但是会发生死锁,甚至内存泄漏.

确认以上问题,特别是最后一个问题,比较烦琐,需要花时间学习或接受培训一下.

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月21日 11:30 回复
luolaluola 发表文章: 20/ 注册时间: 2005年04月20日 14:20
感谢BNAQ的关注 ^_^

我现在找到问题的根源了,问题根源在于连接池设置,业务过程不存在内存泄漏。原先采用proxool连接池 最大连接数1000个最小连接数200个 其他的选项都是默认的设置,ResultSet CallableStatement,Connnect 都有及时释放(Connnect只是放回连接池) 但是这种情况显示,当并发量大的话 GC内存回收 速度极慢 com.microsoft.jdbc.vprt.SSLexTableRowEntry 这个实例数都达到几百万上千万,而且释放速度比增加速度少几十甚至上百倍,而jvm的内存设置是(-Xms128m -Xmx392m),远远不够的,当内存严重不足的情况下,GC开始进行回收有几次完整的回收但是 一些旧的对象根本就无法回收,最后崩溃。

在后来的测试中配置:最大连接数100,最小连接数10 个 jmeter 5个线程,1秒钟并发一次,根据jropfilter的显示不管是 gc时间还是堆视图 可以看到 整个回收非常完整彻底....


是否使用数据库连接池?怎样使用的?是使用容器服务器自己的连接池,还是第三方,如果是第三方,是否经过成熟应用.


-----------------------------------------------------------------
Banq:是否JDBC事务设置不正确,JDBC有四个事务隔离级别,READ_UNCOM READ_COM等,Oracle缺省的是READ_COM,所以Oracle很少有数据库连接死锁现象,SQL-server缺省不是很清楚,估计和sysbase一样是第三个事务隔离,虽然安全,但是会发生死锁,甚至内存泄漏.

请问banq老师 哪里可以得到你提到的JDBC事务这方面的资料,还有有没有那种最佳内存方案的资料 谢谢


回复:re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月22日 08:44 回复
banq 发表文章: 10027/ 注册时间: 2002年08月03日 17:08
>在找到问题的根源了,问题根源在于连接池设置,业务过程不存在内存泄漏

我觉得这可能不是真正原因, 因为如果并发量一大,我们的服务器就崩溃,这显然不能算一个成熟的系统.

正常情况是:当并发量大时,如果我们控制资源,这样就是jmeter发出10个并发线程请求,但是我们的系统只并发处理5个并发线程请求,其他请求必须等待,最后良好结果应该是:无论多大并发量,服务器正常运行,只有jmeter一些线程请求响应时间很长.

虽然你将连接池设置改动了,这也是控制资源的一部分,但是效果不大,因为这是后端,多余并发请求已经从前端(jsp/servlet)进入到了你的服务器中了,而且已经启动了最耗内存的业务Bean,尽管你在通往数据库的路上进行了限制,这只会让问题更遭.

另外, 你的测试条件"jmeter 5个线程,1秒钟并发一次"测试条件太松,JdonFramework测试是8个线程,0秒钟一次,也就是8个线程同时发出,这才能模拟同时同用户操作的环境.

"JDBC事务这方面的资料"一般都在数据库的JDBC章节有说明,"最佳内存方案"我认为就是不要以数据库为中心设计,将分散的数据使用业务对象封装起来,使用cache和Pool,提高内存击中率,减少数据库连接池的使用,使用Pool或单态控制并发高峰对服务器的伤害.这些原理在我设计的JdonFramework时都考虑到,封装在框架中,不让每个应用都为这个问题专门考虑设计.


[该贴被banq于2007年03月22日 09:00修改过]
[该贴被banq于2007年03月22日 09:01修改过]
[该贴被banq于2007年03月22日 09:04修改过]

re:tomcat的运行的时候,GC进行内存回收,回收后的内存是还给OS还是还给JVM 发表: 2007年03月22日 10:49 回复
luolaluola 发表文章: 20/ 注册时间: 2005年04月20日 14:20
谢谢BANQ,嗯,重点还是你说的将分散的数据使用业务对象封装起来,使用cache和Pool,提高内存击中率。提高并控制内存击中率 这个实现起来就复杂了,如果要这么做,是不是要cache业务对象,做一个pool对象池,根据业务需要,调节pool中业务对象的个数以便于控制内存使用命中率和系统负荷,不过写这些东西估计做起来很复杂

我去看看JDONFRAME的实现先

标签     
共有 28 回复 / 21 2
 
上一篇: 求助 liferay操作数据库 下一篇: 面向对象设计与DROOLS
 
查询本论坛 最热门帖子

标签总列表


Jdon框架演示

JiveJdon3.0
源码下载

GoF设计模式

在线教程

社区精彩讨论




收藏本主题到 google yahoo 365Key网摘 CSDN网摘 添加到百度搜藏 POCO网摘 新浪ViVi QQ网摘



手机阅读 add to google add to yahoo
联系我们 | 关于我们 | RSS订阅 | 广告联系 | 网站地图
Copyright (C) 2002-2009 Jdon.com, All Rights Reserved 版权所有 上海解道计算机技术有限公司
沪ICP备05018152号 如有意见请与我们联系 Powered by JdonFramework