2012-01-24 38 views
3

我看到下面的東西在我的亞行logcat窗口:爲什麼這些內存分配數不加起來?

01-24 14:40:56.916: E/dalvikvm-heap(24727): 1957200-byte external allocation too large for this process. 
01-24 14:40:56.966: E/GraphicsJNI(24727): VM won't let us allocate 1957200 bytes 
01-24 14:40:56.976: E/dalvikvm(24727): OutOfMemory: max: 50331648(49152 K), total: 39985120(39047 K), alloc: 33659240(32870 K), extAlloc: 8993870(8783 K) 

我不明白的是爲什麼這些數字對不上(或者我只是不明白這是如何工作)。我看到OutOfMemory:基本上最大爲48MB - 我認爲這是最大的堆大小。不確定這個上下文中的「total」是什麼意思,但它看起來像大約39MB。它在2MB分配上失敗了,我不明白爲什麼它失敗了,應該有9MB可用...我在這裏誤解了什麼?

回答

4

歡迎來到堆碎片的美妙世界。簡而言之,您需要連續的內存塊來滿足分配,而不僅僅是足夠的空閒字節。

作爲一個例子,想象一個空的1MB堆。現在想象一下,在1MB的中間是一個1K分配。即使你有99.9%的空間是免費的,你也不能分配超過500K的空間,因爲它必須是連續的。移動這個1K分配,你可以分配更多,但是在病態的情況下,最終你的分配空間可能會大得多。

對於你的情況,我敢打賭,如果你試圖做2000 1K的分配,將工作的偉大。如果你正在處理碎片或其他問題,那會讓你知道。

+0

所以必須有一種方法來重新配置碎片內存。 System.gc()是否可以做到這一點? – user645402

+0

GC可以減少某些碎片,但並非所有內存分配都可以移動。當前正用於調用操作系統的緩衝區不能移動。 – twk

+0

所以後來的另一件事是,這個東西應該支持48MB的堆(至少根據Runtime.maxMemory(),那麼爲什麼沒有自動增大堆的大小,以適應新的分配? – user645402

相關問題