内存抖动
内存抖动是由于短时间内有大量对象进出新生区导致的,内存忽高忽低,有短时间内快速上升和下落的趋势,分析图呈锯齿状。
它伴随着频繁的 GC,GC 会大量占用 UI 线程和 CPU 资源,会导致 APP 整体卡顿(因为 GC 在回收内存时会停止工作线程),甚至有 OOM 的可能(原因:在新生代创建大量对象,而给新生代分配的空间又比较少,所以它就会占用一部分老年代的空间,然后此时有大对象满足了从新时代进入老年代的条件,而老年代里因为空间不够,再加上没有一块连续的空间分配给这个大对象,这时候就会报 OOM 错误)。
内存泄漏
程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费。
判断对象的存活---可达性分析
如果一个对象是根可达,那它就不会被回收;如果是根不可达,那么它就会被回收。 而内存泄漏这是,一个对象满足根可达,但它却不可用了。
内存泄漏的典型案例:一个静态变量引用了一个 Activity,而这个静态变量是全局的,只要 APP 进程没有被杀死,这个静态变量则一直存在。而 Activity 已经执行了生命周期 onDestory(),但是这个 Activity 被静态变量所应用又根可达,那么这个 Activity 就发生了内存泄漏。
内存分析工具
1. Android Profiler
内存性能分析器是 Android Profiler 中的一个组件,可帮助我们识别可能会导致应用卡顿甚至崩溃的内存泄漏和内存抖动。它显示一个应用内存使用量的实时图表,让我们可以
捕获堆转储
强制执行垃圾回收
跟踪内存分配
2. MAT(Memory Analyzer Tool)
内存快照对比,为了更有效率的找出内存泄漏的对象,一般会获取两个堆转储文件(先 dump 一个,隔段时间再 dump 一个),通过对比后的结果可以很方便定位。
优化案例
字符串的拼接每次都会创建一个新的字符串对象,所以尽量使用 StringBuilder 来完成,StringBuilder 内部是操作一个字符数组来完成的。