Android重要线程进程一览

前言

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

Android重要进程一览

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

USER PID PPID NAME
root 1 0 init
root 151 1 init
root 312 1 Zygote64
system 179 1 servicemanager
system 180 1 hwservicemanager
system 511 312 system_server
shell 4149 1745 ps
  • 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的进程下的所有线程。

USER PID TID PPID CMD
root 1 1 0 init
root 1 150 0 init

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

USER PID TID PPID CMD
root 151 151 1 init
  • PID代表进程的ID。
  • TID代表线程ID。
  • PPID代表父进程ID,即创建该进程的进程ID。

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

Zygote64进程下线程一览

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

USER PID TID PPID CMD
root 312 312 1 main
root 312 7390 1 Jit thread pool
root 312 7391 1 HeapTaskDaemon
root 312 7392 1 ReferenceQueueD
root 312 7393 1 FinalizerDaemon
root 312 7394 1 FinalizerWatchd
  • 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服务的管理。

USER PID TID PPID CMD
system 179 179 1 servicemanager

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方法。
USER PID TID PPID CMD
system 511 612 312 AccountManagerS
system 511 556 312 ActivityManager
system 511 557 312 ActivityManager
system 511 558 312 ActivityManager
system 511 559 312 ActivityManager
system 511  1766 312 AdbDebuggingMan
system 511 615 312 AlarmManager
system 511 535 312 android.anim
system 511 536 312 android.anim.lf
system 511 543 312 android.bg
system 511 534 312 android.display
system 511 531 312 android.fg
system 511 533 312 android.io
system 511 532 312 android.ui
system 511 583 312 AsyncTask #1
system 511 666 312 AudioService
system 511 529 312 Binder:511_1
…… …… …… …… ……
system 511 2266 312 Binder:511_20
system 511 616 312 CameraService_p
system 511 564 312 FileObserver
system 511 520 312 HeapTaskDaemon
system 511 541 312 HwBinder:511_1
…… …… …… …… ……
system 511 815 312 HwBinder:511_5
system 511 519 312 Jit thread pool
system 511 585 312 PackageInstalle
system 511 575 312 PackageManager
system 511 577 312 PackageManager
system 511 574 312 PackageManagerB
system 511 3726 312 queued-work-loo
system 511 696 312 SyncManager
system 511 560 312 Thread-2
system 511 567 312 Thread-3
system 511 568 312 Thread-4
system 511 570 312 Thread-5
system 511 569 312 Thread-6
system 511 669 312 Thread-10
system 511 685 312 Thread-11
system 511 846 312 Thread-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"关闭默认开启的硬件加速则不会有此线程。
USER PID TID PPID CMD
u0_a169 6401 6401 291 pty_application
u0_a169 6401 6411 291 Signal Catcher
u0_a169 6401 6414 291 Jit thread pool
u0_a169 6401 6415 291 HeapTaskDaemon
u0_a169 6401 6416 291 ReferenceQueueD
u0_a169 6401 6417 291 FinalizerDaemon
u0_a169 6401 6418 291 FinalizerWatchd
u0_a169 6401 6419 291 Binder:6401_1
u0_a169 6401 6420 291 Binder:6401_2
u0_a169 6401 6421 291 Binder:6401_3
u0_a169 6401 6423 291 Profile Saver
u0_a169 6401 6424 291 RenderThread

总结

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

猜你喜欢

转载自juejin.im/post/7017110202658848775