1.内存监测工具
1.1 memory profiler
实时图表展示APP内存使用量
1.用于强制执行垃圾回收事件 。
2.用于捕获堆转储的按钮。
3.用于指定性能分析器多久捕获一次内存分配的下拉菜单。
Full:捕获内存中的所有对象分配。 如果您有一个分配了大量对象的应用,可能会在进行性能剖析时观察到应用的运行速度明显减慢。
Sampled:定期对内存中的对象分配情况进行采样。这是默认选项,在进行性能剖析时对应用性能的影响较小。在短时间内分配大量对象的应用仍可能会表现出明显的速度减慢。
Off:停止跟踪应用的内存分配。
4.用于缩放时间轴的按钮。
5.用于跳转到实时内存数据的按钮。
6.事件时间轴,显示活动状态、用户输入事件和屏幕旋转事件。
7.内存使用量时间轴,它会显示以下内容:
- 一个堆叠图表,显示每个内存类别当前使用多少内存,如左侧的 y 轴以及顶部的彩色键所示。
- 一条虚线,表示分配的对象数,如右侧的 y 轴所示。
- 每个垃圾回收事件的图标。
具体可以参考官方文档:
https://developer.android.com/studio/profile/memory-profiler?hl=zh-cn#why-profile-memory
1.2 MAT(Memory Analyzer Tool)
强大的Java heap分析工具,查找内存泄漏及内存占用
生成整体报告。Androidstudio 高版本已经自带该功能。另也可以自己下载。https://www.eclipse.org/mat/ 这里直接介绍Androidstudio 的捕获堆转储功能。
堆转储显示在您捕获堆转储时您的应用中哪些对象正在使用内存。特别是在长时间的用户会话后,堆转储会显示您认为不应再位于内存中却仍在内存中的对象,从而帮助识别内存泄漏。
- 您的应用分配了哪些类型的对象,以及每种对象有多少。
- 每个对象当前使用多少内存。
- 在代码中的什么位置保持着对每个对象的引用。
- 对象所分配到的调用堆栈
点击内存性能分析器工具栏中的 Dump Java heap 图标
-
Allocations:堆中的分配数。
-
Native Size:此对象类型使用的原生内存总量(以字节为单位)。只有在使用 Android 7.0 及更高版本时,才会看到此列。
您会在此处看到采用 Java 分配的某些对象的内存,因为 Android 对某些框架类(如 Bitmap)使用原生内存。 -
Shallow Size:此对象类型使用的 Java 内存总量(以字节为单位)。
-
Retained Size:为此类的所有实例而保留的内存总大小(以字节为单位)。
点击一个类名称可在右侧打开 Instance View 窗口 .列出的每个实例都包含以下信息:
- Depth:从任意 GC 根到选定实例的最短跳数。
- Native Size:原生内存中此实例的大小。 只有在使用 Android 7.0 及更高版本时,才会看到此列。
- Shallow Size:Java 内存中此实例的大小。
- Retained Size:此实例所支配内存的大小
1.3 LeakCanary
https://blog.csdn.net/chentaishan/article/details/104742904
1.4 ARTHook 监测不合理图片
图片的宽高和展示图片控件的宽高很多时候不一致,我们通过检测图片的宽高结合控件的宽高,去动态压缩图片,节省内存。
图片的内存占用计算:
宽高的像素一像素的内存空间 = 图片在内存占用大小
如 100* 100* ARGB_8888 = 1001004 = 40000 byte
Epic 是一个在虚拟机层面、以 Java Method 为粒度的 运行时 AOP Hook 框架。简单来说,Epic 就是 ART 上的 Dexposed(支持 Android 5.0 ~ 11)。它可以拦截本进程内部几乎任意的 Java 方法调用,可用于实现 AOP 编程、运行时插桩、性能分析、安全审计等。 https://github.com/tiann/epic
- 使用
dependencies {
compile 'me.weishu:epic:0.11.0'
}
2.demo
定义一个imageHook类,去监听对象的属性,根据属性转换成业务属性,进行hook后的逻辑处理。
public class ImageHook extends XC_MethodHook {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
// 实现我们的逻辑
ImageView imageView = (ImageView) param.thisObject;
//检测图片的宽高和控件的宽高,如果宽高相差很多,可以提示用户,也可以进行自己的逻辑
checkBitmap(imageView,((ImageView) param.thisObject).getDrawable());
}
通过DexposedBridge hook ImageView类,监听的方法里,去查找要hook的对象及对象方法及监听类。可以在初始化application类里。
DexposedBridge.hookAllConstructors(ImageView.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
DexposedBridge.findAndHookMethod(ImageView.class, "setImageBitmap", Bitmap.class, new ImageHook());
}
});
2.优化方案
1.慎用service
当需要使用service的时候,再启动。当任务执行完停止Service的时候,要小心Service停止失败导致内存泄漏的情况。推荐使用intentservice ,当后台任务执行结束后会自动停止,从而极大程度上避免了Service内存泄漏的可能性。
2 onTrimMemory 释放资源
指导应用程序在不同的情况下进行自身的内存释放,以避免被系统直接杀掉。
TRIM_MEMORY_UI_HIDDEN 表示应用程序的所有UI界面被隐藏了,即用户点击了Home键或者Back键导致应用的UI界面不可见.这时候应该释放一些资源
3.使用ProGuard来剔除不需要的代码
4.对最终的APK使用zipalign
4.图片优化
图片格式对比
png:无损压缩,比较大,需要进行压缩,网站tinypng
jpg:有损压缩,不支持透明通道
webp:支持有损无损压缩,支持透明通道
.9.png 支持拉伸,
4.1 图片内存占用计算
ARGB : aphla red green blue
ARGB_8888: 100* 100 * 4 = 40000字节
其中4 代表4个字节,因为argb4个通道,每个8位,一共4个字节。
所以我们可以选择RGB_565 来降低图片的占用内存
4.2 大图展示
BitmapRegionDecoder 展示大图
c 语言处理图片的输入流,利用矩阵形式展示固定区域内的图像信息
https://blog.csdn.net/shulianghan/article/details/107099591
3 其他优化细节
LargeHeap 属性 --清单文件申请更大内存 乘以2
sharedPrefences
谨慎使用外部库