2011-07-12 23 views

回答

14

否 - 内存泄漏仍然可以在Java中存在。他们只是一种“不同类型”。

Wiki: Memory Leak

内存泄漏,在计算机科学(或泄漏,在这种情况下),会发生当一个计算机程序消耗内存但是不能释放它[存储器]回操作系统

在Java它的情况下(正常)是当一个未用的/不需要的对象从未获回收。例如,即使该对象以后从未被访问过,对象也可能隐藏在全局列表中,并且永远不会被删除。在这种情况下,JVM将不会释放对象/内存 - 它不能 - 因为对象可能在以后需要,即使它不是也不是

(顺便说一句,一些物体,如直接分配的ByteBuffers也消耗“掉JVM堆的”,这可能不及时由于终结和内存压力的性质来回收的存储器。)

在Java的情况下,“内存泄漏”是语义问题而不是“在任何情况下都无法释放”的问题。当然,有错误的JNI/JNA代码,所有投注都关闭;-)

快乐编码。

+2

作为后续工作,没有垃圾收集器总是可以回收所有未使用的内存。建立一个可以检测某个内存是否永远不会再被使用的GC是不可能的,因此大多数GC使用内存是否可以**作为代理。 – templatetypedef

+0

感谢您快速回复pst。你提到的问题是正确的,但更多的是因为(糟糕的)编程实践,对吧?假设内存中有一些“真的”符合回收的对象,它们肯定会被JVM回收吗?当然? – Bhushan

+1

@10101010可回收对象,那些从根部无法到达的对象,**将在“某个时间点”被回收**,是的。但是,对于在终结器中释放“本机”内存的对象,可能((“本地”)内存不够快地释放 - 即使它*可能是*),因此可能导致[过早] OOM。 – 2011-07-12 19:25:21

1

java中的内存泄漏是非常可能的。 Here is a good article which has an example using core java。从根本上讲,当垃圾收集器无法回收对象时,会发生内存泄漏,因为应用程序持有对它的引用,即使该对象本身可能不再使用,它​​仍不会释放。在java中创建内存泄漏的最简单方法是让应用程序对某些内容进行引用,但不使用它。

在此示例中,未使用的对象是一个静态List,并且将其添加到该列表最终会导致JVM耗尽内存。静态集合是“泄漏”的一个相当常见的来源,因为它们通常是长寿命和可变的。

2

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

如果您具体指分配的内存不再由某个内存根引用,那么否,垃圾收集器将最终清除所有这些内存。

如果你的意思一般有你的内存占用量增长没有约束,这是容易实现。只是有一些静态字段引用的集合,并不断添加到。

1

到目前为止有几个很好的回应。我不想重新创建这些帖子,所以我只想补充一点,大多数人不会考虑与这个主题相关的内容是通过JNI运行的本地代码中的泄漏。通过JNI运行的本地代码使用JVM的堆空间来分配内存。因此,如果您的应用程序使用通过JNI运行的泄漏代码,您的应用程序会发生泄漏。

1

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

未关闭的资源(如插座,JDBC连接等)和不断增长的静态集合是一些较知名的泄漏生产者。