2011-07-12 25 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連接等)和不斷增長的靜態集合是一些較知名的泄漏生產者。