Skip to content

Commit 9dd95c8

Browse files
committed
add android kernal
1 parent db0f8bb commit 9dd95c8

22 files changed

+2369
-154
lines changed

AdavancedPart/ANR分析.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# ANR分析
2+
3+
Application Not Responding,字面意思就是应用无响应,稍加解释就是用户的一些操作无法从应用中获取反馈
4+
5+
6+
Android系统中的应用被Activity Manager及Window Manager两个系统服务监控着,Android系统会在如下情况展示出ANR的对话框:
7+
- Service Timeout:比如前台服务在20s内未执行完成;后台服务超过200没有执行
8+
- BroadcastQueue Timeout:比如前台广播在10s内未执行完成,后台60s
9+
- ContentProvider Timeout:内容提供者,在publish过超时10s
10+
- InputDispatching Timeout: 输入事件分发超时5s,包括按键和触摸事件。
11+
12+
13+
14+
ANR信息输出到traces.txt文件中
15+
16+
traces.txt文件是一个ANR记录文件,用于开发人员调试,目录位于/data/anr中,无需root权限即可通过pull命令获取,下面的命令可以将traces.txt文件拷贝到当前目录下
17+
adb pull /data/anr .
18+
19+
20+
1) Thread基础信息
21+
22+
输出种包含所有的线程,取其中的一条
23+
"Thread-1" prio=5 tid=0x00007fde73872800 nid=0x4a03 waiting for monitor entry [0x000000011cb30000]
24+
java.lang.Thread.State: BLOCKED (on object monitor)
25+
at Test.rightLeft(Test.java:48)
26+
- waiting to lock <0x00000007d56540a0> (a Test$LeftObject)
27+
- locked <0x00000007d5656180> (a Test$RightObject)
28+
at Test$2.run(Test.java:68)
29+
at java.lang.Thread.run(Thread.java:745)
30+
a) "Thread-1" prio=5 tid=0x00007fde73872800 nid=0x4a03 waiting for monitor entry [0x000000011cb30000]
31+
32+
首先描述了线程名是『Thread-1』,然后prio=5表示优先级,tid表示的是线程id,nid表示native层的线程id,他们的值实际都是一个地址,后续给出了对于线程状态的描述,waiting for monitor entry [0x000000011cb30000]这里表示该线程目前处于一个等待进入临界区状态,该临界区的地址是[0x000000011cb30000]
33+
这里对线程的描述多种多样,简单解释下上面出现的几种状态
34+
35+
waiting on condition(等待某个事件出现)
36+
waiting for monitor entry(等待进入临界区)
37+
runnable(正在运行)
38+
in Object.wait(处于等待状态)
39+
40+
作者:silentleaf
41+
链接:https://www.jianshu.com/p/30c1a5ad63a3
42+
来源:简书
43+
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
44+
45+
46+
47+
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+
59+
60+
61+
62+
---
63+
64+
- 邮箱 :charon.chui@gmail.com
65+
- Good Luck!
66+

AdavancedPart/Handler导致内存泄露分析.md

Lines changed: 0 additions & 105 deletions
This file was deleted.

AdavancedPart/crash分析.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# crash分析
2+
3+
4+
## Java Crash流程
5+
6+
1、首先发生crash所在进程,在创建之初便准备好了defaultUncaughtHandler,用来处理Uncaught Exception,并输出当前crash的基本信息;
7+
2、调用当前进程中的AMP.handleApplicationCrash;经过binder ipc机制,传递到system_server进程;
8+
3、接下来,进入system_server进程,调用binder服务端执行AMS.handleApplicationCrash;
9+
4、从mProcessNames查找到目标进程的ProcessRecord对象;并将进程crash信息输出到目录/data/system/dropbox;
10+
5、执行makeAppCrashingLocked:
11+
12+
创建当前用户下的crash应用的error receiver,并忽略当前应用的广播;
13+
停止当前进程中所有activity中的WMS的冻结屏幕消息,并执行相关一些屏幕相关操作;
14+
15+
6、再执行handleAppCrashLocked方法:
16+
17+
当1分钟内同一进程连续crash两次时,且非persistent进程,则直接结束该应用所有activity,并杀死该进程以及同一个进程组下的所有进程。然后再恢复栈顶第一个非finishing状态的activity;
18+
当1分钟内同一进程连续crash两次时,且persistent进程,,则只执行恢复栈顶第一个非finishing状态的activity;
19+
当1分钟内同一进程未发生连续crash两次时,则执行结束栈顶正在运行activity的流程。
20+
21+
7、通过mUiHandler发送消息SHOW_ERROR_MSG,弹出crash对话框;
22+
8、到此,system_server进程执行完成。回到crash进程开始执行杀掉当前进程的操作;
23+
9、当crash进程被杀,通过binder死亡通知,告知system_server进程来执行appDiedLocked();
24+
10、最后,执行清理应用相关的四大组件信息。
25+
26+
27+
28+
- 剩余内存: /proc/meminfo,当系统可用内存小于MemTotal的10%时,非常容易发生OOM和大量GC。
29+
- PSS和RSS通过/proc/self/smap
30+
- 虚拟内存: 获取大小/proc/self/status,获取具体的分布/proc/self/maps。
31+
32+
如果应用堆内存和设备内存比较充足,但还出现内存分配失败,则可能跟资源泄露有关。
33+
- 获取fd的限制数量:/proc/self/limits。一般单个进程允许打开的最大句柄个数为1024,如果超过800需将所有fd和文件名输出日志进行排查。
34+
- 获取线程数大小:/proc/self/status一个线程一般占2MB的虚拟内存,线程数超过400个比较危险,需要将所有tid和线程名输出到日志进行排查。
35+
36+
37+
38+
39+
40+
41+
42+
Native Crash
43+
44+
崩溃过程:native crash 时操作系统会向进程发送信号,崩溃信息会写入到 data/tombstones 下,并在 logcat 输出崩溃日志
45+
定位:so 库剥离调试信息的话,只有相对位置没有具体行号,可以使用 NDK 提供的 addr2line 或 ndk-stack 来定位
46+
addr2line:根据有调试信息的 so 和相对位置定位实际的代码处
47+
ndk-stack:可以分析 tombstone 文件,得到实际的代码调用栈
48+
49+
50+
51+
## ANR
52+
53+
54+
55+
56+
ANR排查流程
57+
1、Log获取
58+
1、抓取bugreport
59+
adb shell bugreport > bugreport.txt
60+
复制代码
61+
2、直接导出/data/anr/traces.txt文件
62+
adb pull /data/anr/traces.txt trace.txt
63+
复制代码
64+
2、搜索“ANR in”处log关键点解读
65+
66+
67+
发生时间(可能会延时10-20s)
68+
69+
70+
pid:当pid=0,说明在ANR之前,进程就被LMK杀死或出现了Crash,所以无法接受到系统的广播或者按键消息,因此会出现ANR
71+
72+
73+
cpu负载Load: 7.58 / 6.21 / 4.83
74+
代表此时一分钟有平均有7.58个进程在等待
75+
1、5、15分钟内系统的平均负荷
76+
当系统负荷持续大于1.0,必须将值降下来
77+
当系统负荷达到5.0,表面系统有很严重的问题
78+
79+
80+
cpu使用率
81+
CPU usage from 18101ms to 0ms ago
82+
28% 2085/system_server: 18% user + 10% kernel / faults: 8689 minor 24 major
83+
11% 752/android.hardware.sensors@1.0-service: 4% user + 6.9% kernel / faults: 2 minor
84+
9.8% 780/surfaceflinger: 6.2% user + 3.5% kernel / faults: 143 minor 4 major
85+
86+
87+
上述表示Top进程的cpu占用情况。
88+
注意
89+
如果CPU使用量很少,说明主线程可能阻塞。
90+
3、在bugreport.txt中根据pid和发生时间搜索到阻塞的log处
91+
----- pid 10494 at 2019-11-18 15:28:29 -----
92+
复制代码
93+
4、往下翻找到“main”线程则可看到对应的阻塞log
94+
"main" prio=5 tid=1 Sleeping
95+
| group="main" sCount=1 dsCount=0 flags=1 obj=0x746bf7f0 self=0xe7c8f000
96+
| sysTid=10494 nice=-4 cgrp=default sched=0/0 handle=0xeb6784a4
97+
| state=S schedstat=( 5119636327 325064933 4204 ) utm=460 stm=51 core=4 HZ=100
98+
| stack=0xff575000-0xff577000 stackSize=8MB
99+
| held mutexes=
100+
复制代码
101+
上述关键字段的含义如下所示:
102+
103+
tid:线程号
104+
sysTid:主进程线程号和进程号相同
105+
Waiting/Sleeping:各种线程状态
106+
nice:nice值越小,则优先级越高,-17~16
107+
schedstat:Running、Runable时间(ns)与Switch次数
108+
utm:该线程在用户态的执行时间(jiffies)
109+
stm:该线程在内核态的执行时间(jiffies)
110+
sCount:该线程被挂起的次数
111+
dsCount:该线程被调试器挂起的次数
112+
self:线程本身的地址
113+
114+
作者:jsonchao
115+
链接:https://juejin.cn/post/6844903972587716621
116+
来源:掘金
117+
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
118+
119+
120+
121+
122+
123+
124+
125+
126+

AdavancedPart/布局优化.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,34 @@
11
布局优化
22
===
33

4+
布局优化的核心问题就是要解决因布局渲染性能不佳而导致应用卡顿的问题。
5+
6+
7+
8+
## 绘制原理
9+
10+
Android的绘制主要是借助CPU和GPU结合刷新机制来共同完成。
11+
12+
- CPU负责计算显示内容,包括Measure、Layout等操作,在UI绘制上的缺陷在于容易显示重复的视图组件,这样不仅带来重复的计算操作,而且会占用额外的GPU资源。
13+
- GPU负责光栅化,将UI元素绘制到屏幕上。
14+
15+
例如,文字首先要经过CPU换算成纹理,然后再传递给GPU进行渲染。而图片是先经过CPU计算,然后加载到内存中,最后再传给GPU进行渲染。
16+
17+
18+
## 耗时原因
19+
分析完布局的加载流程之后,我们发现有如下四点可能会导致布局卡顿:
20+
21+
1. 首先,系统会将我们的Xml文件通过IO的方式映射的方式加载到我们的内存当中,而IO的过程可能会导致卡顿。
22+
2. 其次,布局加载的过程是一个反射的过程,而反射的过程也会可能会导致卡顿。
23+
3. 同时,这个布局的层级如果比较深,那么进行布局遍历的过程就会比较耗时。
24+
4. 最后,不合理的嵌套RelativeLayout布局也会导致重绘的次数过多。
25+
26+
27+
## 优化方式
28+
429
- 去除不必要的嵌套和节点
530
这是最基本的一条,但也是最不好做到的一条,往往不注意的时候难免会一些嵌套等。
31+
632
- 首次不需要的节点设置为`GONE`或使用`ViewStud`.
733
- 使用`Relativelayout`代替`LinearLayout`.
834
平时写布局的时候要多注意,写完后可以通过`Hierarchy Viewer`或在手机上通过开发者选项中的显示布局边界来查看是否有不必要的嵌套。
@@ -146,7 +172,26 @@
146172

147173
- 减少不必要的`Inflate`
148174
如上一步中`stub.infalte()`后将该`View`进行记录或者是`ListView``item inflate`的时候。
149-
175+
176+
- 使用ConstraintLayout降低布局嵌套层级
177+
178+
- 实现几乎完全扁平化的布局
179+
- 构建复杂布局性能更高
180+
- 具有RelativeLayout和LinearLayout的特性
181+
182+
- 使用AsyncLayoutInflater异步加载对应的布局
183+
184+
- 工作线程加载布局
185+
- 回调主线程
186+
- 节省主线程时间
187+
188+
AsyncLayoutInflater是通过侧面缓解的方式去缓解布局加载过程中的卡顿,但是它依然存在一些问题:
189+
190+
- 1、不能设置LayoutInflater.Factory,需要通过自定义AsyncLayoutInflater的方式解决,由于它是一个final,所以需要将代码直接拷处进行修改。
191+
- 2、因为是异步加载,所以需要注意在布局加载过程中不能有依赖于主线程的操作。
192+
193+
194+
150195
---
151196

152197
- 邮箱 :charon.chui@gmail.com

Architect/1.架构简介.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121

2222
#### 规划
2323

24-
规划是系统架构中最重要的组成部分,是个人或者组织制定的比较全民长远的发展计划,是对未来整体性、长期性、基本性问题的思考和考量。设计未来整套行动的方案。很早就有规划这个概念了,例如:国家的十一五规划等。当然软件开发也和生活紧密联系,一个大型的系统也需要良好的规划,规划可以说是基石,是系统架构的前提。
24+
规划是系统架构中最重要的组成部分,是个人或者组织制定的比较全面长远的发展计划,是对未来整体性、长期性、基本性问题的思考和考量。设计未来整套行动的方案。很早就有规划这个概念了,例如:国家的十一五规划等。当然软件开发也和生活紧密联系,一个大型的系统也需要良好的规划,规划可以说是基石,是系统架构的前提。
2525

2626

2727
系统架构虽然是软件系统的结构,行为,属性的高级抽象,但其根本就是在需求分析的基础行为下,制定技术框架,对需求的技术实现。
2828

2929

3030

3131

32-
32+
3333
---
3434
- 邮箱 :charon.chui@gmail.com
3535
- Good Luck!

0 commit comments

Comments
 (0)