我刚刚接受了一次面试,我被要求用 Java创建内存泄漏。
不用说,我什至不知道如何开始创建一个
能举一个例子吗?
这是在纯 Java 中创建真正的内存泄漏(运行代码无法访问但仍存储在内存中的对象)的好方法:
ClassLoader
new byte[1000000]
ThreadLocal
由于ThreadLocal在 Oracle 的 JDK 中实现的方式,这会产生内存泄漏:
Thread
threadLocals
在此示例中,强引用链如下所示:
Thread对象→threadLocals映射→示例类的实例→示例类→静态ThreadLocal字段→ThreadLocal对象。
(ClassLoader在创建泄漏中并没有真正发挥作用,它只是因为这个额外的引用链而使泄漏变得更糟:示例类→→ClassLoader它已加载的所有类。在许多 JVM 实现中甚至更糟,尤其是在之前Java 7,因为 classes 和ClassLoaders 被直接分配到 permgen 并且根本没有被垃圾回收。)
这种模式的一个变体是,如果您经常重新部署恰好使用ThreadLocal以某种方式指向自身的 s 的应用程序,应用程序容器(如 Tomcat)可能会像筛子一样泄漏内存。这可能由于许多微妙的原因而发生,并且通常难以调试和/或修复。
包含对象引用的静态字段 [尤其是 最终 字段]
class MemorableClass { static final ArrayList list = new ArrayList(100); }
调用String.intern()一个冗长的字符串
String.intern()
String str = readString(); // read lengthy string any source db,textbox/jsp etc.. // This will place the string in memory pool from which you can't remove str.intern();
(未关闭)打开流(文件、网络等)
try { BufferedReader br = new BufferedReader(new FileReader(inputFile)); ... ... } catch (Exception e) { e.printStacktrace(); }
未关闭的连接
try { Connection conn = ConnectionFactory.getConnection(); ... ... } catch (Exception e) { e.printStacktrace(); }
JVM 垃圾收集器无法访问的区域,例如通过本机方法分配的内存。
在 Web 应用程序中,一些对象存储在应用程序范围内,直到应用程序被显式停止或删除。
getServletContext().setAttribute("SOME_MAP", map);
不正确或不适当的 JVM 选项,例如noclassgcIBM JDK 上阻止未使用的类垃圾收集的选项
noclassgc