我刚刚接受了一次采访,被要求用Java创建内存泄漏。
不用说,我觉得自己很傻,不知道如何开始创作。
什么样的例子?
我刚刚接受了一次采访,被要求用Java创建内存泄漏。
不用说,我觉得自己很傻,不知道如何开始创作。
什么样的例子?
当前回答
面试官可能一直在寻找一个循环参考解决方案:
public static void main(String[] args) {
while (true) {
Element first = new Element();
first.next = new Element();
first.next.next = first;
}
}
这是引用计数垃圾收集器的典型问题。然后,您可以礼貌地解释JVM使用了一种更复杂的算法,它没有这种限制。
其他回答
这里有一个非常简单的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));
}
}
}
理论上你不能。Java内存模型阻止了这一点。但是,因为必须实现Java,所以可以使用一些警告。这取决于您可以使用什么:
如果可以使用本机,则可以分配以后不会放弃的内存。如果这是不可用的,那么Java有一个不为人知的小秘密。您可以请求一个不由GC管理的直接访问数组,因此可以很容易地用于造成内存泄漏。这由DirectByteBuffer提供(http://download.oracle.com/javase/1.5.0/docs/api/java/nio/ByteBuffer.html#allocateDirect(int))。如果不能使用其中任何一个,仍然可以通过欺骗GC来造成内存泄漏。JVM是使用一代垃圾收集来实现的。这意味着垃圾堆被划分为三个区域:年轻人、成年人和老年人。对象创建时从年轻区域开始。随着它被越来越多地使用,它逐渐发展到成人到老年人。最有可能到达接骨木区域的对象不会被垃圾收集。您无法确定对象是否泄漏,如果您请求停止并清理GC,它可能会清理它,但在很长一段时间内,它会泄漏。更多信息请访问(http://java.sun.com/docs/hotspot/gc1.4.2/faq.html)此外,类对象不需要是GC’ed。也许有办法做到这一点。
您可以使用sun.misc.Unsafe类进行内存泄漏。事实上,这个服务类用于不同的标准类(例如java.nio类)。不能直接创建此类的实例,但可以使用反射来获取实例。
代码不会在EclipseIDE中编译-使用javac命令编译代码(编译期间,您会收到警告)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class TestUnsafe {
public static void main(String[] args) throws Exception{
Class unsafeClass = Class.forName("sun.misc.Unsafe");
Field f = unsafeClass.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
System.out.print("4..3..2..1...");
try
{
for(;;)
unsafe.allocateMemory(1024*1024);
} catch(Error e) {
System.out.println("Boom :)");
e.printStackTrace();
}
}
}
可能是潜在内存泄漏以及如何避免它的最简单示例之一,是ArrayList.remove(int)的实现:
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index,
numMoved);
elementData[--size] = null; // (!) Let gc do its work
return oldValue;
}
如果您是自己实现的,您是否想过清除不再使用的数组元素(elementData[-size]=null)?该引用可能会使一个巨大的对象保持活力。。。
任何时候,只要您保留对不再需要的对象的引用,就会出现内存泄漏。请参阅处理Java程序中的内存泄漏,以了解内存泄漏如何在Java中表现出来以及您可以如何处理它。