调皮的内存抖动?前生今世及App解决卡顿慢

内存抖动

·内存抖动是指内存频繁地分配和回收,而频繁的gc会致使卡顿,严重时和内存泄漏同样会致使OOM。android

注意内存抖动为何会形成OOM这关系到Java的垃圾回收。算法

形成的缘由

主要是频繁(很重要)在循环里建立对象数组

  • 一、致使大量对象在短期内被建立,因为新对象是要占用内存空间的并且是频繁,若是一次或者两次在循环里建立对象对内存影响不大,不会形成严重内存抖动这样能够接受也不可避免缓存

  • 二、频繁的话就很内存抖动很严重性能优化

简单的提一下垃圾回收机制

垃圾回收微信

在对对象进行回收前须要对垃圾进行采集,不一样的虚拟机实现可能使用不一样的垃圾收集算法,不一样的收集算法的实现也不尽相同。不一样的算法各有各的优劣势。app

经常使用的收集算法有:

一、标记-清除算法 Mark-Sweepjvm

和他的名字同样,算法分为标记和清除两个阶段:首先标记出全部须要回收的对象,在标记完成后统一回收被标记的对象。函数

二、复制算法 Copying工具

“复制”(Copying)的收集算法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另一块上面,而后再把已使用过的内存空间一次清理掉。

三、标记压缩算法 Mark-Compact

内存抖动为何会形成 OOM?

首先咱们要了解一些垃圾回收机制的来龙去脉

在对对象进行回收前须要对垃圾进行采集,不一样的虚拟机实现可能使用不一样的垃圾收集算法,不一样的收集算法的实现也不尽相同。不一样的算法各有各的优劣势。

经常使用的收集算法有:

一、标记-清除算法 Mark-Sweep 二、复制算法 Copying 三、标记压缩算法 Mark-Compact

不管是通常的JVM仍是DVM,不会只使用一种垃圾收集算法。它会根据内存的划分实现不一样的收集算法。

当前商业虚拟机的垃圾收集都采用分代收集算法。分代的垃圾回收策略,是基于不一样的对象的生命周期是不同的。所以,不一样生命周期的对象能够采起不一样的收集方式,以便提升回收效率。

在Java程序运行的过程当中,会产生大量的对象,因每一个对象所能承担的职责不一样所具备的功能不一样因此也有着不同的生命周期,有的对象生命周期较长,好比Android中的Application、启动的Service等;有的对象生命周期较短,好比一些函数内部new出来的String对象。

在不进行对象存活时间区分的状况下,每次垃圾回收都是对整个堆空间进行回收,那么消耗的时间相对会很长,并且对于存活时间较长的对象进行的扫描工做等都是徒劳。所以就须要引入分治的思想,所谓分治的思想就是因地制宜,将对象进行代的划分,把不一样生命周期的对象放在不一样的代上使用不一样的垃圾回收方式。

如今主流的作法是将Java堆被分为

  • 一、新生代
  • 二、老年代;

新生代又被进一步划分为Eden和Survivor区, Survivor由From Space和To Space组成

这样划分的好处是为了更快的回收内存,根据不一样的分代执行不一样的回收算法;

Android 虚拟机的由来

Java 虚拟机是一个规范,任何实现该规范的虚拟机均可以用来执行 Java 代码。android就是以为如今使用的jvm用着不爽,因为 Androd 运行在移动设备上,内存以及电量等诸多方面跟通常的 PC 设备都有本质的区别 ,通常的 JVM 无法知足移动设备的要求,因此本身根据这个规范开发了一个Dalvik 虚拟机。

Dalvik虚拟机主要使用标记清除算法,也能够选择使用拷贝算法。这取决于编译时期:

ART 是在 Android 4.4 中引入的一个开发者选项,也是 Android 5.0 及更高版本的默认 Android 运行时。google已再也不继续维护和提供 Dalvik 运行时,如今 ART 采用了其字节码格式。

ART 有多个不一样的 GC 方案,这些方案包括运行不一样垃圾回收器。默认方案是 CMS。
复制代码

这就是内存抖动为何会形成 Android App OOM。

检测优化内存抖动

内存抖动在Android Profile中表现为:

内存抖动在Android Profile中表现

关于内存抖动和内存泄漏就到这里了,接下来就说一下Android studio 提供的内存优化方面的工具

**一、利用Alloctions Tracker来进行排查。**前提AndroidStudio版本>=3.0, 在Android Studio中点击memory profiler中的红点录制一段时间的内存申请状况,再点击结束。 Android Studio提供了工具来帮助开发者发现和解决内存抖动和内存泄漏。

二、 Tool - Memory Monitor(用于发现内存抖动及内存泄漏的)

Android Studio中的Memory Monitor能够很好的帮组咱们查看程序的内存使用状况。 Memory Monitor:查看整个app所占用的内存,以及发生GC的时刻,短期内发生大量的GC操做是一个危险的信号(用于发现有没有内存泄漏和严重内存抖动)。

(后面两个是用于定位的内存抖动和内存泄漏发生的具体位置·) Allocation Tracker:使用此工具来追踪内存的分配,前面有提到过。

Heap Tool:查看当前内存快照,便于对比分析哪些对象有多是泄漏了的.

举个栗子

你须要避免在for循环里面分配对象占用内存,须要尝试把对象的建立移到循环体以外,自定义View中的onDraw方法也须要引发注意,每次屏幕发生绘制以及动画执行过程当中,onDraw方法都会被调用到,避免在onDraw方法里面执行复杂的操做,避免建立对象。对于那些没法避免须要建立对象的状况,咱们能够考虑对象池模型,经过对象池来解决频繁建立与销毁的问题,可是这里须要注意结束使用以后,须要手动释放对象池中的对象。

下面是避免发生内存抖动的几点建议:

  • 尽可能避免在循环体或者频繁调用的函数内建立对象,应该把对象建立移到循环体外。
  • 注意自定义View的onDraw()方法会被频繁调用,因此在这里面不该该频繁的建立对象。
  • 当须要大量使用Bitmap的时候,试着把它们缓存在数组中实现复用。
  • 对于可以复用的对象,同理可使用对象池将它们缓存起来。

更多阅读

Android性能优化 (1)—— 内存溢出和内存泄漏的介绍

浅谈App的性能优化

Android性能优化之包体压缩,一篇文章教你玩转优化App

BlockCannery-一个强大的Android程序调试工具,轻松帮你找出卡顿

相信本身,没有作不到的,只有想不到的

微信公众号:终端研发部

技术
相关文章
相关标签/搜索