如何在Java中创建内存泄漏?
2022-08-31 01:22:46
我刚刚接受了一次面试,我被要求使用Java创建内存泄漏。
毋庸置疑,我觉得自己很愚蠢,不知道如何开始创建一个。
举个例子吗?
我刚刚接受了一次面试,我被要求使用Java创建内存泄漏。
毋庸置疑,我觉得自己很愚蠢,不知道如何开始创建一个。
举个例子吗?
以下是在纯Java中创建真正的内存泄漏(通过运行代码无法访问但仍存储在内存中的对象)的好方法:
ClassLoader
new byte[1000000]
ThreadLocal
ClassLoader
由于在Oracle的JDK中实现的方式,这会产生内存泄漏:ThreadLocal
Thread
threadLocals
ThreadLocal
ThreadLocal
ThreadLocal
在此示例中,强引用链如下所示:
Thread
对象→映射→示例类→示例类→静态字段→对象的实例。threadLocals
ThreadLocal
ThreadLocal
(在创建泄漏方面并没有真正发挥作用,它只是由于这个额外的引用链而使泄漏变得更糟:示例类→ →它加载的所有类。在许多JVM实现中,情况更糟,特别是在Java 7之前,因为类和类被直接分配到permgen中,并且从未被垃圾回收。ClassLoader
ClassLoader
ClassLoader
这种模式的一个变体是为什么应用程序容器(如Tomcat)可以像筛子一样泄漏内存,如果你经常重新部署碰巧使用s的应用程序,以某种方式指向它们自己。这可能由于许多微妙的原因而发生,并且通常难以调试和/或修复。ThreadLocal
更新:由于很多人一直在要求它,这里有一些示例代码可以显示这种行为的实际效果。
保存对象引用的静态字段 [尤其是最终字段]
class MemorableClass {
static final ArrayList list = new ArrayList(100);
}
在冗长的字符串上调用 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 选项,例如 IBM JDK 上阻止未使用的类垃圾回收的选项noclassgc
请参阅 IBM JDK 设置。