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

现在检索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里面,没执行到代码就爆了)
虽然我知道是代码里面有内存泄漏,但是找不到,不会找。
希望高手指点一下

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。

鉴于以上原因,认为可能和session缓存有关。
于是把缓存设为ignore,而且执行完sql文后,立刻关闭session
发现居然会报错。
debug进去,发现service方法执行完之后回到action之前,跑到spring框架生成的$Proxy4.actionName里去了,无法debug进去。
貌似是TransactionProxyFactoryBean这个东西在管理transaction。
好像配置文件里把service和它关联上了。
继续查找如何跳过它,来找到问题根源

好恐怖的内存泄露啊,简直是内存杀手

我也用和你类似的框架,和struts,ajax没关系
估计是你hibernate二级缓存设置,链接设置,spring的事务设置有问题

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

谢谢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都不懂怎么写,极大的增加了开发难度,延长了开发时间。把所有的缺点都用上了,优点几乎没发挥出来。

没有用hibernate的二级缓存。
事务管理是spring的那个transactionManager来管理的。
链接是啥不太清楚。