本章参考google官方文档,总结了android开发过程中内存优化的方法,同时,结合实际开发过程中遇到的OOM,总结了部分经验。不当之处,请随时提出。
Random-access memory (RAM) is a valuable resource in any software development environment,
but it’s even more valuable on a mobile operating system where physical memory is often constrained.
Although both the Android Runtime (ART) and Dalvik virtual machine perform routine garbage collection,
this does not mean you can ignore when and where your app allocates and releases memory
随机存取存储器(RAM)是任何软件开发环境中的宝贵资源,但在物理内存通常受限制的移动操作系统上更为有价值。
尽管Android Runtime(ART)和Dalvik虚拟机都执行常规垃圾收集,但这并不意味着您可以忽略应用程序分配和释放内存的时间和位置
查看内存使用情况
- 1 使用android studio自带的 Memory Monitor查看
该工具显示可用和分配的Java内存随时间的图,包括垃圾回收事件
- 2 使用android studio自带的allocation Tracker tool
分配跟踪器记录应用程序的内存分配,并列出分析快照中的所有已分配对象。您可以使用此工具来跟踪分配太多对象的部分代码
优化内存的方案
1 使用onTrimMemory在应用UI隐藏时释放UI资源来释放内存
请注意:这个玩意不同于onStop,你的应用仅仅会在所有UI组件的被隐藏的时候接收到onTrimMemory()的回调并带有参数TRIM_MEMORY_UI_HIDDEN。这与onStop()的回调是不同的,onStop会在activity的实例隐藏时会执行,
例如当用户从你的app的某个activity跳转到另外一个activity时前面activity的onStop()会被执行。
因此你应该实现onStop回调,并且在此回调里面释放activity的资源,例如释放网络连接,注销监听广播接收者。除非接收到onTrimMemory(TRIM_MEMORY_UI_HIDDEN))的回调,否者你不应该释放你的UI资源。这确保了用户从其他activity切回来时,你的UI资源仍然可用,并且可以迅速恢复activity。
|
|
这个回调支持API14以上,要兼容14以下可以使用 onLowMemory()
2 谨慎使用services,可以选择intentservice 代替service
它会在处理完交代给它的intent任务之后尽快结束自己
3 使用ArrayMap/SparseArray代替hashmap等传统数据结构
4 注意代码抽象,少用enum
抽象的代价是巨大的:一般来说,它们需要更多的代码需要执行,需要更多的时间和更多的RAM才能将该代码映射到内存中
For example, enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android
5 谨慎使用第三方库,移除内存使用大的库和资源文件
你的代码中的一些资源和库可以在不知道的情况下消除内存。
您的APK的总体尺寸(包括第三方库或嵌入式资源)可能会影响应用程序消耗多少内存。
您可以通过从代码中删除任何冗余的,不必要的或膨胀的组件,资源或库来提高应用程序的内存消耗
6 减小APk大小
您可以通过减少应用程序的总体大小来显着降低应用程序的内存使用量。
位图大小,资源,动画框架和第三方库都可以帮助您的APK的大小。
Android Studio和Android SDK提供多种工具来帮助您减少资源和外部依赖关系的大小
example Reduce APK Size
7 如果项目必须需要用到依赖注入框架,推荐使用Dragger2(官方推荐)
Dagger不使用反射来扫描您的应用程序的代码。 Dagger的静态编译时实现意味着它可以在Android应用程序中使用,而无需运行时费用或内存使用。
8 使用LeakCanary开源控件,可以很好的帮助我们发现内存泄露的情况
具体的使用请查看官方Github或者中文资料
当然还可以使用MAT
以上参考自android官方性能优化资料
总结
LeakCanary值得推荐,用于监听项目中的内存泄露。
监听会发现除了官方SDK中的方法导致的内存泄露外,大部分都是静态变量的引用未及时销毁导致的。加载大图,及易产生OOM。
因此在加载图片的时候,需要我们对图片进行压缩处理(图片的大小,质量压缩),选择合适尺寸的图片进行加载。同时,需要及时recycle临时图片。减少不必要的全局变量(官方文档给出了同样的建议),避免静态变量引用消耗更多的资源。
减少枚举类型的使用。
在使用SQLite时及时销毁cursor。
以上为项目中遇到的内存优化方案,其他方案若有遗漏会及时补充。
插一句:虽然现在手机内存慢慢在变大,必要的时候,我们可以使用空间换时间,但是在自己能力范围内,不断的优化内存使用,应该算是我们的职业道德吧👍。
虽然我现在是渣渣,但是五年后呢?嘻嘻