Android 中的 Dalvik Heap 和 Native Heap

Android程序为什么容易出现OOM

这个是因为 Android系统对 dalvik 的 vm heapsize 作了硬性限制,当 java 进程申请的 java 空间超过阈值时,就会抛出OOM异常(这个阈值可以是48 M、24 M、16 M等,视机型而定),可以通过adb shell getprop 或者 grep dalvik.vm.heapgrowthlimit 查看此值。

也就是说,程序发生 OMM 并不表示 RAM 不足,而是因为程序申请的 java heap 对象超过了 dalvik vm heapgrowthlimit。也就是说,在 RAM 充足的情况下,也可能发生 OOM 。

这样的设计似乎有些不合理,但是 Google 为什么这样做呢?这样设计的目的是为了让 Android 系统能同时让比较多的进程常驻内存,这样程序启动时就不用每次都重新加载到内存,能够给用户更快的响应。迫使每个应用程序使用较小的内存,移动设备非常有限的RAM就能使比较多的app常驻其中。

进程内存空间和 RAM 之间的关系

进程的内存空间只是虚拟内存(或者叫作逻辑内存),而程序的运行需要的是实实在在的内存,即物理内存(RAM)。在必要时,操作系统会将程序运行中申请的内存(虚拟内存)映射到RAM,让进程能够使用物理内存。

Android中的进程

native进程:采用C/C++实现,不包含dalvik实例的linux进程,/system/bin/目录下面的程序文件运行后都是以native进程形式存在的。

java进程:实例化了 dalvik 虚拟机实例的 linux 进程,进程的入口 main 函数为 java 函数。dalvik 虚拟机实例的宿主进程是fork()调用创建的 linux 进程,所以每一个 android 上的 java 进程实际上就是一个 linux 进程,只是进程中多了一个 dalvik 虚拟机实例。因此,java 进程的内存分配比 native 进程复杂。Android 系统中的应用程序基本都是 java 进程,如桌面、电话、联系人、状态栏等等。

解释一些字段的意思:

  • VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
  • RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存)

  • PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
  • USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)

一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

Android中进程的堆内存

进程空间中的heap空间是我们需要重点关注的,heap空间完全由程序员控制,我们使用的malloc、C++ new 和 java new所申请的空间都是heap空间, C/C++ 申请的内存空间在 native heap 中,而 java 申请的内存空间则在 dalvik heap中。

Android如何应对RAM不足

java 程序发生 OMM 并不是表示 RAM 不足,如果 RAM 真的不足,会发生什么呢?这时 Android 的 memory killer 会起作用,当 RAM 所剩不多时,memory killer 会杀死一些优先级比较低的进程来释放物理内存,让高优先级程序得到更多的内存。

应用程序如何绕过dalvikvm heapsize的限制

创建子进程

创建一个新的进程,那么我们就可以把一些对象分配到新进程的heap上了,从而达到一个应用程序使用更多的内存的目的,当然,创建子进程会增加系统开销,而且并不是所有应用程序都适合这样做,视需求而定。

使用jni在native heap上申请空间

native heap的增长并不受dalvik vm heapsize的限制,只要RAM有剩余空间,程序员可以一直在native heap上申请空间,当然如果 RAM快耗尽,memory killer会杀进程释放RAM。大家使用一些软件时,有时候会闪退,就可能是软件在native层申请了比较多的内存导致的。

相关推荐

深入浅出腾讯云CDN:缓存篇

缓存系统在游戏业务中的特异性

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

王浩的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java面试通关手册

后端程序员必备的Linux基础知识

我自己总结的Java学习的系统知识点以及面试问题,目前已经开源,会一直完善下去,欢迎建议和指导欢迎Star: https://github.com/Snailc...

1612

Apache ZooKeeper vs. etcd3

在实现分布式服务协调方案时,有许多出色的系统,如 Apache ZooKeeper,etcd,consul 和 Hazelcast。如果您还没有听说过分布式协调...

4432
来自专栏Linyb极客之路

分布式定时任务调度框架之elastic-job简介

4493
来自专栏程序员的知识天地

Linux 系统结构详解

内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。部分层次结构如图1-...

2762
来自专栏信安之路

web应用渗透测试流程

对于web应用的渗透测试,一般分为三个阶段:信息收集、漏洞发现以及漏洞利用。下面我们就分别谈谈每个阶段需要做的事情。

990
来自专栏编程之旅

HTTP API 设计指南HTTP API 设计指南

这篇指南介绍描述了 HTTP+JSON API 的一种设计模式,最初摘录整理自 Heroku 平台的 API 设计指引 Heroku 平台 API 指引。

912
来自专栏python3

习题1:第一个程序

743
来自专栏java一日一条

Maven 扫盲(上)

写这个maven的入门篇是因为之前在一个开发者会的动手实验中发现挺多人对于maven不是那么了解,所以就有了这个想法。这个入门篇分上下两篇。本文着重动手,用ma...

772
来自专栏java一日一条

Maven 扫盲(上)

写这个maven的入门篇是因为之前在一个开发者会的动手实验中发现挺多人对于maven不是那么了解,所以就有了这个想法。这个入门篇分上下两篇。本文着重动手,用ma...

611
来自专栏*坤的Blog

Word文件乱码XML

1524

扫码关注云+社区