面试可能遇到的问题:用 Java 写一个内存泄漏程序

问题:

刚参加的一个面试,要我用Java写一个内存泄露程序。

这题完全没有思路,

有好心人能给出一个例子吗?

回答:

造成内存泄漏,就是让运行的程序无法访问存储在内存中的对象,下面是Java实现:

创建一个长时间运行的线程(使用线程池泄露的速度更快)。

线程通过ClassLoader加载某个类(也可以用自定义ClassLoader)。

这个类分配了大量内存(例如new byte[1000000]),赋给静态字段存储对它的强引用,然后在ThreadLocal中存储对自身的引用。还可以分配额外的内存,这样泄漏的速度更快(其实只要泄漏Class实例就足够了)。

这个线程会清除所有自定义类及加载它的ClassLoader的引用。

重复执行。

这个方法之所以奏效,是因为ThreadLocal保留了对该对象的引用,对象引用保留了对Class的引用,而Class引用又保留了对ClassLoader的引用。反过来,ClassLoader会保留通过它加载的所有类的引用。

(在许多JVM实现中情况更糟,尤其Java 7之前版本。因为Class和ClassLoader会直接分配到permgen中,GC不进行回收)。但是,无论JVM如何处理类卸载,ThreadLocal仍然会阻止被回收的Class对象)。

这种方案还可以变化为,频繁地重新部署碰巧用到ThreadLocal的应用程序。这时像Tomcat这样的应用程序容器会像筛子一样泄漏内存。(因为应用程序容器会像上面那样启动线程,并且每次重新部署应用程序时,都会使用新的ClassLoader)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值