目录
1.1.3 ZygoteHooks.nativePreFork
1.2.2 zygote.callPostForkChildHooks
前言
SystemServer就是系统用来启动Framework核心service的入口,如AMS,PMS,WMS等。
Android系统在启动的时候, 在启动两个重要的进程,一个是zygote进程
另一个是由zygote进程fork出来的system_server进程;
/frameworks/base/core/java/com/android/internal/os/
- ZygoteInit.java
- RuntimeInit.java
- Zygote.java
/frameworks/base/core/services/java/com/android/server/
- SystemServer.java
/frameworks/base/core/jni/
- com_android_internal_os_Zygote.cpp
- AndroidRuntime.cpp
/frameworks/base/cmds/app_process/App_main.cpp
一、 systemserver进程创建
//ZygoteInit.java
ZygoteInit.main(){
.....
if (startSystemServer) { //如果参数中包含“start-system-server”就是true
startSystemServer(abiList, socketName);
}
}
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
......
//准备参数, 其中进程名称为system_server
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
//通过fork创建子进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//因为zygote进程socket创建, 子进程就要关闭,否则ams的socket请求就会错乱;
zygoteServer.closeServerSocket();
//子进程返回pid = 0 ,后续启动服务
handleSystemServerProcess(parsedArgs);
}
return true;
}
1.1 Zygote.forkSystemServer
//该函数分为三阶段处理preFork、nativeForkAndSpecialize、postForkCommon。
//VM_HOOKS是Zygote对象的静态成员变量:VM_HOOKS = new ZygoteHooks()
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork(); // 先停止zygote进程中与gc相关的几个线程
...
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
...
VM_HOOKS.postForkCommon(); //fork新进程后将之前停掉的四个Daemon线程启动起来
return pid;
}
1.1.1 ZygoteHooks.preFork
///libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
public void preFork() {
Daemons.stop(); //停止4个Daemon子线程
waitUntilAllThreadsStopped(); //等待所有子线程结束,只保留一个主线程
token = nativePreFork(); //将当前C++中的thread对象地址强转long,保存到token之中,并且完成Runtime中堆的初始化工作
}
//Daemons.java
public static void stop() {
HeapTaskDaemon.INSTANCE.stop(); //Java堆整理线程, 先调用目标线程interrrupt()方法,然后再调用目标线程join()方法,抛出InterruptedException异常后 线程执行完成。
ReferenceQueueDaemon.INSTANCE.stop(); //引用队列线程
FinalizerDaemon.INSTANCE.stop(); //析构线程
FinalizerWatchdogDaemon.INSTANCE.stop(); //析构监控线程
}
private static void waitUntilAllThreadsStopped() {
File tasks = new File("/proc/self/task");
//// 当/proc中线程数大于1,就出让CPU直到只有一个线程,才退出循环
while (tasks.list().length > 1) {
Thread.yield(); //调用yield是
}
}
1.1.2 Daemon.stop
public void stop() {
Thread threadToStop;
synchronized (this) {
threadToStop = thread;
thread = null;
}
if (threadToStop == null) {
throw new IllegalStateException("not running");
}
interrupt(threadToStop); //调用thread.interrupt
while (true) {
try {
threadToStop.join(); //当线程被interrupt之后,再调用join唤醒线程,就会抛出InterruptedException异常,线程结束
return;
} catch (InterruptedException ignored) {
} catch (OutOfMemoryError ignored) {
// An OOME may be thrown if allocating the InterruptedException failed.
}
}
}
/libcore/ojluni/src/main/java/java/lang/Thread.java
public void interrupt() {
nativeInterrupt(); //调用JNI
}
/art/runtime/native/java_lang_Thread.cc
static void Thread_nativeInterrupt(JNIEnv* env, jobject java_thread) {
ScopedFastNativeObjectAccess soa(env);
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = Thread::FromManagedThread(soa, java_thread);
if (thread != nullptr) {
thread->Interrupt(soa.Self());
}
}
/art/runtime/thread.cc
void Thread::Interrupt(Thread* self) {
MutexLock mu(self, *wait_mutex_);
if (interrupted_) {
return;
}
interrupted_ = true; //设置interrupted_为true即可;
NotifyLocked(self);
}
//参数millis = 0, 当线程被interrupt之后,再调用join唤醒线程,就会抛出InterruptedException异常,线程结束
public final void join(long millis) throws InterruptedException {
synchronized(lock) {
long base = System.currentTimeMillis();
long now = 0;
if (millis == 0) {
while (isAlive()) {
lock.wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
lock.wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
}
1.1.3 ZygoteHooks.nativePreFork
/*art/runtime/native/dalvik_system_ZygoteHooks.cc*/
static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
Runtime* runtime = Runtime::Current();
runtime->PreZygoteFork(); // runtime的GC堆初始化,不继续分析了
//将C++ 中的Thread对象 线程转换为long型并保存到token,该过程是非安全的
return reinterpret_cast<jlong>(ThreadForEnv(env));
}
static inline Thread* ThreadForEnv(JNIEnv* env) {
JNIEnvExt* full_env(down_cast<JNIEnvExt*>(env));
return full_env->self; //此处就是C++ 中的Thread对象
}
1.2.1 nativeForkSystemServer
//在该函数中通过调用fork方法,成功的创建了新进程-system_server进程
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
//设置子进程的signal信号处理函数
// zygote监听所有子进程的死亡,如果system_server挂掉,则kill掉zygote ,又因为init监听zygote,继而继续重启相关服务
SetSigChldHandler();
//fork子进程
pid_t pid = fork();
if (pid == 0) { //进入子进程
DetachDescriptors(env, fdsToClose); //关闭并清除文件描述符
....
int rc = setresgid(gid, gid, gid);
rc = setresuid(uid, uid, uid);
SetCapabilities(env, permittedCapabilities, effectiveCapabilities);
SetSchedulerPolicy(env); //设置调度策略
if (se_info_c_str == NULL && is_system_server) {
se_name_c_str = "system_server";
}
if (se_info_c_str != NULL) {
SetThreadName(se_name_c_str); //设置线程名为system_server,方便调试
}
//在Zygote子进程中,设置信号SIGCHLD的处理器恢复为默认行为
UnsetSigChldHandler();
//等价于调用zygote.callPostForkChildHooks()
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
is_system_server ? NULL : instructionSet);
...
} else if (pid > 0) {
//进入父进程,即Zygote进程
}
return pid;
}
1.2.2 zygote.callPostForkChildHooks
先进入了Java世界, 然后其内部调用JNI 方法;
///libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
boolean isZygote, String instructionSet) {
ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
}
//有进入到JNI 世界
static void ZygoteHooks_nativePostForkChild(JNIEnv* env,
jclass,
jlong token,
jint debug_flags,
jboolean is_system_server,
jstring instruction_set) {
Thread* thread = reinterpret_cast<Thread*>(token);
// Our system thread ID, etc, has changed so reset Thread state.
thread->InitAfterFork(); //获取tid值
.....
if (instruction_set != nullptr && !is_system_server) {
......
} else {
//走这个分支
Runtime::Current()->InitNonZygoteOrPostFork(
env, is_system_server, Runtime::NativeBridgeAction::kUnload, nullptr);
}
}
void Runtime::InitNonZygoteOrPostFork(
JNIEnv* env, bool is_system_server, NativeBridgeAction action, const char* isa) {
is_zygote_ = false;
......
// Create the thread pools.
heap_->CreateThreadPool();
// Reset the gc performance data at zygote fork so that the GCs
// before fork aren't attributed to an app.
heap_->ResetGcPerformanceInfo();
....
StartSignalCatcher(); //启动子线程,专门用于捕获3(ANR),10 两个信号
}
1.3.1 VM_HOOKS.postForkCommon
//重新启动4个线程来处理GC内容
public void postForkCommon() {
Daemons.start();
}
public static void start() {
ReferenceQueueDaemon.INSTANCE.start();
FinalizerDaemon.INSTANCE.start();
FinalizerWatchdogDaemon.INSTANCE.start();
HeapTaskDaemon.INSTANCE.start();
}
1.2 handleSystemServerProcess
至此system_server进程就创建出来了,system_server进程的才开始真正工作,那handleSystemServerProcess具体做了些什么呢?
等待下篇文章分析;
二、Fork解释
Fork不需要参数并且返回一个整数值;
fork()返回的不同值:
负值:创建子进程失败;
零:返回到新创建的子进程;
正值:返回父进程或者调用者。该值包含新创建的子进程的进程ID;
Fork函数用来创建一个与当前进程映像一样的子进程,所创建的子进程将复制父进程的代码段,数据 段,BSS段,堆,栈等所有用户空间信息;在内核中操作系统会重新为其申请一个子进程执行的位置;
当进程调用fork后控制转入内核,内核会做4件事;
1.分配新的内存块和内核数据结构给子进程
2.将父进程部分数据结构内容(数据结构,堆栈等)拷贝到子进程
3.添加子进程到系统进程列表中
4.fork返回开始调度器调度