2013-06-11 33 views
10

我盡力解釋我的問題。也許這有點抽象。從Java中的複雜對象中釋放內存

我讀了一些關於文學不調用GC顯式地在Java代碼中,最後確定的方法,指着空,等

我有一些大個XML文件(客戶發票)。使用Jaxb,該文件編組在一個複雜的Java對象中。它的屬性是基本類型(Integer,BigDecimal,String等),但也包括其他類的類,其他類的列表,列表作爲屬性的類的列表等。

當我用對象,我需要將它從內存中刪除。一些XML非常大,我可以避免內存泄漏或OutOfMemoryError情況。

所以,我的問題是:

  • 是否有足夠大的分配對象爲null?我讀過,如果有軟引用,GC不會釋放該對象。
  • 我應該深入清除對象,清除所有列表,爲屬性賦予null等。
  • 怎麼樣JaxB(我使用Java6,所以JaxB內置)和軟引用? JaxB比舊的JibX編組速度更快,但我不知道內存使用情況是否更糟。
  • 我應該用WeakReference或類似的東西包裝megacomplex JaxB類嗎?

對不起混合Java內存使用率的概念,JAXB等我在研究了大量的運行過程的穩定性,以及.hprof文件證據表明,所有發票的所有客戶數據保留在內存中。 對不起,如果這是一個簡單的,基本的或罕見的問題。

在此先感謝

+0

在您完成Jaxb處理之後,代碼是否可以引用由Jaxb生成的對象?多長時間?另外,我不知道這是否可行,但是您可以使用構建器,以便在完成編組時可以生成最終結果而不需要特定於Jaxb的對象? – fge

回答

9

除非別的東西分給你的大對象(圖)的部分,分配大對象引用null就足夠了。

雖然最安全,但在應用程序運行一段時間後使用分析器,並查看對象引用,並查看是否存在未正確GC化的內容。

+0

+1提及使用Profiler進行仔細檢查。 – user949300

+0

@haraldK,謝謝你的回答。我正在學習分析和內存分析。我會嘗試將大對象設置爲空 –

3

你寫

hprof files evidence that all customers data of all invoices remains in memory. 

你應該使用mat分析它。一些好的筆記在http://memoryanalyzer.blogspot.in/

+0

感謝您的回答。我也在學習(開始)記憶分析。您的鏈接看起來像MAT開始很有用(軟件我已被推薦用於分析內存,泄漏等) –

4

是否足以將大對象分配給null?我讀過,如果有軟引用,GC不會釋放該對象。

簡短的回答是是的。將一個大對象分配(所有強引用)爲空就足夠了 - 如果你這樣做,垃圾收集器不再將該對象視爲「強可達」。

軟引用在你的情況下不會成爲問題,因爲它保證了在引發OutOfMemoryError之前可以輕鬆地收集到可輕鬆訪問的對象。他們可能會很好地阻止垃圾收集器立即收集對象(如果他們不這樣做,他們的行爲與弱引用完全相同)。但是這種內存使用將是「臨時的」,因爲如果需要完成分配請求,它將被釋放。

我應該深入清理對象,清除所有列表,將屬性賦值爲空等。

這可能是一個壞主意。如果字段值僅由外部大對象引用,那麼在收集大對象時它們也將被垃圾收集。如果他們不是,那麼引用他們的代碼的其他部分將不會很高興地看到你從他們正在使用的列表中刪除成員!

在最好的情況下,這什麼都不做,最糟糕的情況是這會破壞你的程序。不要讓這種誘惑分散您的注意力,以解決您的對象是否可以強制訪問的唯一實際問題。

JaxB(我使用Java6,JaxB內置)和軟引用呢? JaxB比舊的JibX編組速度更快,但我不知道內存使用情況是否更糟。

我對這些庫的相對時間和空間性能不是特別熟悉。但是總的來說,核心圖書館承擔一個非常強大的「無辜的,直到證實有罪」的態度是安全的。如果存在內存泄漏漏洞,現在可能已經發現,報告並修復了這個漏洞(除非你正在做一些事情)。

如果有內存泄漏,我99.9%確定它是你自己的代碼有問題。

我應該用WeakReference包裝Megacomplex JaxB類還是類似的東西?

這聽起來像你可能會拋出GC「修復」問題,而不考慮實際需要的內容。

如果JaxB類應該被弱引用,那麼無論如何這是一個好主意(它應該已經存在)。但如果不應該,那麼絕對不要這樣做。弱引用更多的是整體語義問題,不應該是專門爲避免內存問題而引入的內容。

如果外部代碼需要對該對象的引用,那麼它需要一個引用 - 沒有什麼魔法可以讓這個實例被垃圾收集,但仍然可用。如果它不需要引用(超出某個特定點),那麼它根本不需要引用 - 更好的是使標準[強]引用無效,或者讓它超出範圍。弱引用是一種特殊情況,通常在你無法完全控制一個對象停止相關的點時使用。這可能是不是這裏的情況。

.hprof文件證明所有發票的所有客戶數據都保留在內存中。

這表明它們確實被引用的時間超過了必要的時間。

好消息是hprof文件將包含正確引用它們的細節。查看您希望獲得GCed的發票實例,並查看引用它的內容並防止它被GCed。然後看看有關問題的課程,看看你是如何期望該引用被釋放,以及爲什麼它沒有在這種情況下。

所有良好的性能/內存調整是基於測量。採取堆轉儲,並檢查實例和引用它們,是您的測量。做到這一點並根據結果採取行動,而不是試圖在WeakReferences中包裝某些東西,希望它可以提供幫助。

+0

感謝您的解釋和詳細的答案。我從這類問題開始(內存管理),並且我不想做那些「可能有用的希望」的事情。我的問題與我的發票對象一樣複雜,我混合了一些概念。我會通過「試錯法」的方法嘗試您的建議,進行堆轉儲,分析和分析它們。謝謝 –