2021-05-06

如何在Java中创建内存泄漏?

我刚刚接受采访,并被要求使用Java造成内存泄漏

不用说,我对如何开始创建它一无所知。

一个例子是什么?

解决方案:

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

  1. 该应用程序创建一个长时间运行的线程(或使用线程池更快地泄漏)。
  2. 线程通过(可选,自定义)加载类ClassLoader
  3. 该类分配大量的内存(例如new byte[1000000]),在静态字段中存储对它的强引用,然后在中存储对自身的引用ThreadLocal。分配额外的内存是可选的(泄漏类实例就足够了),但这将使泄漏工作快得多。
  4. 该应用程序清除对自定义类或ClassLoader从中加载的所有引用。
  5. 重复。

由于该方法ThreadLocal是在Oracle的JDK中实现的,因此会造成内存泄漏:

  • 每个Thread都有一个私有字段threadLocals,该字段实际存储线程局部值。
  • 该映射中的每个都是对ThreadLocal对象的弱引用,因此在对该ThreadLocal对象进行垃圾回收之后,其条目将从映射中删除。
  • 但是每个都是一个强引用,因此,当一个值(直接或间接)指向ThreadLocal作为其键的对象时,只要线程存在,该对象就不会被垃圾回收或从映射中删除。

在此示例中,强引用链如下所示:

Thread对象→threadLocals地图→示例类的实例→示例类→静态ThreadLocal字段→ThreadLocal对象。

ClassLoader在创建泄漏中并没有真正起作用,它只是由于以下附加引用链而使泄漏更糟:示例类→→ClassLoader它已加载的所有类。在许多JVM实现中,甚至在更糟糕的情况下,情况甚至更糟。 Java 7,因为类和ClassLoaders是直接分配到permgen中的,并且根本不会被垃圾回收。)

这种模式的一种变化是,如果您频繁地重新部署碰巧使用ThreadLocals的应用程序,而应用程序容器(例如Tomcat)像sieve那样以某种方式指向自身,那么它可以像筛子一样泄漏内存。发生这种情况的原因可能有很多微妙,而且通常很难调试和/或修复。

更新:由于很多人一直在要求它,所以这里有一些示例代码显示了这种行为。

本文首发于java黑洞网,博客园同步更新

 









原文转载:http://www.shaoqun.com/a/724757.html

跨境电商:https://www.ikjzd.com/

卖家精灵:https://www.ikjzd.com/w/532

好卖家:https://www.ikjzd.com/w/776


我刚刚接受采访,并被要求使用Java造成内存泄漏。不用说,我对如何开始创建它一无所知。一个例子是什么?解决方案:这是在纯Java中创建真正的内存泄漏(运行代码无法访问但仍存储在内存中的对象)的好方法:该应用程序创建一个长时间运行的线程(或使用线程池更快地泄漏)。线程通过(可选,自定义)加载类ClassLoader。该类分配大量的内存(例如newbyte[1000000]),在静态字段中存储对它的强
dojo:https://www.ikjzd.com/w/2052
浩方:https://www.ikjzd.com/w/1046
跨境通:https://www.ikjzd.com/w/1329
一艘滚装船上的集装箱发生大火!27人弃船撤离:https://www.ikjzd.com/home/18687
Prime Day给旺季带来的一点思考:谁赢了?:https://www.ikjzd.com/home/132073
罪魁祸首竟然是它!亚马逊关联导致大面积封杀账号的原因… :https://www.ikjzd.com/home/123919

No comments:

Post a Comment