1、性能优化总结
- Mem(2种方案 手动GC[ mATRIX ] 阈值的处理【koom】)
- FPS(Handler机制、Printer检测卡断问题,消息处理完多少时间)、idleHandler
- 延迟操作 Handler.postDelayed(Runnable r,long time)
Looper.myQueue().addIdleHandler(new Message.IdleHandler(){
//queueIdle 返回true/false 返回true意味着延时操作生效。如果messagequeue为空的时候,就自动回调这个方法。这个可以拿来做FPS的监控?**为啥?**
})
-
so动态加载 Tinker的so的加载流程。把dex加载到数组的最前面。
- Relinker UnsatisfiedlinkError(so没找到对象的库):主要原因是兼容性的问题。包so的剪裁 是由于国内的厂商魔改ROM改的是so加载的路径(3种)。Relinker最牛逼的地方就是解析so的2进制文件,获取so的依赖属性。
- 小于 6.0的版本有个东西叫so的依赖,一个so的库可能依赖其它三个库,顺序不能颠倒,否则就崩溃。这个机制面试种可以说。So的依赖属性很关键,RElinker可以解决这个问题。循环加载lib,最后加载loadPath。重新link
- 网络下载so到本体,要通过这个Relinker库加载到内核当中。
-
面试简历当中。动态加载就要提到兼容性问题,然后要去讲用到ReLiner,模拟这个库写自己的逻辑。
-
动态加载放到简历去
-
ELF动态链接库 so 二进制协议。
-
性能优化+架构+业务逻辑复杂度
-
迅速接入到核心团队,架构,工程优化。不要碰UI的。
-
自己通过relinker库帮我进行加载。试试看。写到简历中
-
Matrix边改边做性能优化。
2、android rabbit-client 是什么?
android rabbit-client 是一个开源的 Android APM 框架,是一个面向开发者的性能监控工具 rabbit-client 可以帮助开发者快速定位应用性能问题,主要功能如下1:
- 应用测速:可以准确统计应用 Applicaiton 创建耗时、应用冷启动耗时和页面 inflate 耗时 & 完全渲染耗时。
- FPS 分析:可以实时显示 FPS 并支持分页面分析 FPS。
- 慢函数检测:可以对代码中定义的敏感函数(比如耗时函数)进行检测,提供阈值报警等功能。
- 内存分析:提供内存泄漏检测、内存分析等功能。
- 网络分析:提供网络请求分析、网络延迟分析等功能。
- 崩溃分析:提供崩溃日志收集、崩溃原因分析等功能。
3、 性能优化总结
github.com/SusionSuc/r… github.com/Tencent/mat…
-
设计还有架构 主流的开源项目 调用 怎么用?面试一定会问你。
-
Matrix:功能很全、相对比较重力度,不适合公司的业务的迭代,包体积很大。做到线上很鸡肋。经常crash。不能用于 线上,不能用于自己公司线上搭建
-
听云sdk(>8.0 CPU指标问题)
-
网易 腾讯GT
-
360的APM gradle集成的时候会有很多的问题
-
httpdns可以作为一个亮点
4、指标的问题
- 稳定性的问题(崩溃的问题) (bugly+breakpad+firebase(国外)) 一个set default 一个非set 非default?
- 流量/网络 (Http协议的可达率、流量的大小)OkHttp的拦截器 全链路的监控APM、网络一体化的问题、协议本身(Socket)统一的处理 (这里不要谈)
- 页面的FPS
- 错误日志动态上传。压缩 加密 workmanager 约束(充电或者其它情况传) wakeup
5、建议大家重点关注的APM的性能指标:
- 电量 最好讲battery historian、广播监听,统一的方案,
- 流量消耗 打印出来 trafficStats/getUidRxBytes(int uid)/getTotalbytes() 后台流量偷跑怎么处理?后台起个定时任务,获取时间间隔流量,或者5s或者5min,计算平均值。
- 内存指标的统计/内存的泄漏/
/**
* 只能用在debug model,
* */
private fun getMemoryInfoInDebug(): RabbitMemoryInfo {
val info = Debug.MemoryInfo()
Debug.getMemoryInfo(info)
val memInfo = RabbitMemoryInfo()
memInfo.totalSize = (info.totalPss) * 1024 // 这个值比profiler中的total大一些
memInfo.vmSize = (info.dalvikPss) * 1024 // 这个值比profiler中的 java 内存值小一些, Doesn't include other Dalvik overhead
memInfo.nativeSize = info.nativePss * 1024
memInfo.othersSize = info.otherPss * 1024 + info.totalSwappablePss * 1024
memInfo.time = System.currentTimeMillis()
memInfo.pageName = RabbitMonitor.getCurrentPage()
return memInfo
}
//pss
mActivityManager?.getProcessMemoryInfo(intArrayOf(Process.myPid())) ?: return 0
//内存的泄漏 application的 生命周期的监听
weakreference
activity,activity.class.simplename
activity onStop的时候 手动GC 2次 sleep
- 线上收集,需要有开关开启,当有重大问题的时候才收集。
- 线下用leakcanary就可以了
- application的生命周期的监听
- weakreference。activity activity.class.simplename、activity onStop的时候 手动gc2次,给一个 sleep。申请大对象。
6、FPS
- 原理知道 了 代码写在哪里?
Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
if(frameTimeNanos - mLastFrameNanos > 100) {
...
}
mLastFrameNanos = frameTimeNanos;
Choreographer.getInstance().postFrameCallback(this);
}
});
//推荐下面
public static void loop() {
...
for (;;) {
...
// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
...
}
}
- onActivtyResumed()开启监听 onWindowFocusChanged 如果界面可见我们可以收集pause暂停我们就停止。
- 面试中说的点
-
1、消息机制looper
-
2、Choreographer。性能不太好。
-
建议大家用message的消息监听,不要用这个编舞者。因为doframe不停执行,不需要刷新时也是不停执行,重复监听,不断去调用,对于线上监控性能不太好。
-
- 推荐这种方案。
- 丢帧不一定卡,卡顿一定丢帧。 Matrix中对卡顿有有定义,先掌握方法后面看代码就快了。
7、启动耗时监控
冷启动:App耗时时间检测 暖启动: activity的首帧判断 onWindowsFocusChange CP大法 ContentProvider中记录时间,再在first frame中计算,算下耗时。