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

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

什么样的例子?


当前回答

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

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

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

其他回答

以在任何servlet容器(Tomcat、Jetty、GlassFish等)中运行的任何web应用程序为例。连续重新部署应用程序10或20次(只需在服务器的autodeploy目录中触摸WAR即可)。

除非有人真的测试过,否则在重新部署几次之后,很可能会出现OutOfMemoryError,因为应用程序没有注意自己的清理。通过此测试,您甚至可以在服务器中发现错误。

问题是,容器的生存期比应用程序的生存期长。您必须确保容器对应用程序的对象或类的所有引用都可以被垃圾收集。

如果只有一个引用在web应用程序的取消部署后仍然存在,则相应的类加载器以及web应用程序中的所有类都不能被垃圾收集。

应用程序启动的线程、ThreadLocal变量、日志附加器是导致类加载器泄漏的常见原因。

我可以从这里复制我的答案:在Java中导致内存泄漏的最简单方法

“在计算机科学中,当计算机程序消耗内存但无法将其释放回操作系统时,就会发生内存泄漏。”(维基百科)

简单的答案是:你不能。Java执行自动内存管理,并将释放您不需要的资源。你无法阻止这种情况的发生。它将始终能够释放资源。在具有手动内存管理的程序中,这是不同的。可以使用malloc()在C中获得一些内存。要释放内存,您需要malloc返回的指针并对其调用free()。但是,如果您不再拥有指针(被覆盖或超过生存期),那么很遗憾,您无法释放此内存,因此会出现内存泄漏。

到目前为止,所有其他答案在我的定义中都不是真正的内存泄漏。他们的目标都是快速用毫无意义的东西填满记忆。但在任何时候,您仍然可以取消引用创建的对象,从而释放内存-->无泄漏。尽管我不得不承认,acconrad的答案非常接近,因为他的解决方案实际上是通过强制垃圾收集器进入一个无休止的循环来“崩溃”垃圾收集器)。

长时间的答案是:通过使用JNI为Java编写库,可以获得内存泄漏,JNI可以进行手动内存管理,从而产生内存泄漏。如果调用此库,Java进程将泄漏内存。或者,JVM中可能存在bug,从而导致JVM丢失内存。JVM中可能存在bug,甚至可能存在一些已知的bug,因为垃圾收集并不是那么简单,但它仍然是一个bug。根据设计,这是不可能的。您可能需要一些受此类错误影响的Java代码。很抱歉,我不知道,而且在下一个Java版本中,它可能不再是一个bug。

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

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

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

Java内存泄漏的一个例子是当忘记调用ResultSets close方法时导致的MySQL内存泄漏错误。例如:

while(true) {
    ResultSet rs = database.select(query);
    ...
    // going to next step of loop and leaving resultset without calling rs.close();
}

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

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

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

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

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

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