@Awille
2021-10-19T15:04:45.000000Z
字数 1436
阅读 157
Android 内存优化
Android 内存优化
1、优化前言-Dalvik与ART
1.1、DVM与JVM的区别
- JVM基于栈,这样数据处理伴随着大量的出入栈操作,对于性能有限的移动设备是不适合的,而DVM是基于寄存器的,指令更少,更快。
- JVM执行.class, DVM执行.dex文件 dx工具将将多个class文件整合程一个dex文件,去除了一些冗余信息,减少了IO操作,加快了类的查找速度。
- DVM允许存在多个进程
- DVM由zygote创建
1.2、ART与DVM的区别
- ART在系统安装应用程序时进行一次预编译 AOT ahead of time compilation,将字节码预先编译成机器码存储在本地。 缺点,因为有了AOT安装事件变长,二、存储机器码空间变大。 为了优化上述问题,7.0后引入了JIT Just in time compiler,在运行中对热点代码进行编译,从而节省应用安装时间与存储空间。
- DVM只支持32位CPU,而ART支持64位
2、绘制优化
2.1 Hierarchy Viewer
- Windows 当前所有界面列表
- Tree View:当前Activity的所有View的层次按照高层到底层从右到做闲事出来
- Tree Overview:全局概览
- Layout View:整体布局
选择一个view还可以看到一个 View的耗时
2.2、布局优化方法
- 合理运用布局减少层级嵌套
- 使用include标签进行布局复用
- 使用merge标签去除多余层级
- 使用ViewStub提高加载速度
- 使用View 的GONE和INVISIBLE属性,这种方法效率不高,虽然达到了隐藏的目的,但是仍在布局当中,系统仍然会解析它们,可以用ViewStub来解决这一问题。ViewStub是轻量级的View,不可见并且不占布局位置。当ViewStub调用inflate 方法或者设置可见时,系统会加载ViewStub指定的布局,然后将这个布局添加到ViewStub中,在对ViewStub调用inflate方法或者设置可见之前,它是不占布局空间和系统资源的,它主要的目的就是为目标视图占用一个位置。因此,使用ViewStub可以提高界面初始化的性能,从而提高界面的加载速度
2.3、避免GPU过度绘制
- 在XML布局中,控件有重叠并且都设置北京
- View的onDraw在同一区域绘制多次
避免过度配置方法:
* 移除不需要的backgroud
* 在vieww的ondraw方法中,用canvas.clipRect来指定绘制的区域,放置重叠的组件发生过度绘制。
3、内存优化
3.1、内存泄漏场景
- 非静态内部类的静态实例
- 多线程相关的匿名内部类/非静态内部类
- Handler内存泄漏。Handler的Message被存储在MessageQueue中,有些Message并不能马上被处理,它们在MessageQueue中存在的时间会很长,这就会导致Handler无法被回收。如果Handler是非静态的,则Handler也会导致引用它的Activity或者Service不能被回收。Handler是非静态的匿名内部类的实例,它会隐性引用外部类HandlerActivity。上面的例子就是当我们点击Button 时,HandlerActivity会结束,但是Handler 中的消息还没有被处理,因此HandlerActivity无法被回收。解决方案有两个,一个是使用一个静态的Handler内部类,Handler持有的对象要使用弱引用
3.2、MAT
3.3、Leak Canary