ANR(Application Not Responding)
5s程序无响应,主线程做耗时操作引起,也就是主线程被阻塞。
发生在主线程中的有:
Activity、Service、BroadcastReceiver的onReceive回调
主线程中new Handler();
view.post(Runnable)
解决方式:
使用AsyncTask处理耗时操作
使用Thread和HanlderThread提高优先级
Activity的生命周期回调中尽量不要做耗时操作
app申请的内存
每个app分配的最大内存限制,随不同设备而不同
切换应用时后台app清理机制:
LRU Cache机制:最近使用的排在最前面,最少可能的被清理
清理内存回调onTrimMemory方法
Java中的引用方式
强引用:对象强引用,当内存不足,虚拟机宁愿抛出OOM,也不会随意回收强引用
软引用(SoftReference):当内存不足时候,垃圾回收器才回收
弱引用(WeakReference):当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象
虚引用(PhantomReference):如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收
ps:被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收...
** 优化方法**
数据结构的优化
-
字符串的拼接用StringBuilder(替换频繁的String字符拼接等)
字符串通过+的方式进行拼接会产生中间字符串内存块,这些都是没有用的。 -
ArryMap、SpareseArray替换HashMap
因为ArryMap、SpareseArray内存占用少,且效率更高 -
内存抖动
一时间创建很多对象 -
Service使用完尽量停止
对象复用
1、复用系统自带资源
2.ListView相关复用
3.避免在onDraw中创建对象
避免内存泄露
代码问题导致这块内存,虽然停止使用,但依然
被其他对象引用这,使得GC没发对它回收
1.避免Activity泄露,用弱引用
2.引用Context时,能用Application尽量用Application
- Context 泄漏, 主要为Activity 传递泄漏, context 未使用applciationConext 在单例创建时。
- Handler 泄漏 , handler中持有view ,context 等做耗时操作。
- Cursor 泄漏 , cursor未关闭
- register 未 unregister
- Bitmap
- adapter 未使用convertView
- WebView内存泄露
- 不良代码等
WebView内存泄露解决方式:
https://stackoverflow.com/questions/3130654/memory-leak-in-webview
Android系统的一个bug:通过XML布局创建WebView时,活动作为WebView的上下文而不是应用程序上下文传递。 完成活动后,WebView仍然保持对活动的引用,因此活动不会从内存中移除。 必须使用new创建:
WebView webView = new WebView(getApplicationContext());
webView销毁:
```
@Override
protected void onDestroy() {
super.onDestroy();
if (null != mWebView) {
//解除webView与父控件的依附关系
((ViewGroup) mWebView.getParent()).removeView(mWebView);
mWebView.removeAllViews();
mWebView.setTag(null);
mWebView.clearHistory();
mWebView.loadUrl("about:blank") ;
mWebView.setVisibility(View.GONE);
mWebView.destroy();
mWebView = null;
}
}
```
资源使用完未关闭(BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap)
写完程序对程序进行Review,或者用代码检测工具检查,运行时候使用LeakCanary检查是否有内存泄露。内存紧张时释放一些图片内存等
如查询数据库的操作,使用到Cursor,也要对Cursor对象及时关闭
ndroid程序里面存在很多需要register与unregister的监听器,手动add的listener,需要记得及时remove这个listener。
强引用、软引用、弱引用
优化OOM
1.注意临时Bitmap对象的及时回收
2.加载Bitmap:缩放比例、解码格式、局部加载
性能优化
卡顿原理:
60fps->16ms,如果16毫秒在60帧以下,就会卡顿
解决方式:
不要在主线程中做轻微的耗时操作
同一时间动画执行次数过多,导致CPU或GPU负载过重,要避免
列表Adapter的复用
布局优化:
去除XML布局中不必要的bg设置
减小View的层级,使用ViewStub
避免嵌套过多无用布局,同样的层级LinearLayout优于RelativeLayout.
merge标签的使用
冷启动:
在启动应用前,系统中没有该应用的任何进程信息
缩短冷启动时间:
减少onCreate方法的工作量,使用懒加载加载第三方SDK
热启动:
退出应用后,重启启动应用系统中有该应用的任何进程信息
[启动优化](http://www.jianshu.com/p/f5514b1a826c):
Splash添加主题
异步初始化第三方组件(使用IntentService开启后台线程初始化)
Bitmap
LRU(LruCache)算法:清除最近最少使用的Bitmap, put进去的时候有个putCount的计数器,可以判断putCount最小的就是最少使用的
计算inSampleSize
缩略图
三级缓存:先查内存--->SD卡--->网络请求
其他优化
不要使用静态变量存储数据
Shareprefrence:
不能跨进程同步
不能存储大数据,因为读写値会阻塞主线程,并且会产生大量临时对象,频繁GC导致内存抖动等等
APK瘦身
使用一套资源,且图片使用tinypng有损压缩
启动页使用jpg 720小图
webp图片使用
开启混淆代码
通过AS工具移除无用资源
删除无用语言资源
so包只使用armable目标(微信等大厂app都是这样)
避免重复库的使用,比如使用了两个图片加载库:Glide和Picasso
如果raw文件夹下有音频文件,尽量不要使用无损的音频格式,比如wav。可以考虑相比于mp3同等质量但文件更小的opus音频格式
多用代码实现UI,shape等
电量优化
及时停止定位
谨慎使用WakeLock
网友评论