请教 关于内存泄漏的检测方法

07-04-10 jstxqgb
现在检索200条左右数据就会在下次检索时outofmemory。

直接在opensessioninviewfilter那里挂掉了,跟不进代码阿。

最奇怪的就是为什么在第一次select 200条数据时,只占用了20M左右。

直到下一次检索2,3条数据时,一下子暴到200M呢?

[GC 24760K->22810K(29880K), 0.0023559 secs]

Hibernate: select ...

(这里检索200条数据,检索完了。回收时一共才20M)

[GC 24794K->22929K(29880K), 0.0022210 secs]

session MainMenuInfo : common.util.MainMenuInfo@e6df19

session UserInfo : common.util.LoginUserInfo@14e8936

session K0200MenuForm : K02.form.K0200MenuForm@61b29f

session K02_TEMP_K0201001OrgSelectForm : K02.form.K0201001OrgSelectForm@1a626ac

session org.apache.struts.action.LOCALE : ja

class org.apache.catalina.core.ApplicationFilterChain

[GC 24790K->23612K(29880K), 0.0057686 secs]

[GC 25435K->25408K(29880K), 0.0071911 secs]

[GC 27230K->27203K(29880K), 0.0062332 secs]

[GC 29027K->28998K(31180K), 0.0061798 secs]

[Full GC[Unloading class sun.reflect.GeneratedMethodAccessor123]

[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor2]

[Unloading class sun.reflect.GeneratedMethodAccessor154]

[Unloading class sun.reflect.GeneratedMethodAccessor155]

[Unloading class sun.reflect.GeneratedMethodAccessor150]

[Unloading class sun.reflect.GeneratedMethodAccessor147]

[Unloading class sun.reflect.GeneratedMethodAccessor146]

[Unloading class sun.reflect.GeneratedMethodAccessor148]

[Unloading class sun.reflect.GeneratedMethodAccessor152]

[Unloading class sun.reflect.GeneratedMethodAccessor89]

[Unloading class sun.reflect.GeneratedMethodAccessor110]

[Unloading class sun.reflect.GeneratedMethodAccessor86]

[Unloading class sun.reflect.GeneratedMethodAccessor151]

[Unloading class sun.reflect.GeneratedConstructorAccessor38]

[Unloading class sun.reflect.GeneratedMethodAccessor153]

[Unloading class sun.reflect.GeneratedMethodAccessor88]

28998K->24461K(31180K), 0.3669290 secs]

[GC 27069K->27026K(43908K), 0.0046235 secs]

[GC 29629K->29591K(43908K), 0.0042978 secs]

[GC 32195K->32155K(43908K), 0.0049096 secs]

[GC 34759K->34720K(43908K), 0.0050124 secs]

[GC 37324K->37285K(43908K), 0.0050249 secs]

[GC 39889K->39849K(43908K), 0.0051174 secs]

[GC 42453K->42414K(45468K), 0.0050942 secs]

[Full GC 42414K->40955K(45468K), 0.3308669 secs]

[GC 45381K->45315K(73444K), 0.0067525 secs]

[GC 49741K->49675K(73444K), 0.0080516 secs]

[GC 54101K->54035K(73444K), 0.0078046 secs]

[GC 58461K->58395K(73444K), 0.0077898 secs]

[GC 62820K->62755K(73444K), 0.0079532 secs]

[GC 67182K->67114K(73444K), 0.0078652 secs]

[GC 71541K->71475K(76304K), 0.0085567 secs]

[Full GC[Unloading class sun.reflect.GeneratedMethodAccessor49]

71475K->71475K(76304K), 0.2570003 secs]

[GC 78764K->78656K(127228K), 0.0804133 secs]

[GC 86466K->86350K(127228K), 0.0164222 secs]

[GC 94161K->94043K(127228K), 0.0194583 secs]

[GC 101854K->101739K(127228K), 0.0153807 secs]

[GC 109548K->109432K(127228K), 0.0188826 secs]

[GC 117242K->117126K(127228K), 0.0209809 secs]

[GC 124937K->124819K(133208K), 0.0165180 secs]

[Full GC 124819K->124819K(133208K), 0.2503483 secs]

[GC 137837K->137645K(222296K), 0.0957457 secs]

[GC 151442K->151237K(222296K), 0.0276680 secs]

[GC 165034K->164829K(222296K), 0.0261955 secs]

[GC 178625K->178421K(222296K), 0.0403532 secs]

[GC 192222K->192017K(222296K), 0.0248087 secs]

[GC 205821K->205609K(222296K), 0.0247825 secs]

[GC 219412K->219201K(233216K), 0.0272929 secs]

[Full GC 219201K->219201K(233216K), 0.2625688 secs]

[GC 233783K->233562K(260160K), 0.1095519 secs]

(下一次检索2,3条数据时的垃圾回收)

Hibernate: select stf.staff_Id, stf.staff_Name...

(真正开始执行检索)

还有就是测试数据库一共才10M左右,为什么一两次检索就会弄出这么多内存呢?

开发阶段,不让研究这个问题-_-!

就让截了几张图证明问题在spring框架里(因为确实错误信息在spring的filter里面,没执行到代码就爆了)

虽然我知道是代码里面有内存泄漏,但是找不到,不会找。

希望高手指点一下

1
jstxqgb
2007-04-10 18:01
javax.servlet.ServletException: サーブレットの実行により例外を投げました

common.util.EncodingFilter.doFilter(EncodingFilter.java:25)

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)

org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:77)

原因

java.lang.OutOfMemoryError: Java heap space

上面是tomcat用默认jvm大小是出的错。

还有就是只是子画面时会溢出,主画面检索200条不会溢出。(代码几乎一样)

唯一区别就是子画面检索时,关联数据多“系”一层吧。(局,部,课,系相互关联)。

虽然系统比较失败,但是很想找到内存泄漏的地方。

系统是用spring+hibernate+struts的,而且下拉列表选择局,部,课,系的联动部分用了ajax。

jstxqgb
2007-04-20 17:35
鉴于以上原因,认为可能和session缓存有关。

于是把缓存设为ignore,而且执行完sql文后,立刻关闭session

发现居然会报错。

debug进去,发现service方法执行完之后回到action之前,跑到spring框架生成的$Proxy4.actionName里去了,无法debug进去。

貌似是TransactionProxyFactoryBean这个东西在管理transaction。

好像配置文件里把service和它关联上了。

继续查找如何跳过它,来找到问题根源

diamondsong
2007-04-20 21:44
好恐怖的内存泄露啊,简直是内存杀手

我也用和你类似的框架,和struts,ajax没关系

估计是你hibernate二级缓存设置,链接设置,spring的事务设置有问题

使用过的链接是否立即关闭了,释放了资源

jstxqgb
2007-04-23 09:53
谢谢diamondsong的指点,我去看看资料,该怎么设置hibernate缓存。

<filter>

<filter-name>openSessionInViewFilter</filter-name>

<filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

</filter-class>

<init-param>

<param-name>singleSession</param-name>

<param-value>false</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>openSessionInViewFilter</filter-name>

<url-pattern>*.do</url-pattern>

</filter-mapping>

目前在web.xml中是如上那么写的,好像session的管理用的spring的OpenSessionInViewFilter。

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource">

<ref local="dataSource" />

</property>

<property name="lobHandler" ref="lobHandler" />

<property name="mappingDirectoryLocations">

<list>

<value>classpath:./entity</value>

</list>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.format_sql">false</prop>

<prop key="hibernate.dialect">${kwdb.sqlDialect}</prop>

<prop key="hibernate.default_schema">

${kwdb.default_schema}

</prop>

</props>

</property>

</bean>

<!-- transaction manager -->

<bean id="transactionManager"

class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory">

<ref local="sessionFactory" />

</property>

</bean>

<bean id="LoginService"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager">

<ref local="transactionManager" />

</property>

<property name="target">

<ref local="LoginServiceTarget" />

</property>

<property name="transactionAttributes">

<props>

<prop key="insert*">

PROPAGATION_REQUIRED,-java.lang.Exception

</prop>

<prop key="update*">

PROPAGATION_REQUIRED,-java.lang.Exception

</prop>

<prop key="delete*">

PROPAGATION_REQUIRED,-java.lang.Exception

</prop>

<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

spring.context文件是如上的写法,好像service的transaction都被TransactionProxyFactoryBean管理了。

我刚接触这个项目,不知谁构架的系统。我之前没接触过struts,hibernate和spring,周围也没有人懂。

只好厚着脸皮上来问了,可能问的问题比较幼稚。

我完全抛开这个框架,直接用jdbc执行那部分代码,发现没有内存泄漏。

大概就像diamondsong说的那样,框架配置的不好了吧。

borland的optimizeit过期了,不敢用盗版的,怕被找上门。只好用-verbosegc看。。。

个人感觉如果用这些框架,没有很好的项目管理的话,项目会很失败的。因为大多数pg都不懂怎么写,极大的增加了开发难度,延长了开发时间。把所有的缺点都用上了,优点几乎没发挥出来。

jstxqgb
2007-04-23 10:42
没有用hibernate的二级缓存。

事务管理是spring的那个transactionManager来管理的。

链接是啥不太清楚。

banq
2007-05-08 10:28
相关帖子:

http://www.jdon.com/jivejdon/thread/31647.html

猜你喜欢