2013-07-15 50 views
-2

在我們的Java應用程序之一,我們已經得到 OutOfMemoryError:GC Overhead limit exceeded.的OutOfMemoryError:GC開銷超過限制

我們已經用在someplaces HashMaps這樣用於存儲我,我們可以找出一些data.From日誌重放的在同一個地方。

我想問一下垃圾收集器是否花更多時間清理hashmaps?

在看代碼(我不能分享在這裏),我發現有一個HashMap創建像

Hashmap topo = new HashMap();

,但從未使用過此HashMap。 這是我的應用程序中的一種內存泄漏嗎?

如果此Hashmap被這是做一些處理的方法中創建並且它不別處使用這種方法也被訪問我的多個線程說20。然後在這樣的情況下將它的影響,如上面創建的Hashmap,垃圾收集器花更多時間來恢復堆並拋出OOME。

如果您需要更多詳細信息,請讓我知道。

+2

如果'topo'引用不能轉義它所聲明的範圍,那麼否,它不會造成內存泄漏。 –

+0

垃圾收集器在清除這些HashMap時會遇到問題嗎?如果假設有大量的hashmaps – Saurav

+2

使用分析器來查看內存消耗或增加最大內存大小。如果你不測量你的程序,你只是猜測。使用大量的HashMap對性能/內存不利,但它可能不是您最大的問題。 –

回答

0

n one of our java application we have got OutOfMemoryError:GC Overhead limit exceeded. We have used HashMaps in someplaces for storing some data.From logs we can I identify that its reproducing at the same place.

如果HashMap的僅僅是有史以來建設,最有可能被標記爲靜態的,這意味着你不斷添加的東西這個HashMap和永不刪除。然後一個很好的一天它會導致OutOfMemoryError。

I wanted to ask if Garbage Collector spends more time in clearing up the hashmaps?

垃圾回收器花費時間在未引用,弱引用,軟引用的對象上。無論它找到這樣的物體,根據需要它將清除它們。

Upon looking at the code(i cant share here), I have found that that there is a Hashmap created like Hashmap topo = new HashMap(); , but this hashmap is never used. Is this a kind of memory leak in my application ?

if this Hashmap is created inside a method which is doing some processing and it is not used elsewhere also this method is accessed my multiple threads say 20 . Then in such a case would it impact,creating Hashmap as above, Garbage collector to spend more time in recovering heap and throw OOME.

如果是HashMap的地方到methid和方法做了一些處理後退出,那麼就應該儘快收集方法退出垃圾。由於hashmap對於方法來說是本地的,因此每個線程都會有一個單獨的映射副本,並且一旦線程完成方法執行,map就可以使用GC。

+0

謝謝...假設如果有大量這樣的未使用的HashMap,請問垃圾收集器會花費一些時間來恢復堆,並且它可能會拋出OOME。 – Saurav

+0

@Saurav空的hashmaps的簡單參考幾乎不會吃大量的堆空間。 –

+0

簡單的答案是,你在別處泄漏。您將在應用程序的整個生命週期中保存或累積實際數據。暫時的HashMap(局部於方法&不在外部引用)不會成爲問題。 –

0

您需要尋找長壽命的物體結構,這可能是實際的問題,而不是瘋狂地掌握一些無知的經理人對潛在問題的想法。

參見:

看出來特別是對靜態/或應用程序生命週期地圖或列表,它被添加到生命週期中,而不是僅僅在初始化。它很可能是一個或幾個正在積累的東西。

還要注意,內部類(Listener,Observers)可以捕獲對其包含範圍的引用&防止它們被無限期GC_ed。

+0

我收集了OOME上的heapDump,發現我們在ThreadpoolExecutor中使用的LinkedBlockingQueue佔用了分配給process.total堆的93%,分配的總堆是-Xmx3500m.Is發生這種情況是因爲任務生成速度比池中的線程正在執行它嗎?可能這個java錯誤會對此負責:http://bugs.sun.com/view_bug.do?bug_id=6806875。如何處理這種情況? – Saurav

+0

JDK bug不應該導致OOME - 它應該會降低性能,並且當「次要GC」本來就足夠時會導致「完全GC」。 –

+0

爲什麼不包裹LinkedBlockingQueue的條目(添加)和退出(刪除)點,並計算進/出和排隊的多少任務?記錄下來,看看是否是這種情況,如果是這樣 - 那麼你可以查看*爲什麼*這麼多任務已經入隊。 –

0

Please let me know if you need some more details.

需要一些更多的細節。您需要對應用程序進行配置,以查看哪些對象正在佔用堆空間。

然後,如果某些可調整大小的對象實際上不再被應用程序使用,則會發生內存泄漏。查看對這些對象的引用,找出爲什麼當它們不再有用時,它們仍然保留在內存中,然後修改代碼以不再保存這些引用。

或者,您可能會發現內存中的所有對象都是您期望作爲工作集的內容。然後,無論您需要增加堆大小,還是重構應用程序以使用較小的工作集(例如,一次一個流式傳輸事件,而不是讀取整個列表;將最後的日期細節存儲在數據庫而不是內存中;等等)。

+0

我收集了OOME上的heapDump,發現我們在ThreadpoolExecutor中使用的LinkedBlockingQueue佔用了分配給process.total堆的93%,分配給的是-Xmx3500m.Is發生這種情況是因爲任務生成速度比池中的線程正在執行它嗎?可能這個java錯誤會對此負責:http://bugs.sun.com/view_bug.do?bug_id=6806875。如何處理這種情況? – Saurav

+0

@Saurav再一次,這是你必須看的東西,但它似乎可能是你添加任務太快。該隊列中的任務是否都處於等待執行狀態?如果是這樣,那麼確實你已經產生了3.3GB的數據需要在未來運行,但還沒有。在這種情況下沒有簡單的答案。要麼限制創建任務的速度,要麼提高處理速度,要麼增加堆大小。你選擇哪一個取決於你的要求和你的情況的細節。 –

+0

爲了解決這個問題,我使用了ArrayBlockingQueue(50),並且線程池中最多有20個線程。由於我使用了有界隊列,因此後續任務將被拒絕,所以使用RejectedExecutionHandler處理拒絕的任務和缺省處理程序政策CallerRunsPolicy,因爲我不想失去任務。我期待着測試這個解決方案。請提供您的意見。它會有幫助嗎? – Saurav

相關問題