当前位置: 首页 > 面试题库 >

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

贺功
2023-03-14
问题内容

我刚刚接受采访,并被要求使用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中的内存泄漏(例如使用JHat)?我试图在JHat中加载堆转储,以进行基本了解。但是,我不明白我应该如何找到根引用(ref)或任何被称为根引用的东西。基本上,我可以说哈希表条目有几百兆字节([java.util.HashMap $ Entry或类似的东西),但是地图到处都是……使用某种方法可以搜索大型地图,还是找到大对象树的一般根? [编辑]好的,到目前为止,我已经阅

  • 本文向大家介绍Java 内存泄漏,包括了Java 内存泄漏的使用技巧和注意事项,需要的朋友参考一下 在Java中,垃圾回收(析构函数的工作)是使用垃圾回收自动完成的。但是,如果代码中有引用它们的对象怎么办?它无法取消分配,即无法清除其内存。如果这种情况一再发生,并且创建或引用的对象根本没有被使用,它们就会变得无用。这就是所谓的内存泄漏。 如果超过了内存限制,则程序将通过抛出错误(即“ OutOfM

  • 我需要找到Flutter的内存泄漏。如何找到他们?以及如何为测试创建内存泄漏?

  • 我们有一个使用eclipse-jetty版本8.1.6的java webserver。最近我们开始注意到内存不足的错误。我们对活动线程数的分析很少。这似乎在100左右是合理的。该进程具有5GB最大堆内存和4GB初始堆内存。 webserver平均每分钟接收350个请求。此外,我们在ELB(kubernetes服务)后面运行许多这样的实例。跑了几个小时后,我们注意到了这个OOM。这个问题是随机的,它

  • 手动创建vue组件的方法: 手动销毁组件的方法 在组件销毁后,仍然能检测到大量的detached DOM,检测过没有全局的事件绑定,有哪位大佬遇到过类似的问题,望不吝赐教!

  • 问题内容: 我发现使用是众所周知的与相关的内存问题。 使用中是否存在内存泄漏? 如果是,解决方法是什么? 以下链接显示了Java中子字符串的正确用法。 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4513622 另外一个博客谈论子字符串中可能的MLK。 http://nflath.com/2009/07/the-dangers-of- st