1.降低运行时内存
2.代码优化
3.内存泄漏优化

1.降低运行时内存
降低运行时内存可以分为减小APK体积和Bitmap优化两部分
(1)减小APK体积
方法一:去除无用的资源代码,通过合理使用git,一些由于业务变更而基本不会用到的代码,该删除的决不能手软。
即使以后要用到,通过git也能找回。同时一些图片资源未用到的也应该删除,因为即使gradle配了sharkresource选项
发布的时候这些没用到的图片依然会被打包到你的apk.

方法二:尽量复用资源,其实这是一种比较好的编码习惯。

方法三:对应用的启动图引导页图片进行压缩,往往这些图片占据了大部分空间,压缩后可以起到很好的效果。平时开发中
对于分辨率大于100*100的图片基本山都会进行压缩,很多好的压缩算法经常可以减少一半的大小,而感官上基本看不出有
任何改变。

(2)Bitmap优化
方法一:统一的bitmap加载器,选择Glide,Fresco,Picasso中的一个作为图片加载框架。实际开发中加载到view的图片的大小
不应该超过view的大小,图片加载框架默认hi对图片进行缓存,按view实际大小加载。在开发中为了减少apk的大小,一般只放
一套3X图片,但是这些图片在小分辨率的手机上直接加载就会出现内存浪费。统一的bitmap加载器就可以很好的解决该问题。

方法二:图片存在像素浪费,对于.9图,美工可能在出图时在拉伸与非拉伸区域都有大量的像素重复。而这些图片是可以缩小,
但并不影响显示效果。

方法三:inSampleSize:缩放比例,在把图片加载如内存之前,我们需要计算一个合适的缩放比例,避免不必要的大图载入。
(使用inBitmap参数前,每创建一个Bitmap对象都会分配一块内存供其使用,而使用了inBitmap参数后,多个Bitmap可以复用
一块内存,这样可以提高性能。)

2.代码优化
(1)考虑使用ArrayMap/SpareseArray而不是传统的HashMap等数据结构,Android系统为移动设计的容器ArrayMap更加高效,占用
内存更少,因为HashMap需要额外的实例对象来记录Mapping的操作。而SparesArray高效的避免了key和value的自动装箱,而且
避免了装箱后的解箱。

(2)在onDraw()这种频繁调用的方法要避免对象的创建操作,因为他会迅速增加内存的使用,引起频繁的gc,甚至内存抖动。

(3)SoftReference(软引用),WeakReference(弱引用),PhantomReference(虚引用)

(4)谨慎使用large heap, android设备由于软硬件的差异,heap阀值不同,特殊情况下可以在manifest中使用largeheap=true声明
一个更大的heap空间,使用getLargememoryClass()来获取到这个更大的空间。但是要谨慎使用,因为额外的空间会影响到系统整体
的用户体验,切换任务时性能大打折扣,对于oom异常是指标不治本的一种做法。

(5)谨慎使用多进程,使用多进程可以把应用中的部分组件运行在单独的进程当中,这样可以扩大应用的内存占用范围,但是这个技术
必须谨慎使用,绝大多数应用都不应该贸然使用多进程,一方面是因为使用多进程会使得代码逻辑更加复杂,另外如果使用不当,他可能
反而会导致显著增加内存。

3.内存泄漏优化
(1)Activity调用了finish,但是引用Activity的对象未被释放(生命周期没有结束),Activity Context被传递到其他实例中,可能
导致自身被引用而发生泄漏,建议使用weakReferce.

(2)除必须使用Activity Context的情况(Dialog的context必须是Activity),我们可以使用Application Context来避免Activity泄漏

(3)大多数情况下,我们对Bitmap对象增加缓存机制,但是有时候部分bitmap需要及时回收。比如我们临时创建的某个相对大的bitmap对象
变换得到新的bitmap对象后,尽快回收原始的bitmap,及时释放原来的空间。

(4)webView引起的内存泄漏主要是因为
org.chromium.android_webview.AwContents 类中注册了component callbacks,
但是未正常反注册而导致的。让onDetachedFromWindow先走,在主动调用destroy()之前,
把webview从它的parent上面移除掉(Basewebfragment onDestroy())

(5)虽然单例模式简单实用,提供了很多便利性,但是因为单例的生命周期和应用保持一致,使用不合理很容易出现持有对象的泄漏。

(6)我们在对数据库进行操作时,使用完cursor没有及时关闭,cursor的泄露,会对内存管理带来负面影响。

(7)谨慎使用static对象,因为static的生命周期过长,和应用的进程保持一致,使用不当很可能导致对象泄漏。