大厂架构师经验分享!Android-性能优化最佳实践( 三 )


本来GC的诞生是为了让java程序员更加轻松(这一点隔壁C++痛苦的一匹),java虚拟机会自动帮助我们回收那些不再需要的内存空间 。通过引用计数法,可达性分析法等等方法,确认该对象是否没有引用,是否可以被回收 。
有人会说真么强悍的功能看起来无懈可击啊,对,理论上可以达到消除内存泄漏,但是很多人不按常理出牌啊,往往很多时候,有的对象还保持着引用,但逻辑上已经不会再用到 。就是这一类对象,游走于GC法律的边缘,我没用了,但是你又不知道我没用了,就是这么赖着不走,空耗内存 。
因为有内存泄漏,所以内存被占用越来越多,那么GC会更容易被触发,GC会越来越频发,但是当GC的时候所有的线程都是暂停状态的,需要处理的对象数量越多耗时越长,所以这也会造成卡顿 。
那么什么情况下会出现这样的对象呢? 基本可以分为以下四大类: 1、集合类泄漏 2、单例/静态变量造成的内存泄漏 3、匿名内部类/非静态内部类 4、资源未关闭造成的内存泄漏
1、集合类泄漏
集合类添加元素后,仍引用着集合元素对象,导致该集合中的元素对象无法被回收,从而导致内存泄露 。
举个栗子:
static List mList = new ArrayList<>();for (int i = 0; i < 100; i++) {Object obj = new Object();mList.add(obj);obj = null;}
当mList没用的时候,我们如果不做处理的话,这就是典型的占着茅坑不拉屎,mList内部持有者众多集合元素的对象,不泄露天理难容啊 。解决这个问题也超级简单 。把mList清理掉,然后把它的引用也给释放掉 。
mList.clear();mList = null;
2、单例/静态变量造成的内存泄漏
单例模式具有其 静态特性,它的生命周期 等于应用程序的生命周期,正是因为这一点,往往很容易造成内存泄漏 。先来一个小栗子:
【大厂架构师经验分享!Android-性能优化最佳实践】public class SingleInstance {private static SingleInstance mInstance;privat