android 优化

内存优化:

 App性能测试和分析工具:

  

一、Android内存分配回收机制

参考Android 操作系统的内存回收机制,这里简单做下总结:

从宏观角度上来看Android系统可以分为三个层次

  1. Application Framework,

  2. Dalvik 虚拟机

  3. Linux内核。

这三个层次都有各自内存相关工作:

1. Application Framework

Anroid基于进程中运行的组件及其状态规定了默认的五个回收优先级:

  • Empty process(空进程)

  • Background process(后台进程)

  • Service process(服务进程)

  • Visible process(可见进程)

  • Foreground process(前台进程)

系统需要进行内存回收时最先回收空进程,然后是后台进程,以此类推最后才会回收前台进程(一般情况下前台进程就是与用户交互的进程了,如果连前台进程都需要回收那么此时系统几乎不可用了)。

由此也衍生了很多进程保活的方法(提高优先级,互相唤醒,native保活等等),出现了国内各种全家桶,甚至各种杀不死的进程。

Android中由ActivityManagerService 集中管理所有进程的内存资源分配。

2. Linux内核

参考QCon大会上阿里巴巴的Android内存优化分享,这里最简单的理解就是ActivityManagerService会对所有进程进行评分(存放在变量adj中),然后再讲这个评分更新到内核,由内核去完成真正的内存回收(lowmemorykillerOom_killer)。这里只是大概的流程,中间过程还是很复杂的,有兴趣的同学可以一起研究,代码在系统源码ActivityManagerService.java中。

3. Dalvik虚拟机

Android进程的内存管理分析,对Android中进程内存的管理做了分析。

Android中有Native Heap和Dalvik Heap。Android的Native Heap言理论上可分配的空间取决了硬件RAM,而对于每个进程的Dalvik Heap都是有大小限制的,

具体策略可以看看 android dalvik heap 浅析

Android App为什么会OOM呢?其实就是申请的内存超过了Dalvik Heap的最大值。这里也诞生了一些比较”黑科技”的内存优化方案,比如将耗内存的操作放到Native层,或者使用分进程的方式突破每个进程的Dalvik Heap内存限制。

Android Dalvik Heap与原生Java一样,将堆的内存空间分为三个区域,Young Generation(新生代),Old Generation(老一代), Permanent Generation(持久代)。

这就涉及到垃圾回收:

垃圾回收(GC) 

垃圾回收器中有一个进程来做上面的这些事情, 这个进程查找我们的对象引用的关系并释放其内存, 这个进程就是garbage collection(垃圾回收), 也就是我们常说的GC.

垃圾回收器有三大职责:

  1. 分配内存;
  2. 确保任何被引用的对象保留在内存中;
  3. 回收不能通过引用关系找到的对象的内存.

Heap和Stack

  • Heap内存是指java运行环境用来分配给对象和JRE类的内存. 是应用的内存空间.
  • Stack内存是相对于线程Thread而言的, 它保存线程中方法中短期存在的变量值和对Heap中对象的引用等.
  • Stack内存, 顾名思义, 是类Stack方式, 总是后进先出(LIFO)的.
  • 我们通常说的GC的针对Heap内存的. 因为Stack内存相当于是随用随销的.

回收

     1)三种经典垃圾回收算法

     2)标记清除算法

     2)复制算法

     3)标记整理算法

     4)分代收集算法

     5)七种垃圾收集器

1、对象是否可以被回收有两种经典算法:

 (1)引用计数法(垃圾收集器中的早期策略),缺陷:很难解决对象之间互相循环引用的问题。

       通过判断对象的引用数量来决定对象是否可以被回收。

       当一个对象被创建时,且将该对象实例分配给一个引用变量,该对象实例的引用计数设置为1。

       当任何其它变量被赋值为这个对象的引用时,对象实例的引用加1.(a = b,  则b引用的对象实例的的计数器加1)

       当一个对象实例被垃圾收集时,它引用的任何对象实例的引用计数器均减1。

       任何引用计数为0的对象实例可以被当做垃圾收集。

 (2)可达性分析算法

       通过判断对象的引用链是否可达来决定对象是否可以被回收。

       名为”GC Root“ 的对象作为起始点,从这些点开始向下搜索,搜索的所经过的路径,叫引用链。

       如果一个对象到GC Root都没有任何引用链(GC Root 到 这个对象不可达),则证明此对象不可用,可回收。

  在java中,可作为GC Root 的对象

    1)虚拟机栈(栈帧中的局部变量中)中引用的对象。

    2)方法区中类静态属性引用的对象。

    3)方法区中常量应用的对象。

    4)本地方法栈中Native方法引用的对象。

 

  5)System Class 系统Class Loader加载的类. 例如java运行环境中rt.jar中类, 比如java.util.* package中的类.

  6)Thread 运行中的线程

  7)JNI 中的本地/全局变量, 用户自定义的JNI代码或是JVM内部的.

  8)Busy Monitor 任何调用了wait()或notify()方法, 或是同步化的(synchronized)的东西. 可以理解为同步监控器.

  9)Java本地实例, 还在运行的Thread的stack中的方法创建的对象.

 

2、堆的新生代、老年代、永久代的垃圾回收时机,MinorGC 和 FullGC

 

JVM 由于执行GC而停止了应用程序的执行,并且这种情形会在任何一种GC算法中发生。

 

小GC执行非常频繁, 而且速度特别快.

 

大GC一般会比小GC慢十倍以上.

 

大小GC都会发出"Stop the World"事件, 也就是说中断程序运行, 直至GC完成. 这也是我们在 App优化之消除卡顿 中为什么说频繁GC会造成用户感知卡顿.

 

当GC发生时,除了GC所需的线程以外,所有线程都处于等待状态,直到GC任务完成。

 

GC优化,很多时候就是减少GC过程发生的时间:

GC时会导致线程暂停,导致卡顿,Google在新版本的Android中优化了这个问题, 在ART中对GC过程做了优化揭秘 ART 细节 —— Garbage collection,据说内存分配的效率提高了10倍,GC的效率提高了2-3倍(可见原来效率有多低),不过主要还是优化中断和阻塞的时间,频繁的GC还是会导致卡顿。

回过头来看,现在各种手机厂商鼓吹人工智能手机,号称18个月不卡顿,越用越快,其实很大一部分Android系统的内存优化有关,无非就是利用一些比较成熟的基于统计,机器学习的算法定时清理数据,清理内存,甚至提前加载数据到内存。

 

JVM使用分代式的内存管理方式, 将Heap分成三代 --- 新生代, 老一代, 持久代.

  • Young Generation

    • 新生代.
    • new出来的对象.
    • 该区域的内存管理使用minor garbage collection(小GC).
    • 更进一步分成Eden space, Survivor 0 和 Survivor 1 三个部分.
  • Old Generation

    • 老年区.
    • 新生代中执行小粒度的GC幸存下来的"老"对象.
    • 该区域的内存管理使用major garbage collection(大GC).
  • Permanent Generation

    • 持久代.
    • 包含应用的类/方法信息, 以及JRE库的类和方法信息.

GC 流程

1. 创建新的对象

每当我们使用new创建一个对象时, 这个对象会被分配到新生代的Eden区域

当new出来的对象的空间大于虚拟机中-XX:PretenureSizeThreshold参数时(即所谓的大对象)会直接放入老年代,而不会放入新生代

2. 当Eden区域满时
当Eden区域内存被分配完时, 小GC程序被触发:

引用可达的对象会移到Survivor(幸存者)区域--S0, 然后清空Eden区域, 此时引用不可达的对象会直接删除, 内存回收.

3. Eden再次满时
当Eden区域再次分配完后, 小GC执行, 引用可达的对象会移到Survivor(幸存者)区域, 而引用不可达的对象会跟随Eden的清空而删除回收.

需要注意的是, 这次引用可达的对象移动到的是S1的幸存者区.
而且, S0区域也会执行小GC, 将其中还引用可达的对象移动到S1区, 且年龄+1. 然后清空S0, 回收其中引用不可达的对象.

此时, 所有引用可达的对象都在S1区, 且S1区的对象存在不同的年龄.

4. 当Survivor区的对象年龄达到"老年线"时
上面1~3循环, Survivor区的对象年龄也会持续增长, 当其中某些对象年龄达到"老年线", 例如8岁时, 它们会"晋升"到老年区.

 

Android 图片优化

Androi 布局性能优化

Android 电量测试以及电量优化

Android 性能优化之使用Lint

Android 内存泄漏解决

Android 内存优化以及内存泄漏分析工具

BlockCanary 一个轻量的,非侵入式的性能监控组件(阿里)

Android 应用内存优化 之 onLowMemory & onTrimMemory

c++ 随机数,在一些android机型的cpu上,会崩毁。

posted @ 2018-07-13 15:38  晕菜一员  阅读(259)  评论(0)    收藏  举报