Android 系统(56)---Android 系统开机日志

《Android内核开发》系列的第八篇文章,本文主要关注如何分析Android系统的启动log,学会通过搜索重要的TAG标签,找到Android启动过程中的重要节点。


要学会分析系统的启动log信息,首先得了解Android系统的启动过程,建议先阅读《Android内核开发:图解Android系统的启动过程》这篇文章,它详细介绍了Android系统的启动过程。其次,你需要知道如何抓取系统启动log信息,建议阅读《Android内核开发:如何统计系统启动时间》这篇文章,它详细地介绍了如何抓取系统的启动log信息。


本文在这2篇文章的基础上,进一步介绍如何深入地分析系统启动log信息,找出Android启动启动过程中每一个部分所消耗的具体时间节点。


首先,我们给出一张比较全面的Android系统启动图(来自Embeded Android):


wKioL1WBbnDTaqQlAAJ4msbU3f0944.jpg


根据上述Android的启动框图,我们可以顺序地列出Android系统启动中涉及的几个关键步骤:


(1) Linux内核的启动


(2) Init程序启动,并启动各个本地服务(如 healthd, debuggerd等)


(3) Zygote进程启动


(4) Zygote进程初始化工作(preload class/resource)


(5) SystemServer进程启动,并启动各个Java服务(如 ActivityManager, PackageManager等 )


(7) 启动结束的标志点


如果我们能够从启动log信息中找出上述这些关键步骤的时间节点,也就可以很清晰地得到Android系统启动过程中各个模块消耗的时间了,在做系统启动优化时,也就知道该去优化哪些耗时的模块了,同样,在分析系统启动bug的时候,也就知道到底哪里出了问题了。


下面,我们以高通的APQ8064开发板(Android 4.4.2)的启动log信息为例来分析(这些log文件上传到我的Github上了:https://github.com/Jhuster/AOSP/tree/master/logs/APQ8064),其实各个Android系统都有类似的log输出,我们只需重点掌握关键节点的TAG和分析方法。


1.  配置系统的log输出


(1) 在内核log信息中打印出时间信息


在Linux kernel源码树中执行 make menuconfig,勾选下面的选项:


"Kernel hacking" -> "Show timing information on printks"


(2) 将init进程的详细log输出到dmesg文件中


修改/system/core/rootdir/init.rc,把loglevel从3改为7


2.  抓取系统启动的log信息


前面的文章已经介绍过,Android系统启动的log分为Linux内核的log和Android Logger系统的log,


抓取的方法如下:


$ adb shell dmesg > dmesg.txt

$ adb logcat -d -v time -b "main"   >  main.txt

$ adb logcat -d -v time -b "system" >  system.txt

$ adb logcat -d -v time -b "events" >  events.txt


3.  分析log信息


(1) Linux内核的启动


Linux内核启动的log都位于dmesg.txt文件中,从log文件开始直到出现下面这条消息则标志着Linux内核已经完成了启动:


"Freeing init memory"


因此,我们从dmesg.txt文件中即可得到APQ8064开发板的Linux内核启动只用了6.613s,如图所示:


wKioL1WBcBOQBimqAAAouZFmP0c299.jpg


(2) Init程序启动,并启动各个本地服务(如 healthd, debuggerd等)


Init程序的log信息也位于dmesg.txt文件中,我们可以通过检索“init”找到该程序的打印消息。


通过检索“init starting”,我们可以找到init进程启动了哪些本地服务,如:


wKiom1WBbouiU3HlAAeKNfLsVoY385.jpg


(3) Zygote进程启动


zygote进程是在init进程中启动的,因此,我们从上面init进程的输出log中,检索"zygote"就可以找到zygote进程何时启动的,如图所示:


wKioL1WBcGLxLbvZAAAxIazSkdg520.jpg


(4) Zygote进程初始化工作(preload class/resource)


Zygote进程所输出的log信息被放到/dev/log/main文件中了,因此,我们需要检索main.txt得到Zygote的log信息。


由于后续所有的Android应用程序都是从Zygote进程fork出来的,Android系统为了提高应用程序的启动速度,会在Zygote进程初始化过程中加载一些常用的java class和资源文件到进程的内存中,从而共享常用的class和resourse资源。这个过程我们可以通过检索"preload"标签得到这个过程所消耗的时间,如图所示:


wKioL1WBcI2QQ24VAADbZAseC7w046.jpg


(5) SystemServer进程启动,并启动各个Java服务(如 ActivityManager, PackageManager等 )


Zygote完成了初始化工作后就启动SystemServer进程了,SystemServer进程的log信息被放到了/dev/log/system文件中了,因此,我们需要检索system.txt文件得到SystemServer的log信息,如图所示:


wKiom1WBbv6QYTP9AA1W3Tk_JEk001.jpg


(7) 启动结束的标志点


《Android内核开发:如何统计系统启动时间》这篇文章已经详细地介绍了如何找到启动结束的时间,这里选取其中一种方法再复述一遍,就是检索dmesg文件的 "boot_completed" 标志,如图所示,我们知道了整个系统一共耗时29.913s完成启动:


wKiom1WBbyHiG2-XAABTfQTyDMI651.jpg

<think>好的,我现在需要帮助用户排查Android系统中ss_map进程高资源占用的问题,特别是涉及到Android内核错误的情况。首先,我要整理用户提供的信息和引用资料,看看哪些可能有帮助。 用户提到的问题是关于ss_map进程的高资源占用,可能与Android内核错误有关。我需要考虑常见的导致高资源占用的原因,比如CPU、内存、I/O或者网络问题,以及如何利用Android的工具和日志来诊断。 首先,根据引用[3]中的内容,ActivityManager在开机时的日志显示用户解锁过程中的状态变化,这可能与系统启动时的资源竞争有关。不过用户的问题不是开机时的问题,而是ss_map进程的持续高占用,可能需要关注该进程的具体行为。 引用[1]中的getRecentTasks方法可能用于获取最近任务,但不确定是否与ss_map直接相关。引用[2]提到的Application.quit()导致的crash问题,可能与进程退出时的资源释放有关,但用户的问题是高占用而非崩溃。引用[4]的PACKAGE_USAGE_STATS权限可能用于监控应用使用情况,但需要确认ss_map是否有相关权限滥用。 接下来,我需要规划排查步骤: 1. **确认进程信息**:使用adb命令查看ss_map的进程ID和资源使用情况,比如top或ps命令。 2. **分析CPU占用**:通过Android Profiler或systrace工具抓取CPU使用情况,查看是否有异常线程或频繁的调度。 3. **检查内存泄漏**:利用内存分析工具如MAT或Android Studio的Profiler,检查堆转储,确定是否有内存泄漏。 4. **I/O和网络分析**:使用strace或systrace跟踪系统调用,查看是否有大量的文件读写或网络请求。 5. **内核日志检查**:通过dmesg或logcat查看内核级别的错误信息,寻找可能的OOM(内存溢出)或死锁。 6. **系统服务关联**:检查ss_map是否是系统服务的一部分,查看ActivityManager的相关日志(引用[1]和[3]可能涉及ActivityManager的状态变化)。 7. **权限和第三方库**:确认是否有过度使用权限,如引用[4]提到的PACKAGE_USAGE_STATS,或者第三方库导致的资源泄露。 用户可能需要具体的命令和步骤,比如如何获取日志,使用哪些工具。同时,需要考虑到不同Android版本之间的差异,以及是否需要root权限。例如,获取内核日志可能需要adb shell dmesg,而systrace需要正确的参数配置。 另外,可能涉及系统服务的bug,比如ActivityManager在处理特定任务时未能正确释放资源,导致ss_map持续占用资源。需要结合用户提供的日志中的时间点,检查是否有异常事件发生,比如频繁的进程创建销毁,或者锁竞争。 最后,生成相关问题时要覆盖排查步骤中的各个方面,帮助用户深入理解问题可能的原因和解决方法。</think>### ss_map进程高资源占用排查指南 #### 一、确认进程基本信息 1. 获取进程ID和资源消耗: ```bash adb shell top -n 1 | grep ss_map # 输出示例:13167 0.3% 2% S 56M 7632K fg u0_a123 ss_map ``` 重点关注`%CPU`和`VSS/RSS`内存指标[^3] 2. 查看线程级CPU占用: ```bash adb shell ps -T -p <PID> # 输出示例: # USER PID TID PPID VSZ RSS WCHAN ADDR S CMD # u0_a123 13167 13189 12345 123456 78900 futex_ S 0 Binder:13167_1 ``` 若发现特定线程持续占用CPU,可能涉及死锁或循环逻辑 #### 二、内核级诊断 1. 检查内核错误日志: ```bash adb shell dmesg | grep -E "ss_map|oom|sigsegv" ``` 关注`SIGSEGV`段错误(如引用[2]的crash问题)或`OOM`内存溢出记录 2. 分析进程调度延迟: ```bash # 生成systrace报告(需提前配置环境) python systrace.py -o ss_map_trace.html sched freq idle am wm ``` 通过`sched`标签查看进程调度状态,定位`D状态`(不可中断睡眠)或`R状态`(运行队列堆积) #### 三、内存泄漏检测 1. 生成内存快照: ```bash adb shell am dumpheap <PID> /data/local/tmp/ss_map.hprof adb pull /data/local/tmp/ss_map.hprof ``` 使用Android Studio Memory Profiler分析内存对象分布 2. 检查内存映射异常: ```bash adb shell cat /proc/<PID>/maps | grep -E "anon|ss_map" ``` 若发现大量`anon`匿名内存块持续增长,可能发生Native层内存泄漏 #### 四、系统服务关联分析 1. 检查ActivityManager关联性: ```bash adb shell dumpsys activity processes | grep -A 20 "ss_map" ``` 观察`oom_adj`值(0-15)判断进程优先级,高优先级进程更易触发资源竞争(参考引用[1]的RecentTask机制) 2. 验证广播接收状态: ```bash adb shell dumpsys activity broadcasts | grep ss_map ``` 排查是否因频繁接收`BOOT_COMPLETED`等广播(如引用[3]的开机广播延迟)导致唤醒风暴 #### 五、优化建议 1. 权限约束: ```xml <!-- 检查manifest是否包含高敏感权限 --> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" /> <!-- 参考引用[4] --> ``` 2. Native层问题定位: ```bash # 使用addr2line解析堆栈地址 aarch64-linux-android-addr2line -e symbols.so <崩溃地址> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值