`
dengbaoleng
  • 浏览: 1124989 次
文章分类
社区版块
存档分类
最新评论

由android:process引发的内存限制的问题

阅读更多

android:process

定义activity运行所在的进程名称。一般情况下,应用的所有组件都运行在为应用创建的默认的进程中,该默认进程的名称应用包名称一致。通过定义<application>元素的“process”属性可以为所有组件指定一个不同的默认进程。但是任意组件都可以重写默认进程,以便实现多进程操作。

如果该属性指定名称以“:”开头,则一个新的专属于该应用的进程将会被创建。如果该进程名以小写字母开头,则为该activity提供权限以让其在一个全局的进程中运行。这样会允许多个应用的不同组件共用一个进程,以便节省资源。

Android是支持多进程的,每个进程的内存使用限制一般为24MB的内存,所以当完成一些很耗费内存的操作如处理高分辨率图片时,需要单独开一个进程来执行该操作(上面的配置可以用来实现该操作)。即便如此,开发者还是不要随意多开进程来耗费用户的资源。(内存限制,有16MB24MB 32MB,很老的机型的内存限制会是16MB,这个具体还要再搜索下资料。。)

另外一些还有一些其他的方式来绕过内存限制,使用更多的资源来完成自己的任务,如下文(有待实践):

How to work around Androids 24 MB memory limit

The Android framework enforces a per-process 24 MB memory limit. On some older devices, such as the G1, the limit is even lower at 16 MB.

Whats more, the memory used by Bitmaps is included in the limit. For an application manipulating images it is pretty easy to reach this limit and get the process killed with an OOM exception:

E/dalvikvm-heap(12517): 1048576-byte external allocation too large for this process.
E/GraphicsJNI(12517): VM won't let us allocate 1048576 bytes
D/AndroidRuntime(12517): Shutting down VM
W/dalvikvm(12517): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0)
E/AndroidRuntime(12517): FATAL EXCEPTION: main
E/AndroidRuntime(12517): java.lang.OutOfMemoryError: bitmap size exceeds VM budget

This limit is ridiculously low. For a device, like the Nexus One, with 512MB of physical RAM, setting the per-process memory limit for the foreground activity to only 5% of the RAM is a silly mistake. But anyway, thats how things are and we have to live with it i.e. find how to work around it.

There are two ways to allocatemuchmore memory than the limit:

One way is to allocate memory from native code. Using the NDK (native development kit) and JNI, its possible to allocate memory from the C level (e.g. malloc/free or new/delete), and such allocations are not counted towards the 24 MB limit. Its true, allocating memory from native code is not as convenient as from Java, but it can be used to store some large amounts of data in RAM (even image data).

Another way, which works well for images, is to use OpenGL textures the texture memory is not counted towards the limit.

To see how much memory your app has really allocated you can use android.os.Debug.getNativeHeapAllocatedSize().

Using either of the two techniques presented above, on a Nexus One, I could easily allocate 300MB for a single foreground process more than 10 times the default 24 MB limit.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics