我刚刚接受了一次采访,被要求用Java创建内存泄漏。

不用说,我觉得自己很傻,不知道如何开始创作。

什么样的例子?


当前回答

这里有一个非常简单的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));
        }
    }
}

其他回答

也许通过JNI使用外部本机代码?

使用纯Java,这几乎是不可能的。

但这是一种“标准”类型的内存泄漏,即您无法再访问内存,但它仍然属于应用程序。相反,您可以保留对未使用对象的引用,或者打开流而不关闭它们。

正如许多人所建议的那样,资源泄漏很容易造成,就像JDBC示例一样。实际的内存泄漏有点困难——尤其是如果您不依赖JVM中的碎片来为您进行泄漏。。。

创建占地面积非常大的对象,然后无法访问这些对象的想法也不是真正的内存泄漏。如果没有东西可以访问它,那么它将被垃圾收集,如果有东西可以访问,那么它就不是泄漏。。。

然而,一种曾经有效的方法——我不知道它是否仍然有效——是有一条三深的环形链。正如在对象A中有对对象B的引用,对象B有对对象C的引用,而对象C有对对象A的引用。GC足够聪明,知道如果A和B不能被任何其他对象访问,但不能处理三方链,则可以安全地收集两个深链(如在A<-->B中)。。。


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();
        }
    }
}

在具有自己生命周期的类中随意使用非静态内部类。

在Java中,非静态内部类和匿名类对其外部类具有隐式引用。另一方面,静态内部类则不然。

下面是一个常见的Android内存泄漏示例,但这并不明显:

public class SampleActivity extends Activity {

  private final Handler mLeakyHandler = new Handler() { // Non-static inner class, holds the reference to the SampleActivity outer class
    @Override
    public void handleMessage(Message msg) {
      // ...
    }
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Post a message and delay its execution for a long time.
    mLeakyHandler.postDelayed(new Runnable() {//here, the anonymous inner class holds the reference to the SampleActivity class too
      @Override
      public void run() {
     //....
      }
    }, SOME_TOME_TIME);

    // Go back to the previous Activity.
    finish();
  }}

这将防止活动上下文被垃圾收集。

答案完全取决于面试官认为他们在问什么。

在实践中是否可能造成Java泄漏?当然是这样,其他答案中有很多例子。

但有很多元问题可能被问到了?

理论上“完美”的Java实现是否容易泄漏?候选人是否理解理论与现实之间的区别?应聘者是否了解垃圾收集的工作原理?或者垃圾收集在理想情况下应该如何工作?他们知道他们可以通过本地接口调用其他语言吗?他们知道用其他语言泄露内存吗?应聘者是否知道什么是内存管理,以及Java的幕后情况?

我把你的元问题理解为“在这种面试情况下我可以用什么答案”。因此,我将重点关注面试技巧,而不是Java。我相信,你更可能重复在面试中不知道问题答案的情况,而不是你需要知道如何使Java泄漏。所以,希望这会有所帮助。

你可以培养的面试最重要的技能之一是学会积极倾听问题,并与面试官合作以提取他们的意图。这不仅可以让你以他们想要的方式回答他们的问题,还表明你有一些重要的沟通技巧。当要在许多同样有才华的开发人员之间做出选择时,我会雇佣一个在他们每次回应之前都能倾听、思考和理解的人。