- 什么是内存抖动
- 内存抖动的影响
- 引起内存抖动的原因
- 如何发现内存抖动
- 内存抖动常见的解决方式
Android 是基于 Java ,不管是刚刚接触 Android 的新手,还是混迹在开发前线的老手,都知道在 Android上面的开发,不用管内存的回收,需要对象的时候 new 出来就好了,其余的 GC 会帮助我们,但是 GC 也不是万能的,GC 机制帮助我们的同时,也会限制我们,俗话说有得有失嘛。今天来看一下由于这种机制给我们带来的第一个坑,内存抖动。
什么是内存抖动
内存回收是指在程序需要对象的时候,在堆当中分配出来一块空间,使用完毕以后,由 GC 帮我们清理掉这片内存空间。如果频繁的一直持续上述操作,就会引起内存抖动。也就是有源源不断的对象被创建,同时又有源源不断的对象被回收。
内存抖动的影响
- 导致程序卡顿
- 导致程序内存溢出
出现上述情况的内存抖动,会对程序造成什么影响呢,首先我们知道 GC 回收的时候也是需要消耗资源的,比如 GC 回收的时候会停止掉所有的线程,如果触发一次 GC 就停止一次,那如果多次频繁的触发 GC 线程也会一卡一卡的,所以总的来说内存抖动可能会造成程序的卡顿。
如果发生频繁的 GC 会导致出现不连续的内存片无法进行分配,导致 OOM 内存溢出。
注意:Android 垃圾回收机制使用的是 CMS 垃圾回收器 (采用标记 - 清理算法)
引起内存抖动的原因
内存抖动出现原因主要是频繁在循环里创建对象,导致大量对象在短时间内被创建,由于新对象是要占用内存空间的而且是频繁,如果一次或者两次在循环里创建对象对内存影响不大,不会造成严重内存抖动这样可以接受也不可避免,频繁的话就很内存抖动很严重。
如何发现内存抖动
首先我们先来看一个简单的 Demo
我们知道 Java 当中的字符串对象是不可变的,如果累加的话。会将原来的 Copy 出来一份。然后进行累加成为新的字符串,原来的就会被回收掉,现在我们就利用这个特性来模拟一个简单的内存抖动现象
1 |
|
这样必然会出现内存抖动,我们通过 AS 自带的工具观察一下内存的使用情况,如下所示:
有小白色的垃圾桶,说明触发了 GC ,有一个代表出发了一次 GC ,上图有多个,然后我们选定一个时刻,仔细的看一下对象,例如下图
可以看到对象最多便是char数组,和 String 类型,然后点击 String,随便选取一个实例,查看他的堆栈,双击 便可以定位到我们的代码当中,然后结合详细的代码,进行分析,便可以规避上述的问题。
内存泄漏常见的解决方式
- 尽量避免在循环体内创建对象,应该把对象创建移到循环体外。
- 注意自定义View的onDraw()方法会被频繁调用,所以在这里面不应该频繁的创建对象。
- 当需要大量使用Bitmap的时候,试着把它们缓存在数组中实现复用。
- 对于能够复用的对象,同理可以使用对象池将它们缓存起来。
参考文献:
https://www.cnblogs.com/xgjblog/p/9042458.html
https://blog.csdn.net/wanghao200906/article/details/79311288
https://blog.csdn.net/nicolelili1/article/details/89219191
https://blog.csdn.net/qq_31370269/article/details/52818277
https://blog.csdn.net/wanghao200906/article/details/79311288
https://www.youtube.com/watch?v=McAvq5SkeTk