1

他们在 android.com 上说,如果您使用 Java,则可以使用的最大内存为 16 MB。至少这是设备应该支持的。如果您的手机较旧,您会发现无法获得更多,反而会收到 OutOfMemoryError。如果您使用 NDK 做同样的事情,则不会。在我的应用程序中,我试图获得 50MB 甚至更多,到目前为止,Android 还算不错。

我在 android.com 上没有找到与此相关的任何内容。

像Java一样有限制吗?

如果是:限制是多少?

如果不是:那有什么好的价值?

问题是,我必须根据该大小构建我的代码。

[编辑:] 我尝试了 Seva Alekseyev 的建议。

     root@android:/ # ulimit -a
     ulimit -a
     time(cpu-seconds)    unlimited
     file(blocks)         unlimited
     coredump(blocks)     0
     data(KiB)            unlimited
     stack(KiB)           8192
     lockedmem(KiB)       64
     nofiles(descriptors) 1024
     processes            7806
     flocks               unlimited
     sigpending           7806
     msgqueue(bytes)      819200
     maxnice              40
     maxrtprio            0
     resident-set(KiB)    unlimited
     address-space(KiB)   unlimited
     root@android:/ # ulimit -v
     ulimit -v
     unlimited
     root@android:/ #

我请求的内存(通过使用“alloc”或“new”)是虚拟内存(ulimit -v)。所以没有机会弄清楚我能得到多少?!

4

1 回答 1

2

您受到三种类型的内存限制:

1) 人为设置限制以保持系统在多任务处理时的响应——VM 堆限制是这方面的主要例子。ulimit 是操作系统为您提供进一步限制的潜在机制,但我还没有看到它在 Android 设备上被限制使用。

2) 基于可用实内存的物理限制。您应该有一个正在开发/测试的基准设备,并且应该非常积极地假设其他进程(后台服务、其他应用程序)也需要内存。还要记住,操作系统使用的内存随操作系统版本而变化(并且会随着时间的推移而增加)。Stock Android 不会交换,所以如果你走得太远,你就死定了。一种可能的情况是 Nexus One(512MB RAM),带有音频播放器和手机应用程序在后台运行,“气球”服务占用另外 100MB 物理内存以留出一些余地;在此配置中,您仍然会发现超过 100MB 的可用空间。

3) 基于地址空间的虚拟内存限制。Stock android 允许过度使用内存,因此如果您在具有 512MB RAM 的设备上请求 1GB 虚拟分配(通过 mmap 等),它不会闪烁,这通常是一件非常有用的事情。但是,当您随后触摸内存时,需要将其带入物理内存。如果物理内存中有只读页面,它们可以被弹出,但很快你就会用完,而且没有交换——死了。(在内存不足的情况下,组合和过度提交和无交换直接导致进程死亡,而不是像 malloc 返回 null 这样的可恢复错误)。

最后,值得注意的是 calloc/malloc/new 是否需要物理分配取决于分配器,但假设是更安全,尤其是对于少于大量页面的分配。所以:如果您正在处理 < 100 MB 的标准、行为良好的分配,那么您可能很清楚——但请测试!如果您正在处理需要内存映射的大量数据,则 mmap 是您的朋友,小心使用时,并且仅与 PROT_READ 一起使用时是您最好的朋友。如果您要处理大于 100 MB 的物理内存分配,希望在现代设备上运行得非常好,但是您必须仔细定义基线并测试、测试、测试,因为检测到内存不足的情况苍蝇一般是不可能的。

另一个注意事项:APP_CMD_LOW_MEMORY 存在,并且是清除缓存的好地方,但不能保证及时调用它来挽救你的生命。它根本不会改变整体情况。

于 2012-12-05T17:38:38.040 回答