You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
---
|
|
|
|
内存优化
|
|
|
|
---
|
|
|
|
|
|
|
|
#### 目录
|
|
|
|
|
|
|
|
1. 设备分级
|
|
|
|
2. Bitmap 优化
|
|
|
|
3. 内存泄露
|
|
|
|
|
|
|
|
#### 前言
|
|
|
|
|
|
|
|
内存优化,应该从哪里着手呢?通常会从设备分级、Bitmap 优化和内存泄露这三个方面入手。
|
|
|
|
|
|
|
|
#### 设备分级
|
|
|
|
|
|
|
|
内存优化首先需要根据设备环境来综合考虑。
|
|
|
|
|
|
|
|
- 设备分级
|
|
|
|
|
|
|
|
对于低端机用户可以关闭复杂的动画、或者某些功能;使用 565 格式的图片,使用更小的缓存内存等。在现实生活中,不是每个用户的设备都跟我们的测试机一样高端,在开发过程中我们要学会思考功能要不要对低端机开启、在资源紧张的时候能不能做降级。
|
|
|
|
|
|
|
|
- 缓存管理
|
|
|
|
|
|
|
|
需要有一套统一的缓存管理机制,可以适当的使用内存;可以使用 onTrimMemory 回调,根据不同的状态决定释放多少内存。对于大项目来说,可能存在几十上百个模块,统一缓存管理可以更好的监控每个模块的缓存大小。
|
|
|
|
|
|
|
|
- 进程模型
|
|
|
|
|
|
|
|
一个空进程也会占用 10M 的内存,减少应用启动的进程数,减少常驻进程、有节操的保活,对低端机内存优化非常重要。
|
|
|
|
|
|
|
|
- 安装包大小
|
|
|
|
|
|
|
|
安装包中的代码、资源、图片以及 so 库的体积,跟它们占用的内存有很大的关系。一个 80M 的应用很难在 512 MB 的内存手机上流畅的运行。这种情况我们需要考虑针对低端机用户推出 4MB 的轻量版本,例如 Facebook Lite、今日头条极速版都是这个思路。
|
|
|
|
|
|
|
|
|
|
|
|
#### Bitmap 优化
|
|
|
|
|
|
|
|
Bitmap 内存一般占应用总内存很大一部分,所以内存优化永远无法避开图片内存这个永恒主题。
|
|
|
|
|
|
|
|
即使把所有的 Bitmap 都放到 Native 内存,并不代码图片内存问题就完全解决了,这样做只是提示了系统内存利用率,减少了 GC 带来的一些问题而已。
|
|
|
|
|
|
|
|
如果优化图片内存呢?这里介绍两种方法。
|
|
|
|
|
|
|
|
##### 方法一,统一图片库
|
|
|
|
|
|
|
|
图片内存优化的前提是收拢图片的调用,这样我们可以做整体的控制策略。例如低端机使用 565 格式、更加严格的缩放算法,可以使用 Glide、Fresco 或者采取自研都可以。而且需要进一步将所有 Bitmap.createBitmap、BitmapFactory 相关的接口也一并收拢。
|
|
|
|
|
|
|
|
##### 方法二:统一监控
|
|
|
|
|
|
|
|
在统一图片库后就非常容易监控 Bitmap 的使用情况了,这里有三点需要注意:
|
|
|
|
|
|
|
|
- 大图片监控
|
|
|
|
|
|
|
|
我们需要注意某张图片内存占用是否过大,例如长宽远远大于 View 甚至屏幕的长宽。在开发过程中,如果检测到不合格的图片使用,应该立即弹出对话框提示图片所在的 Activity 和堆栈,让开发同学更快的发现并解决问题。在灰度和线上环境下可以将异常信息上报到后台,我们可以计算有多少比例的图片会超过屏幕的大小,也就是图片的“超宽率”。
|
|
|
|
|
|
|
|
- 重复图片监控
|
|
|
|
|
|
|
|
重复图片指的是 Bitmap 的像素数据完全一致,但是有很多不同的对象存在。
|
|
|
|
|
|
|
|
- 图片总内存
|
|
|
|
|
|
|
|
通过收拢图片使用,我们还可以统计应用所有图片占用的内存,这样在线上就可以按不同的系统、屏幕分辨率等维度去分析图片内存的占用情况。在 OOM 崩溃的时候,也可以把图片占用的总内存、Top N 图片的内存都写到崩溃日志中,帮助我们排查问题。
|
|
|
|
|
|
|
|
#### 内存泄露
|
|
|
|
|
|
|
|
内存泄露简单来说就是没有回收不再使用的内存,排查和解决内存泄露也是内存优化无法避开的工作之一。
|
|
|
|
|
|
|
|
内存泄露主要分两种情况,一种是同一个对象泄露,还有一种情况更加糟糕,就是每次都会泄露新的对象,可能会出现几百上千个无用的对象。
|
|
|
|
|
|
|
|
对于 Java 内存泄露,可以使用 LeakCanary 自动化检测方案。
|