Android OutOfMemory 但有空闲内存

发布于 2025-01-06 13:31:39 字数 699 浏览 0 评论 0原文

因此,我一直试图让内存密集型程序正常工作,但一直遇到内存错误。我读过其他线程,他们都谈论内存泄漏,但我不认为这里是这种情况。

我创建了一个分配 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北斗星光 2025-01-13 13:31:39

我注意到 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. An OutOfMemoryError 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.

橘寄 2025-01-13 13:31:39

有趣的问题。我一直在各种 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,

  • If you're processing incoming data, you could try keeping less of it in memory, and using stream processing.
  • If you really need the data, you could consider different structures (that don't require contiguous blocks).
  • If all else fails, you can always build some helper classes that give the impression of a contiguous block of memory, while actually chunking it into smaller parts.
∞梦里开花 2025-01-13 13:31:39

在 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.

葮薆情 2025-01-13 13:31:39

在我的模拟器(设置为 API 10)上,我使用了这个:

Runtime rt = Runtime.getRuntime();

rt.gc(); // cause garbage collection for better accuracy

int[][] i = new int[4024][2014]; // a blob from hell to cause OOM crash and Force Close 

long max = rt.maxMemory(); // max that can be allocated (more than max gets you OOM crash)

long total = rt.totalMemory(); // this is total in use, not total possible

long free = rt.freeMemory();    

long used = (total - free); 

s = "RAM:" + String.format("%.0fKB, %.0fU, %.0fF", 
                           max / 1024.0, used / 1024.0, free / 1024.0); 

我崩溃了,因为 blob + app 略大于模拟器的 24MB 限制。
但我仍然没有完全理解内存问题。就内存而言,Android/Java 世界似乎比 Linux/C 世界更复杂。

On my emulator (set to API 10) I used this:

Runtime rt = Runtime.getRuntime();

rt.gc(); // cause garbage collection for better accuracy

int[][] i = new int[4024][2014]; // a blob from hell to cause OOM crash and Force Close 

long max = rt.maxMemory(); // max that can be allocated (more than max gets you OOM crash)

long total = rt.totalMemory(); // this is total in use, not total possible

long free = rt.freeMemory();    

long used = (total - free); 

s = "RAM:" + String.format("%.0fKB, %.0fU, %.0fF", 
                           max / 1024.0, used / 1024.0, free / 1024.0); 

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文