2017-05-08 58 views
-3

我想問的確切問題已經回答here。不過我只想探索更多的可能性(如果有的話)。高效使用Java堆內存

場景:我的應用程序是基於線程的以數據爲中心的web應用程序,數據量由用戶在運行時決定。用戶可以請求一些數據操作,這會觸發多個線程,每個線程傳輸自己的數據。有時,數據選擇會使應用程序崩潰OutOfMemoryError,即沒有足夠的空間來分配Java堆中的新對象。當有多個用戶同時使用該應用程序並且大多數用戶請求大數據操作時,這種情況(OutOfMemoryError)更可能發生。

問題:有沒有一種方法可以防止整個應用程序崩潰?我可以限制內存中的數據量,但如果有更好的方法比這更好?即使在限制每個用戶的數據量之後,多個併發用戶也可以生成OutOfMemoryError。一個用戶可以暫停或退出,而不是全部生存。

+0

想想這樣:如果你到了一個你內存不足的地步,_something_需要被清除/覆蓋,或者他們只需要等到先前的任務完成。理想情況下,您將能夠估計手頭任務的內存量。嘗試發佈一些更具體的問題,因爲對於實際的問題,可能有更好的解決方案。 – Rogue

+0

@盜賊謝謝,但你提到的觀點已經爲我所知。我關心的是併發性,即用戶是否對應用程序造成問題。有沒有辦法阻止其他用戶離開他? – manurajhada

+0

@盜賊我明白,你的意見是有道理的。 – manurajhada

回答

1

始終如一我已經經歷了以下幾個點:

  • 流大數據出來。與Accept-Inflate上的GZIPOutputStream(可能是servlet過濾器)結合使用。這可以爲文件系統和數據庫完成。此外還存在(基於URL)XML流水線,其中部分XML可以流式傳輸。

這降低存儲器成本,一個流可以被節流(articially減慢

  • PDF生成:優化PDF,重複圖像只存儲一次,明智的字體使用(理想的PDF字體,否則嵌入字體)

  • Office文檔:。在OpenOffice或微軟XLSX/DOCX變種

你的情況:

有充分的過程是結合的,並且流下,結果到一個輸出流:任務的分支管道。如果可以使用相同的參數調用這樣的任務,產生相同的數據,則可以使用參數化的URL並緩存結果。

我知道這個答案可能不適合。

+0

如果我將每個新的http請求作爲新進程啓動,該怎麼辦?它會有效嗎?通過這種方式,每個用戶請求將不會相互搶佔內存? – manurajhada

+0

正常的方法是使用線程池,重用線程,通常沒有垃圾收集問題,並且是一個非常有效的限制機制。 **內存映射文件**可以在某些情況下用來逃避使用Java堆。使用課程數據庫也很好。 –