StrictMode的使用
StrictMode用来基于线程或VM设置一些策略, 一旦检测到策略违例, 控制台将输出一些警告,包含一个trace信息展示你的应用在何处出现问题.
通常用来检测主线程中的磁盘读写或网络访问等耗时操作.
在Application或是Activity的onCreate中开启StrictMode:
public void onCreate() {
if (BuildConfig.DEBUG) {
// 针对线程的相关策略
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
// 针对VM的相关策略
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
如果你的线程出了问题, 控制台会有警告输出, 可以定位到代码.
相对简单, 在此就不多废话了.
解决UI线程的耗时操作方案, 可以参考ANR详解里面说到的那些线程模式.
频繁的GC
实际上内存原因也可能会造成应用不流畅, 卡顿的.
说到这, 想起当年配台式机的三大件(CPU, 内存, 显示器)了. 貌似分析App性能也是这几大件啊 :)
为什么说频繁的GC会导致卡顿呢?
简而言之, 就是执行GC操作的时候,任何线程的任何操作都会需要暂停,等待GC操作完成之后,其他操作才能够继续运行, 故而如果程序频繁GC, 自然会导致界面卡顿.
以下内容参考自Android Performance Patterns:Memory Churn and Performance. 需翻墙
导致频繁GC有两个原因:
内存抖动(Memory Churn), 即大量的对象被创建又在短时间内马上被释放.
瞬间产生大量的对象会严重占用Young Generation的内存区域, 当达到阀值, 剩余空间不够的时候, 也会触发GC. 即使每次分配的对象需要占用很少的内存,但是他们叠加在一起会增加Heap的压力, 从而触发更多的GC.