Android OutOfMemory 但有空闲内存
因此,我一直试图让内存密集型程序正常工作,但一直遇到内存错误。我读过其他线程,他们都谈论内存泄漏,但我不认为这里是这种情况。
我创建了一个分配 1 MB 空间的按钮,然后以 MB 为单位显示内存使用情况(maxmem、totalmem、freemem)。最初我有 (40, 5, 2),我按下按钮 (40, 6, 2)。我按住按钮,然后得到 (40, 7, 2)、(40, 8, 2)、(40, 9, 2),然后是 OutOfMemory。我期望 (40, 10, 2) 并且在达到 (40, 40, 0) 之前不应该出现内存不足,对吗?
int[][] hi = new int[100][];
int i = 0;
public void save(View view) {
hi[i] = new int[256*1024];
i++;
TextView tv1 = (TextView) findViewById(R.id.seekBar1Text);
System.gc();
tv1.setText("Memory is max " + Runtime.getRuntime().maxMemory()/1024/1024 + " total " + Runtime.getRuntime().totalMemory()/1024/1024 + " free " + Runtime.getRuntime().freeMemory()/1024/1024);
}
So I've been trying to get a memory intensive program to work, and kept running into memory errors. I've read the other threads, and they all talk about memory leaks, but I don't think that is the case here.
I created a button that allocates 1 megabyte of space, then displays the memory usage in megabytes (maxmem, totalmem, freemem). Initially i have (40, 5, 2), I press the button (40, 6, 2). I keep pressing the button and I get (40, 7, 2), (40, 8, 2), (40, 9, 2), then OutOfMemory. I would expect (40, 10, 2) and shouldn't get OutOfMemory until I hit (40, 40, 0), right?
int[][] hi = new int[100][];
int i = 0;
public void save(View view) {
hi[i] = new int[256*1024];
i++;
TextView tv1 = (TextView) findViewById(R.id.seekBar1Text);
System.gc();
tv1.setText("Memory is max " + Runtime.getRuntime().maxMemory()/1024/1024 + " total " + Runtime.getRuntime().totalMemory()/1024/1024 + " free " + Runtime.getRuntime().freeMemory()/1024/1024);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我注意到 Dianne Hackborn 的明确答案Android 内存测量不使用
运行时
方法。因此,我不知道我是否会相信他们。首先,我知道没有 Android 设备的堆大小为 40MB。另外,您似乎认为
OutOfMemoryError
意味着您的内存完全耗尽。当尝试分配失败时,将发生OutOfMemoryError
。这可能是因为没有您所寻求的大小的单个空闲块。由于 Dalvik VM GC 例程的性质,这种情况在 Android 上比其他操作系统更有可能发生。I notice that Dianne Hackborn's definitive answer on Android memory measurement does not use the
Runtime
methods. Hence, I do not know if I would trust them. For starters, I know of no Android device with a 40MB heap size.Also, you seem to assume that an
OutOfMemoryError
means that you are fully out of memory. AnOutOfMemoryError
will occur when an attempted allocation fails. That could be because there is no single free block of the size you seek. This is more likely to happen on Android than with other operating systems due to the nature of the Dalvik VM's GC routines.有趣的问题。我一直在各种 Android 版本(模拟)中尝试过这个,并在我自己的机器上尝试过。我可以在 Android 3.1 上看到您期望的行为(内存填满,然后才崩溃),但 2.2 显示了您所描述的行为。
正如@CommonsWare所说,它很可能与您请求的巨大内存块有关:即使在我的机器上,我也无法分配具有 4*256*1024 个元素的数组(请记住,该数组必须是可索引的,因此它以某种方式是连续的)。
最好的解决方案似乎不是分配更少的内存,而是分配的时间不要那么多。在Android 2.2中,我可以使用16*1024的块来填充内存,没有任何问题。
确切的解决方案取决于您的应用程序的具体情况。例如,
Interesting problem. I have been playing around with this in various Android versions (emulated), and tried it out on my own machine. I can see the behavior you expect (memory filling up, and only then crashing) on Android 3.1, but 2.2 shows the behavior you describe.
As @CommonsWare states, it most likely has to do with the huge block of memory you request: even on my machine, I cannot allocate an array that has 4*256*1024 elements (remember that this array has to be indexable, so it has be contiguous somehow).
The best solution seems to be not to allocate less memory, but to allocate not as much as the same time. In Android 2.2, I can fill up the memory using blocks of 16*1024 without any problems.
The exact solution depends on the specifics of your application. For instance,
在 JVM 中,它将大型结构直接放入永久空间中。如果它无法调整此空间的大小(或其过于碎片化),即使有足够的可用空间,您也可能会耗尽这些结构的可用空间。有时调整虚拟机会有所帮助。
In the JVM, it places large structures directly into a tenured space. If it can;t resize this space (or its too fragmented) you can run out of available space for these structures even though there is plenty of free space. Sometimes tuning the VM can help.
在我的模拟器(设置为 API 10)上,我使用了这个:
我崩溃了,因为 blob + app 略大于模拟器的 24MB 限制。
但我仍然没有完全理解内存问题。就内存而言,Android/Java 世界似乎比 Linux/C 世界更复杂。
On my emulator (set to API 10) I used this:
I got a crash, because blob + app were slightly larger than emulator's 24MB limit.
I still don't fully get the memory issues though. Seems that Android/Java world is more complex than the Linux/C world when it comes to memory stuff.