原文地址:http://developer.android.com/training/articles/memory.html
在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家
下面是本次的正文:
################
随机访问存储器(Ram) 不管在哪种软件开发环境中都是一种极其宝贵的资源,而在移动开发平台下,极其有限的物理内存则更为宝贵。因此,虽然Android的Dalvik虚拟机会执行垃圾回收,但这不代表你可以对你应用的内存分配和释放不闻不问。
为了使垃圾回收期能够回收你应用中的内存,你需要避免内存泄露(通常是由于在全局变量持有某个对象引起的),以及在适当的时候释放点引用对象(比如在生命周期中)。对于大多数应用而言,Dalvik虚拟机的垃圾回收器会帮你回收掉那些不再处于作用域中的对象的内存。
本文将介绍 Android 是如何管理内存进程以及内存分配,以及如何在开发过程中减少内存使用。如果对于 Java 的清理资源机制,你还希望了解的更多,那么你可以去看看一些关于资源引用的书籍或者在线文档。如果你正在寻找如何分析当前应用内存使用的资料,那么你可以参考这篇文章(Investingating Your RAM Usage)。
Android 如何管理内存
Android 虽然没有提供内存的交换空间,但是他使用了分页和内存映射文件来管理内存。这代表任何你修改过的内存,不论是分配了一个新的对象,再或者是更改了内存映射夜的操作,都将在保留在内存,以至于不能被释放。从你的应用中释放这些内存唯一的方法就是将使用的对象释放,使得垃圾回收机制能够能够回收他。唯一的例外是,对于那些没有被更改的数据,例如代码,当系统希望在别的地方使用他的时候,就被系统调用到哪里。
公有内存
Android 为了在RAM中能够存放尽量多的资源,因此他允许某些共有内存跨进程使用。他的原理如下:
1.每一个应用进程都是被一个叫做 Zygote 的进程负责出来的。Zygote 进程是在系统启动的时候自动启动的,并且内部加载了很多公用框架代码以及资源(例如 Activity 主题等)。启动一个新应用的时候,系统从 Zygote 进程中复制这些资源,然后在新进程中运行应用代码。这就允许框架和资源中的大量内存资源被跨进程复用。
2.大多数静态数据是通过内存映射放置到进程中。这不仅代表着同样的数据能够被跨进程分享,同样代表着当需要的时候能够随时被调用。举个例子,静态数据包括:Dalvik 码(使用预编译的.odex来直接调用),应用资源(国通简历资源映射表来调用),以及一些默认的项目资源,例如在.so 文件中的本地代码
3.在很多地方,Android 都会通过直接分配内存区域来跨进程分享同样的动态 RAM。例如,窗口 Surface 使用公用内存在应用和屏幕排序,Cursor 缓存在 ContentProvider 和客户端之间使用同样的内存
由于公用内存的使用,我们需要关心你的应用需要使用多少内存。 如何正确分析应用内存使用请参看Investingating Your RAM Usage。
分配和释放应用内存
以下是关于 Android 如何分配和释放内存的部分:
1.每个进程的Dalvik 堆会被限制在一个虚拟内存范围内。这代表着逻辑堆的大小可以随着他的需要而增长(当然系统会限制每个应用的最大内存占用)
2.每个堆的逻辑大小和堆使用的物理内存并不是一样。当检查应用的堆的时候,Android 会计算一个叫做比例大小(PPS)的值,这会将与其他应用共享的脏数据和清洁数据都计算在内,你的PPS的总值将被系统认为是物理内存的值。更详细的信息请查看Investingating Your RAM Usage。
3.Dalvik堆并不会压缩堆的逻辑尺寸,这代表着Android并不会通过清理空间来减小堆得大小。Android只在堆没有剩余空间的时候才对堆本身采取回收措施。但这并不代表被堆使用的物理内存可以得到释放。在垃圾回收之后,Dalvik会扫描堆来找到不用的内存页,并通过madvise将这些内存页释放到内核空间。因此大批量的分配或者释放对象将会回收使用过的物理内存。尽管如此,从那些小的资源中回收内存空间效果并不是很好,因为存放这些小资源的分页,很可能被其他对象所使用,导致不能释放。
限制应用内存
Android为了保证自身的多任务环境,他为每一个应用设置了堆的硬件限制。这个限制取决于设备拥有多少RAM。如果你的应用已经达到了堆的上限,并且还希望分配更多的内存空间,那么就会导致OOM。
在某种条件下,你或许希望知道在当前设备上系统最大允许的堆空间,打个比方说用来决定缓存的大小。那么你可以通过查询getMemoryClass()来获取到这些系统数据,他会将你应用可用的内存作为一个int类型的值进行返回,这将会在下面被讨论。
切换应用
当用户在应用之间进行切换时,Android使用近期最少使用算法(LRU)将进程保存在一个前台应用组件列表中,而非存放在交换空间。比如说当用户首次启动一个应用的时候,该应用的进程就会被创建,但是当用户离开这个应用的时候,应用却没有完全退出。系统将保存进程的缓存,这样一来当用户接下来返回到当前应用的时候,这个缓存就可以被尽可能快的调用,以提升进入程序的速度。
如果你的应用有一个缓存的进程,并且他保持了他所需要的内存,那么即使在用户没有使用到他的时候,也会限制系统的整体性能。因此当系统内存资源不足的时候,他就可能会杀死那些最近没有被使用到的进程。所以为了使自己进程能够尽可能的保持,最好跟着下面的章节学习,将自己的资源进行释放
如果希望了解更多关于进程在非前台环境下是如何被缓存,以及Android如何决定哪个进程被杀死的信息,那么请参看进程与线程
接下来,可以看看应用是如何管理自己的内存的
Android内存之基础篇--Android如何管理内存 -[Android 性能优化系列]
相关推荐
### Android内核基础 Android内核是基于Linux内核的一个分支,具体而言,它基于Linux 2.6内核(当前版本为2.6.31),这一选择主要是为了利用Linux内核的强大功能和稳定性,同时进行必要的修改以适应Android平台设备...
本篇文章将深入探讨"Android SDK (SDK Platforms)-android-20.zip"这一特定版本的SDK,旨在为开发者提供详尽的了解和使用指导。 "android-20"指的是Android 4.2.2(API级别20),这是Google在2012年底推出的Android...
本文将深入探讨“Android基础篇-Button学习”中的关键知识点,包括如何通过三种不同的方式绑定监听器,以及如何自定义Button的行为。 首先,我们来看第一种绑定监听器的方式:通过XML属性。在布局文件中,Button...
本篇文章将深入探讨Android应用性能优化的关键点,从理解性能优化的基本原则,到具体的实践技巧,帮助开发者构建更加高效的应用。 #### 高效编码的两大准则 1. **避免不必要的工作**:编写代码时应确保每一行代码...
本篇将深入探讨"android-kotlin-fundamentals-apps"这个开源项目,它是一个专为学习Android Kotlin Fundamentals设计的应用程序集合。这些应用程序涵盖了Kotlin在Android开发中的基本概念和最佳实践,对于初学者和有...
这篇文档旨在为初学者提供一个关于Android内核的概述,同时也为后续深入探讨各个驱动程序打下基础。 首先,Android内核包含了对Android平台特有的硬件和功能的支持。例如,Android Binder驱动是Android进程间通信...
Android安全开发基础--5--四大组件之内容提供器(Content Provider).pdf Android安全开发基础--6--进程间通信机制(IPC).pdf Android安全开发基础--7--JVM Dalvik ART虚拟机.pdf Android安全开发基础--8--Java本地...
总的来说,Android性能优化涉及多个层面,从渲染性能的提升,到减少过度绘制,再到理解和利用VSYNC,以及内存和电量管理,都需要开发者深入理解和实践。通过使用谷歌提供的工具和最佳实践,开发者可以创建出更加高效...
2. **模拟器优化**:macOS用户可以利用HAXM(Intel Hardware Accelerated Execution Manager)来加速Android Emulator的性能,提高模拟器的运行速度。 3. **IntelliJ IDEA或Android Studio集成**:大多数开发者会...
在本节"Android应用开发基础到深入篇-Lesson1_什么是Android(1)"中,我们将探索Android操作系统的基础知识,以及其在移动设备领域的深远影响。这节课由一位经验丰富的讲师引领,他将分享自己的Android开发历程,并...
这篇博客“Android学习09-----Android中数据的存储和访问 (3) By SQLite”深入探讨了如何利用SQLite进行数据管理。 SQLite是一种关系型数据库管理系统,它嵌入到应用程序中,不需要单独的服务或进程来运行。在...
这篇文档将详细介绍“android-sdk_r24.4.1-linux+jdk-8u144-linux-x64.rar”压缩包中的关键知识点,这是一份专门为Android开发准备的工具集合,包含了Android SDK和JDK 1.8的Linux版本。 首先,让我们来看看JDK...
标题和描述中提到的知识点主要包括: 1. Google官方Android开发教程的翻译版本: - 这些教程是根据Google Android开发者官网的Training教程翻译而来,...对于初学者来说,这些知识点是理解和掌握Android开发的基础。
在Android开发中,数组资源是十分重要的组成部分,用于存储和管理数据。本篇文章将深入探讨`string-array`和`integer-array`的用法,以及如何在XML中定义和使用它们。 首先,`string-array`是Android中用于存储字符...
3. **应用程序框架**:提供了一系列服务和API,如活动管理器、内容提供者、广播接收器等,开发者可以利用这些组件构建复杂的应用。 4. **应用程序**:用户可以直接交互的各类应用,如电话、短信、浏览器等,以及...
### Android UI篇——Dialog(对话框) 在Android应用开发中,对话框(Dialog)作为用户交互的重要组成部分之一,被广泛应用于各种场景下,比如提示信息、请求确认操作、登录界面等。本文将深入探讨Android中Dialog的...
在本篇讨论中,我们将聚焦于如何将20140215版本的NTFS-3g移植到Android系统,并探讨其在移动设备上的应用。 首先,NTFS-3g的移植工作涉及到对Android系统的深入理解和对Linux内核的熟悉。Android基于Linux内核,但...
这篇新版的Android开发教程笔记将带你进入Android编程的世界,从最基础的入门概念开始讲解。本文主要围绕以下几个关键知识点展开: 1. **Android SDK(软件开发工具包)**:Android SDK是开发者进行Android应用开发...
[14本经典Android开发教程]-5-linux Android基础知识总结 ------------------------------------------------------- linux ,Android基础知识总结 1. Android编译系统分析 2. 文件系统分析 3. 制作交叉工具链 4. ...
[14本经典Android开发教程]-7...[14本经典Android开发教程]-5-linux Android基础知识总结 http://download.csdn.net/detail/cleopard/8380529 [14本经典Android开发教程]-6-Android驱动开发入门及手机案例开发分析教程 ...