发布日期:2018-03-26
如何在Java中故意制造一个内存泄漏+ 查看更多
如何在Java中故意制造一个内存泄漏
+ 查看更多
发布日期:2018-03-10 14:25
分类:JAVA
浏览次数:118
我刚刚有一个面试,我被要求使用Java创建一个内存泄漏。不用说,没有如何开始创建一个内存泄漏的线索我觉得相当的蠢。一个内存泄漏的例子应该是什么样的?
最佳答案
这里有一个很好的方法在Java中创建一个内存泄漏(通过运行的代码对象是无法访问但是仍然存储在内存中)。
- 应用程序创建一个长时间运行的线程(或者使用一个线程池来更快的泄漏)
- 线程通过一个(可选择定制的)ClassLoader加载类。
- 该类分配大块内存(例如:new byte1000000),在静态字段中存储一个对这个类的强引用,然后在一个ThreadLocal中存储一个对它自身的引用。分配额外的内存是可选的(泄漏Class实例是足够的),但是这样将会是内存泄漏工作更快。
- 该线程清除所有对这个自定义类或者这个加载这个类的ClassLoader的引用。
- 重复以上操作
这个方法奏效因为这个ThreadLocal保存对这个对象的一个引用,从而保存对它的类的一个引用,继而保存了对它的ClassLoader的一个引用。ClassLoader保存对它所加载的所有类的一个引用。因为在很多JVM实现中类和ClassLoader被直接分配到permgen中,从来没有GC'd。
这个模式的一个变化是当你频繁重新部署应用程序,以任何方式使用ThreadLocals时,应用程序容器(像Tomcat)能像筛子一样泄漏内存的原因。(因为应用程序容器使用所描述的线程,并且每次当你重新部署这个应用程序,一个新的ClassLoader被使用。)
其实还有很多方式可以使java出现内存泄漏。原理基本上都是使用一个生命周期超长的容器(例如一个static的Map),然后让一些对象被这些不死的容器引用,然后。。。你懂的。所以,没有两把刷子,不要学人家用static的容器哦。