2012-01-24 40 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

相关问题