为了账号安全,请及时绑定邮箱和手机立即绑定

用Java创建内存泄漏

用Java创建内存泄漏

慕哥9229398 2019-06-06 13:20:41
用Java创建内存泄漏我刚刚进行了一次面试,我被要求创建一个内存泄漏用爪哇。不用说,我觉得自己很笨,根本不知道怎么开始创作。举个例子怎么样?
查看完整描述

3 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

下面是在纯Java中创建真正内存泄漏(运行代码无法访问但仍存储在内存中的对象)的好方法:

  1. 应用程序创建一个长时间运行的线程(或者使用线程池更快地泄漏)。
  2. 线程通过一个(可选的自定义)ClassLoader加载一个类。
  3. 类分配大量内存(例如:

    new byte[1000000]

    ),在静态字段中存储对它的强引用,然后将对自身的引用存储在ThreadLocal中。分配额外的内存是可选的(泄漏Class实例就足够了),但是它会使泄漏的速度更快。
  4. 线程清除对自定义类或从其加载的ClassLoader的所有引用。
  5. 重复一遍。

这是因为ThreadLocal保存了对象的引用,对象保留了对其类的引用,而该类又保留了对ClassLoader的引用。而ClassLoader则保留对其加载的所有类的引用。

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

这种模式的一个变化是,为什么应用程序容器(如Tomcat)会像筛子一样泄漏内存,如果您经常重新部署碰巧以任何方式使用ThreadLocals的应用程序。(由于应用程序容器使用所描述的线程,而且每次重新部署应用程序时,都会使用新的ClassLoader。)

更新因为很多人一直在要求它,下面是一些示例代码,它显示了这种行为的作用.


查看完整回答
反对 回复 2019-06-06
?
守着一只汪

TA贡献1872条经验 获得超3个赞

要做的一件简单的事情是使用带有不正确(或不存在)的HashSet。hashCode()equals(),然后继续添加“重复”。而不是忽略重复的应该,集将永远只会增长,你将无法删除他们。

如果您希望这些坏的键/元素在周围徘徊,您可以使用一个静态字段,如

class BadKey {
   // no hashCode or equals();
   public final String key;
   public BadKey(String key) { this.key = key; }}Map map = System.getProperties();map.put(new BadKey("key"), "value");
    // Memory leak even if your threads die.


查看完整回答
反对 回复 2019-06-06
  • 3 回答
  • 0 关注
  • 493 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信