Java应用程序中是否完全没有内存泄漏?

Are memory leaks totally absent in Java applications?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Creating a memory leak with Java

在爪哇有一个"垃圾收集器",但这是否意味着Java应用程序中完全没有内存泄漏?如果没有,它们是如何发生的,为什么会发生?

我对使用Javase的应用程序的场景更感兴趣。


Java中仍然没有内存泄漏。它们只是一种"不同的种类"。

wiki:内存泄漏

A memory leak, in computer science (or leakage, in this context), occurs when a computer program consumes memory but is unable to release it [the memory] back to the operating system.

< /块引用>

在Java的情况下(通常)是当未使用的/不需要的对象永远不符合回收的资格。例如,一个对象可能被存储在一个全局列表中,并且永远不会被删除,即使以后再也不会访问该对象。在这种情况下,JVM不会释放对象/内存——它不能——因为对象可能在以后需要,即使它从来都不是。

(除此之外,一些对象(如直接由Buffers分配的对象)也会消耗"超出JVM堆"的内存,由于终结器的性质和内存压力,这些内存可能无法及时回收。)

在Java的情况下,"内存泄漏"是语义问题,而不是"不能在任何情况下发布"的问题。当然,使用Buggy JNI/JNA代码,所有的赌注都是关闭的;-)

快乐编码。


取决于如何定义内存泄漏。

如果您的意思是分配的内存不再被某个内存根引用,那么不,垃圾收集器最终将清除所有这些内存。

如果您的意思是通常让您的内存足迹不受约束地增长,那么这很容易实现。只是让一些集合被静态字段引用并不断添加到。


任何具有一个或多个活动引用的对象都不会被垃圾收集。只要某个变量(静态、堆中或堆栈中)引用某个对象,该对象将继续占用不可回收的内存空间。

未关闭的资源(如套接字、JDBC连接等)和不断增长的静态集合是一些更著名的泄漏生成器。


到目前为止,有一些很好的回应。我不想重新创建这些文章,所以我只想补充一点,大多数人不考虑与这个主题相关的一件事是通过JNI运行的本机代码泄漏。通过JNI运行的本机代码使用JVM的堆空间来分配内存。因此,如果您的应用程序使用通过JNI运行的本机代码,那么您的应用程序就有一个漏洞。


Java中的内存泄漏是非常可能的。这是一篇很好的文章,里面有一个使用JAVA Java的例子。从根本上讲,当垃圾回收器无法回收对象时,Java内存会发生内存泄漏,因为应用程序持有对它不释放的引用,即使对象本身可能不再被使用。在Java中创建内存泄漏最简单的方法是让应用程序保持对某个引用的引用,而不是使用它。

在本例中,未使用的对象是一个静态列表,向该列表中添加内容最终会导致JVM耗尽内存。静态集合是"泄漏"的一个非常常见的来源,因为它们通常是长期存在的和可变的。