Android重要线程进程一览

2,964 阅读9分钟

前言

    你是否对于Android系统的各大进程例如Zygote、init、SystemServer进程,以及Android的关键服务AMS,ServiceManager服务的关系感到混乱?总是记了又忘,难以在大脑中形成一个完整的结构?本文通过几个简单的shell命令让你看到系统的运行情况,使你对系统中的进程线程有一个直观的感受,方便你后续再进一步的分析各大服务的源码。

Android重要进程一览

    首先在terminal执行adb devices命令确保你已经连接到一个虚拟机或者真机并在线了,然后再执行adb shell ps 命令即可看到当前设备的所有运行中的进程。下面表格仅列出了我们熟悉的一些进程。

USERPIDPPIDNAME
root10init
root1511init
root3121Zygote64
system1791servicemanager
system1801hwservicemanager
system511312system_server
shell41491745ps
  • USER代表进程的当前用户。root是Linux内置的超级用户,而system则是Android系统用户。
  • PID代表进程的ID。
  • PPID代表父进程ID,即创建该进程的进程ID。这里可以很明显的看到,Linux创建了init进程,init进程又创建了Zygote64servicemanager等进程,Zygote进程又创建了system_server进程。

执行adb shell 进入shell之后再执行ps命令可能和看到的结果并不相同,那是因为使用的shell终端不同,此时使用ps -A命令即可看到完整的。直接执行adb shell ps 命令使用的是电脑中的shell终端,而执行adb shell 进入的shell则是设备中的shell终端。

init进程下线程一览

    执行adb shell ps -T 1 命令即可查看PID为1的进程下的所有线程。

USERPIDTIDPPIDCMD
root110init
root11500init

    执行adb shell ps -T 151 命令即可查看PID为151的进程下的所有线程。

USERPIDTIDPPIDCMD
root1511511init
  • PID代表进程的ID。
  • TID代表线程ID。
  • PPID代表父进程ID,即创建该进程的进程ID。

并不了解为何系统会有两个init进程、三个init线程,如果后续了解到会再补充。

Zygote64进程下线程一览

    执行adb shell ps -T 312 命令即可查看PID为312的进程下的所有线程。所有的应用进程都是通过Zygote进程fork出来的子进程,所以他所有的线程都会在应用线程创建的时候就存在。

USERPIDTIDPPIDCMD
root3123121main
root31273901Jit thread pool
root31273911HeapTaskDaemon
root31273921ReferenceQueueD
root31273931FinalizerDaemon
root31273941FinalizerWatchd
  • main即通常所说的主线程。
  • Jit thread pool 不认识,暂时没在源码里查到
  • HeapTaskDaemon用于释放堆内存即通常说的GC
  • ReferenceQueueDaemon负责软、弱、虚引用的对象的回收
  • FinalizerDaemon用来回调【即将被回收的对象】的finalize方法;
  • FinalizerWatchdogDaemon 监视FinalizerDaemon线程,如果在回调【即将被回收的对象】的finalize方法时超过了100_0000_0000纳秒(即10秒),那么进程会被强行kill掉

ServiceManager进程下线程一览

    执行adb shell ps -T 179 命令即可查看PID为179的进程下的所有线程。可以看到ServiceManager进程下仅有一个同名线程,说明ServiceManager线程专门用于Binder服务的管理。

USERPIDTIDPPIDCMD
system1791791servicemanager

SystemServer进程下线程一览

    执行adb shell ps -T 511 命令即可查看PID为511的进程下的所有线程。SystemServer进程下有多达150个线程,这里仅列举出部分我们熟悉的线程。这里可以看到有:

  • 1个ActivityManagerService线程,这是ActivityManagerService所使用的线程。
  • 4个ActivityManager线程,暂时不知道干嘛的。
  • android.anim主要工作:Choreographer运行在这个线程中,负责协调动画相关内容。
  • android.anim.lf主要工作:负责协调SurfaceAnimation动画相关内容。
  • android.bg所有线程共享的一个后台线程,本身并不包含处理任务的代码,具体的工作由Runnable或者Handler完成。TODO 具体工作内容还需进一步分析。
  • android.display线程,主要用于:
    1. DisplayManagerService(display adapter,viewport ,event…)
    2. InputManagerService (keyboard , input device …)
    3. WindowManagerService 实例的创建
  • android.fg一个共享前台线程,源代码为FgThread.java,主要用于:
    1. AccountManagerService
    2. BatteryStatsService
    3. DreamManagerService
    4. MountService
    5. NetworkManagementService
    6. PackageManagerService
    7. usb相关(debug, device, portmanager)
    8. WindowManagerService(screenshotApplicationsInner)
  • android.io线程,主要有用于:
    1. BluetoothManagerService 相关操作
    2. MountService里的obb操作
    3. Tethering 网络共享(usb /wifi/mobile?)
    4. TvInputManagerService tv里channel session相关
  • android.ui主要处理:
    1. AMS UiHandler里show各种msg
    2. DisplayManagerService里的overlay相关msg
    3. PointerEventDispatcher inputevent相关
    4. VoiceInteractionManagerService Voice交互
    5. WindowManagerPolicy init操作
  • AsyncTask #1是我们的AsyncTask所使用的线程。查看AsyncTask源码可知AsyncTask最多可同时启动20个线程,但空闲时只保留1个线程。当然不一定是保留编号为1的线程,所以#后面跟的编号并不一定是1。
    WARNING:新版本谷歌已经将AsyncTask废弃并建议用户使用Concurrent并发包。
  • Binder:511_1~Binder:511_20 SystemServer所使用的Binder线程池,9.0源码里SystemServer的Binder线程数量最多为31个。但小米手机里的有32个,暂时不清楚为什么……
  • queued-work-looper 异步任务所使用的线程,最著名的使用方法是SharedPreference的Apply方法。
USERPIDTIDPPIDCMD
system511612312AccountManagerS
system511556312ActivityManager
system511557312ActivityManager
system511558312ActivityManager
system511559312ActivityManager
system511 1766312AdbDebuggingMan
system511615312AlarmManager
system511535312android.anim
system511536312android.anim.lf
system511543312android.bg
system511534312android.display
system511531312android.fg
system511533312android.io
system511532312android.ui
system511583312AsyncTask #1
system511666312AudioService
system511529312Binder:511_1
…………………………
system5112266312Binder:511_20
system511616312CameraService_p
system511564312FileObserver
system511520312HeapTaskDaemon
system511541312HwBinder:511_1
…………………………
system511815312HwBinder:511_5
system511519312Jit thread pool
system511585312PackageInstalle
system511575312PackageManager
system511577312PackageManager
system511574312PackageManagerB
system5113726312queued-work-loo
system511696312SyncManager
system511560312Thread-2
system511567312Thread-3
system511568312Thread-4
system511570312Thread-5
system511569312Thread-6
system511669312Thread-10
system511685312Thread-11
system511846312Thread-13

部分资料来源:System server里创建常见的几个thread

附加题 Hello World应用进程创建后有多少个线程

    可以看到除了从Zygote继承过来的6个线程之外,系统还为进程创建了Signal CatcherProfile SaverRenderThread以及3个Binder构成的线程池。

  • Signal Catcher 源代码在signal_catcher.cc,具体的启动方式是在runtime.cc的InitNonZygoteOrPostFork方法中启动的,参见SignalCatcher的线程启动。此进程主要功能:一是打印当前进程的堆栈(Java、Native、Kernel),同时把当前虚拟机的一些状态信息也打印出来,并保存在traces.txt文件中;二是进行进程的强制GC并保存GC的profile信息。
  • Profile Saver Profile收集线程,源代码在profile_saver.cc,用于更新app的profile文件,指导dex2oat如何将dex编译成oat文件。Android profile-guided dex2oat
  • RenderThread 渲染线程,Android 5.0之后,Android应用程序的Open GL线程从主线程中独立出来,称为Render Thread。源代码在RenderThread.cpp,具体主线程和渲染线程的分工可以看Android Systrace 基础知识 - MainThread 和 RenderThread 解读。如果你在应用的Application标签下配置android:hardwareAccelerated="false"关闭默认开启的硬件加速则不会有此线程。
USERPIDTIDPPIDCMD
u0_a16964016401291pty_application
u0_a16964016411291Signal Catcher
u0_a16964016414291Jit thread pool
u0_a16964016415291HeapTaskDaemon
u0_a16964016416291ReferenceQueueD
u0_a16964016417291FinalizerDaemon
u0_a16964016418291FinalizerWatchd
u0_a16964016419291Binder:6401_1
u0_a16964016420291Binder:6401_2
u0_a16964016421291Binder:6401_3
u0_a16964016423291Profile Saver
u0_a16964016424291RenderThread

总结

    此次研究仅是对Android系统内部的进程和线程有了一个初步的了解。相对于其他文章的源代码分析、调用链分析,直接的查看系统当前进程、线程运行情况能让初学者对线程和进程的关系、Android启动过程中进程的创建流程有一个更直观的了解。本文适合作为Android各大服务源代码分析的前置文章,仅供各位参考,文章中有任何讹误欢迎在评论区指出,感谢!