2015-11-02 85 views
6

我有一個客戶的呼叫上週末告訴我做數據導入時,他們的Java程序沒有響應。該數據是一個帶有4個工作表的簡單Excel工作簿。所有數據正在從列中讀取並添加到數據庫中。作戰的Java堆大小,Java之間的大區別本地和Java Web Start

於是我開始調查,並有一些奇怪的結果。

  1. 使用Netbeans中的Run測試導入。此使用Java 64位實例:

首先運行

local first run (64-bit)

第二運行

local second run (64-bit)

  • 測試通過使用Java Web Start進行導入。這是正在打開JNLP文件發佈和使用Java 32位實例:
  • 首先運行

    webstart first run (32-bit)

    在這種情況下,我有同樣的問題這對客戶來說是報告,程序在經過一段時間後才停止響應。這是由於我達到最大堆大小,據我所知(紅圈)。

    第二輪

    所以我決定增加通過添加以下到我的JNLP文件的初始堆大小和最大堆大小:initial-heap-size="512m" max-heap-size="1024m"。當我再次測試的進口,它似乎工作,但我發現有使用更多的內存相比前兩種情況:

    webstart second run (32-bit)

    • 爲什麼會出現的情況下,與內存使用300MB的區別1和2與案例4相比?
    • 這是內存佔用率過高不好的編程或內存泄漏的結果?或者是否有這樣高的值是正常的?
    • 是增加initial-heap-size="512m" max-heap-size="1024m"針對此問題的有效的解決方案?
    +4

    @StackFlowed我非常懷疑。 – Kayaman

    回答

    2

    那麼,明顯的區別是你的第一次運行是用64-bit server VM來完成的,後面的運行是用32-bit client VM來完成的。

    據說客戶端虛擬機爲桌面型應用程序更好的可用性和虛擬機「服務器」工作優化的服務器進行了優化。我沒有完整的差異列表(或者它在實際使用情況下是否確實可行)。不要在此引用我的意見,但我確實相信客戶端虛擬機避免GC比服務器虛擬機更多,因爲它至少在一個點上被認爲是緩慢的。這將解釋爲什麼客戶端虛擬機使用更多的內存,而不是積極釋放它。

    擺弄GC參數有時是正確的事情,在這種情況下,它幾乎是唯一可以做的事情,除非您發現任何重大的內存泄漏。不管怎樣,熟悉什麼使GC在任何情況下打勾都不失爲一個好主意。

    +0

    非常感謝您的回答,我通過查看Eden&Old gen空間來進一步檢查我的應用程序是否存在內存泄漏,但沒有看到任何壯觀的事情。現在它已經被初始堆大小和最大堆大小修復了,但我會看看是否可以更多地優化我的代碼。我認爲記憶峯值是由顯示/隱藏的控件引起的。 Allthough我猜想它應該保持引用而不是在內存中創建新的引用? – Perneel

    +0

    是的,如果你只是隱藏一個組件,它不符合GC的條件。您應該運行內存採樣器一段時間,以查看是否可以識別任何其他熱點。 – Kayaman

    +1

    我改變了我的代碼。我根據用戶輸入做了很多數據庫創建實體的請求,總是創建一個Client對象來處理這個請求。似乎這是造成內存問題。我現在將所有要創建的實體放入一個包裝中,並在一個請求中創建它們。 – Perneel