我最近参加了一次面试,其中被要求使用Java创建一个内存泄漏。
不用说,我感到很笨,因为我不知道如何开始创建。
你可以给一个例子吗?
我最近参加了一次面试,其中被要求使用Java创建一个内存泄漏。
不用说,我感到很笨,因为我不知道如何开始创建。
你可以给一个例子吗?
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class Main {
public static void main(String args[]) {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
((Unsafe) f.get(null)).allocateMemory(2000000000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
我在javax.swing.JPopupMenu
中遇到了一个非常真实的内存泄漏问题。
我有一个GUI应用程序,显示多个选项卡文档。关闭文档后,如果在选项卡上的任何组件上使用了右键单击上下文菜单,则该文档会在内存中停留。菜单在选项卡之间共享,并且事实证明,在调用popupMenu.show(Component invoker, int x, int y)
之后,组件会静默地持续作为菜单的“invoker”,直到下一次更改或通过setInvoker(null)
清除。间接地,调用者引用会使整个文档及其关联的所有内容持久化。
值得注意的是,菜单只能以这种方式保存对旧组件的一个引用,因此此内存泄漏不会无限增长。
在JDK 1.7之前,内存泄漏的一个实时例子:
假设您读取了一个包含1000行文本的文件,并将它们保存在String对象中:
String fileText = 1000 characters from file
fileText = fileText.subString(900, fileText.length());
fileText
应该只引用100个字符,所有其他字符都应该被垃圾回收,因为我失去了对它们的引用,但在JDK 1.7之前,子字符串函数间接地引用了最后100个字符的原始字符串,并防止整个字符串被垃圾回收,直到你失去子字符串的引用,整个1000个字符将一直存在于内存中。这很简单:
Object[] o = new Object[]{};
while(true) {
o = new Object[]{o};
}
while(true) {
ResultSet rs = database.select(query);
...
// going to next step of loop and leaving resultset without calling rs.close();
}
您可以尝试使用一个while
循环,让许多缓冲读取器同时尝试打开同一个文件,并且条件永远不为假。最后的关键是这些读取器从未关闭。
就像这样!
public static void main(String[] args) {
List<Object> objects = new ArrayList<>();
while(true) {
objects.add(new Object());
}
}
这是一个非常简单的Java程序,它将会耗尽空间。
public class OutOfMemory {
public static void main(String[] arg) {
List<Long> mem = new LinkedList<Long>();
while (true) {
mem.add(new Long(Long.MAX_VALUE));
}
}
}