大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢

转载请标明出处(http://blog.csdn.net/kifile),再次感谢

原文地址: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 和client之间使用相同的内存

因为公用内存的使用,我们须要关心你的应用须要使用多少内存。

怎样正确分析应用内存使用请參看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怎样管理内存的更多相关文章

  1. Android性能优化第(二)篇---Memory Monitor检测内存泄露

    上篇说了一些性能优化的理论部分,主要是回顾一下,有了理论,小平同志又讲了,实践是检验真理的唯一标准,对于内存泄露的问题,现在通过Android Studio自带工具Memory Monitor 检测出 ...

  2. [Android 性能优化系列]内存之提升篇--应用应该怎样管理内存

    大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地 ...

  3. Android性能优化系列之apk瘦身

    Android性能优化系列之布局优化 Android性能优化系列之内存优化 为什么APK要瘦身.APK越大,在下载安装过程中.他们耗费的流量会越多,安装等待时间也会越长:对于产品本身,意味着下载转化率 ...

  4. Android性能优化系列之App启动优化

    Android性能优化系列之布局优化 Android性能优化系列之内存优化 Android性能优化系列之apk瘦身 应用的启动速度缓慢是我们在开发过程中常常会遇到的问题,比方启动缓慢导致的黑屏.白屏问 ...

  5. [Android 性能优化系列]降低你的界面布局层次结构的一部分

    大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地 ...

  6. Android性能优化第(三)篇---MAT比Menmery Monitor更强大

    作者 LooperJing 2016.11.17 16:42* 字数 1687 阅读 1603评论 3喜欢 21 在Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GC ...

  7. Android性能优化系列 + Android官方培训课程中文版

    Android性能优化典范 - 第6季 http://hukai.me/android-performance-patterns-season-6/   Android性能优化典范 - 第5季 htt ...

  8. Android性能优化第(一)篇---基本概念

    最近打算总结几篇app性能优化方面的东西,毕竟android弄了这么久,万一到哪些转了行,岁月久了就忘记了,纯粹当个人笔记.今个是第一篇---性能优化的基本概念,毛主席说了,让理论先行,理论指导实践. ...

  9. Android性能优化系列之电量优化

    电量消耗的计算与统计是一件麻烦而且矛盾的事情,记录电量消耗本身也是一个费电量的事情,随着Android开的性能要求越来越高,电量的优化,也显得格外重要,一个耗电的应用,用户肯定会毫不犹豫的进行卸载,所 ...

随机推荐

  1. SqlServer执行存储过程时,参数值为null,sql语句参数值变成default

    从C#代码里传入参数到调用存储过程,参数的值为null,执行存储过程一直提示需要参数 '@xxx',但未提供该参数.通过profiler发现生成的参数值变成为default. 解决方案:1.将Para ...

  2. [转]C#使用Window图片查看器打开图片

    //建立新的系统进程 System.Diagnostics.Process process = new System.Diagnostics.Process(); //设置文件名,此处为图片的真实路径 ...

  3. javascript中对象属性的介绍

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 关于生sql中的空值

    在数据库中的空值无非就是两种形式的表示 一种是什么都没有,一种是以NuLL显示的 , 那么在C# 读取出来怎么判断呢, DtStatus.Rows[0]["FetchCode"]. ...

  5. shell学习第二弹-进阶

    1.linux系统中配置文件执行顺序 1)用户登录系统,首页调用/etc/profile文件初始化所有bash用户的默认特征 2)然后shell依次查找~/.bash_profile,~/.bash_ ...

  6. Linux学习笔记(Redhat)

    一.开始 linux平台上的开发 vi.gcc.gdb.make.jdk.tomcat.mysql. linux基本操作 c语言功底<c专家编程>和java语言 学习unix高级编程 &l ...

  7. java函数式编程之lambda表达式

    作为比较老牌的面向对象的编程语言java,在对函数式编程的支持上一直不温不火. 认为面向对象式编程就应该纯粹的面向对象,于是经常看到这样的写法:如果你想写一个方法,那么就必须把它放到一个类里面,然后n ...

  8. Js判断一个字符串是否包含一个子串

    Js中经常遇到判断一个字符串是否包含一个子串,java语言中有containes的方法,直接调用就可以了.除非引用第三方数据库,Js中没有contains方法. 为了实现更java语言中contain ...

  9. WPF 利用RichTextBox 打印出不同颜色的文本

    using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows ...

  10. shell中的交互模式:expect

    在shell开发中,我们连接FTP或者passwd或sudo等操作时,需要手动输入密码.对于自动化而言,这显然是不合适的.而expect的强交互模式解决了这个问题.工作中偶有涉及到这个,个人也是简单的 ...