预防classloader内存泄漏

作者:Ken Wu`s Blog 日期:2009/12/14 原文链接:http://kenwublog.com/prevent-classloader-memory-leak 最近在开发一个插件动态部署功能,由于在单元测试里批量进行了redeploy,竟然到最后出现了OOM, faint。 看来有必要回顾一下classloader memory leak。 Classloader的内存泄漏。早在JDK1.5以前,就频繁出现于tomcat, jboss的redeploy动作后。 限于当时没有一款像样的内存泄漏分析工具问世。导致,很多用户都不敢轻易使用hotdeploy功能。 随着JDK6的发布,动态化,OSGi等概念也如火如荼地大规模应用于各大app server。使得classloader内存泄漏的问题,再次引起人们的注意。 所谓的classloader内存泄漏,举个简单例子说明一下。 假设有A和B两个classloader,分别加载 A 和 B两个类。 他们new出来的instance,取名叫 a 和 b。此时,如果你通过某种方式,将a的instance传递给b,b又不小心hold住a的实例时,就有可能发生memory leak。 仔细分析,主要是因为a实例hold class A , class A hold classloader A,b hold a,那么b也就跟classload A有了间接引用关系。 GC过程中,如果发现classloader a 从classloader b的引用关系可达(reached),那么classloader A是不会被回收。 这是一个classloader的小常识,多数人都能很好理解。但问题就在于实际应用过程中,classloader的复杂性,往往会让你神不知鬼不觉地跌入memory leak的陷阱。 比如OSGi,你可能会将一些公用的class或lib放到 Share Bundle, 这个bundle是你不希望会被undeploy或很少undeploy的。 不幸的是,随着系统功能逐渐的丰富起来,业务bundle A的某个实例可能稀里糊涂地被 Share bundle hold住了,此时,你又在毫不知情地情况下,尝试了多次redeploy,那memory leak跟你相见只是时间问题。 对于一般应用,我们不需要关注得太深入。但如果你的系统经常使用一些动态化功能,或许就该体检一下了。 一般推荐使用Eclipse MAT做内存分析,从root开始往下找你期望被unloaded的classloader,并祈祷它不要被找到。 推荐下面三篇文档: http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java http://blogs.sun.com/fkieviet/entry/how_to_fix_the_dreaded http://www.zeroturnaround.com/blog/rjc201/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值