用开源源码做淘宝客网站,保险网上预约,上海网站设计公司 静安,wordpress 页面导出Zygote的启动流程
Init进程启动后#xff0c;会加载并执行init.rc文件。该.rc文件中#xff0c;就包含启动Zygote进程的Action。详见“RC文件解析”章节。
根据Zygote对应的RC文件#xff0c;可知Zygote进程是由/system/bin/app_process程序来创建的。
app_process大致处…Zygote的启动流程
Init进程启动后会加载并执行init.rc文件。该.rc文件中就包含启动Zygote进程的Action。详见“RC文件解析”章节。
根据Zygote对应的RC文件可知Zygote进程是由/system/bin/app_process程序来创建的。
app_process大致处理流程如下详见“app_process解析”章节。
创建AppRuntime整理传参并将相应参数传给Runtime或Zygote进程。使用Runtime调用start方法传入“com.android.internal.os.ZygoteInit”类和zygote传参启动zygote。
class AppRuntime 继承自 public AndroidRuntime。调用start方法后将执行以下步骤。详见AndroidRuntime解析章节。
搜集JVM参数启动VM注册JNI方法。利用java的反射调用com.android.internal.os.ZygoteInit类中的main方法创建zygote进程。 Zygote代码分析
RC文件解析
Init.rc中的Zygote内容
init.rc中涉及Zygote的部分有五处。从代码中可以看出在初始化晚期阶段late-init会触发Zygote-start行为而该行为会创建zygote以及zygote_secondary两个进程。
import /system/etc/init/hw/init.${ro.zygote}.rcimport /system/etc/init/hw/init.boringssl.${ro.zygote}.rc...on late-inittrigger zygote-start...on zygote-startwait_for_prop odsign.verification.done 1# A/B update verifier that marks a successful boot.exec_start update_verifierstart statsdstart netdstart zygotestart zygote_secondary...on userspace-reboot-resumetrigger userspace-reboot-fs-remounttrigger post-fs-datatrigger zygote-starttrigger early-boottrigger boot
关于如何启动这两个进程可以参照init.${ro.zygote}.rc。${ro.zygote}的值可以通过shell指令“getprop ro.zygote”获取。以下图为例zygote64_32代表64模式为主32位模式为辅。 init.zygote64_32.rc
引用了init.zygote64.rc
声明了一个名字为“zygote_secondary”的service。该service将有/system/bin/app_process进程来启动。其中以“-”开头的是JVM参数-Xzygote /system/bin。以“--”开头的是进程参数--zygote --socket-namezygote_secondary --enable-lazy-preload。
创建了两个socket名字为zygote_secondary和usap_pool_secondary。
import /system/etc/init/hw/init.zygote64.rcservice zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-namezygote_secondary --enable-lazy-preloadclass mainpriority -20user rootgroup root readproc reserved_disksocket zygote_secondary stream 660 root systemsocket usap_pool_secondary stream 660 root systemonrestart restart zygotetask_profiles ProcessCapacityHigh MaxPerformanceinit.zygote64.rc
声明了一个名字为“zygote”的service。该service将有/system/bin/app_process进程来启动。其中以“-”开头的是JVM参数-Xzygote /system/bin。以“--”开头的是进程参数--zygote --start-system-server --socket-namezygote。
创建了两个socket名字为zygote和usap_pool_primary。
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-namezygoteclass mainpriority -20user rootgroup root readproc reserved_disksocket zygote stream 660 root systemsocket usap_pool_primary stream 660 root systemonrestart exec_background - system system -- /system/bin/vdc volume abort_fuseonrestart write /sys/power/state on# NOTE: If the wakelock name here is changed, then also# update it in SystemSuspend.cpponrestart write /sys/power/wake_lock zygote_kwlonrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart --only-if-running media.tuneronrestart restart netdonrestart restart wificondtask_profiles ProcessCapacityHigh MaxPerformancecritical window${zygote.critical_window.minute:-off} targetzygote-fatal
init.boringssl.zygote64_32.rc
包含的都是在某些条件下触发的自测进程。了解即可。
on init property:ro.product.cpu.abilist32*exec_start boringssl_self_test32
on init property:ro.product.cpu.abilist64*exec_start boringssl_self_test64
on property:apexd.statusready property:ro.product.cpu.abilist32*exec_start boringssl_self_test_apex32
on property:apexd.statusready property:ro.product.cpu.abilist64*exec_start boringssl_self_test_apex64
app_process解析
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{if (!LOG_NDEBUG) {String8 argv_String;for (int i 0; i argc; i) {argv_String.append(\);argv_String.append(argv[i]);argv_String.append(\ );}ALOGV(app_process main with argv: %s, argv_String.c_str());}//步骤1创建Runtime.--------------------------------------------AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// Process command line arguments// ignore argv[0]argc--;argv;// Everything up to -- or first non - arg goes to the vm.//// The first argument after the VM args is the parent dir, which// is currently unused.//// After the parent dir, we expect one or more the following internal// arguments ://// --zygote : Start in zygote mode// --start-system-server : Start the system server.// --application : Start in application (stand alone, non zygote) mode.// --nice-name : The nice name for this process.//// For non zygote starts, these arguments will be followed by// the main class name. All remaining arguments are passed to// the main method of this class.//// For zygote starts, all remaining arguments are passed to the zygote.// main function.//// Note that we must copy argument string values since we will rewrite the// entire argument block when we apply the nice name to argv0.//// As an exception to the above rule, anything in spaced commands// goes to the vm even though it has a space in it.const char* spaced_commands[] { -cp, -classpath };// Allow spaced commands to be succeeded by exactly 1 argument (regardless of -s).bool known_command false;//步骤2解析传参将-开头的参数传给Runtime.--------------------------------------------int i;for (i 0; i argc; i) {if (known_command true) {runtime.addOption(strdup(argv[i]));// The static analyzer gets upset that we dont ever free the above// string. Since the allocation is from main, leaking it doesnt seem// problematic. NOLINTNEXTLINEALOGV(app_process main add known option %s, argv[i]);known_command false;continue;}for (int j 0;j static_castint(sizeof(spaced_commands) / sizeof(spaced_commands[0]));j) {if (strcmp(argv[i], spaced_commands[j]) 0) {known_command true;ALOGV(app_process main found known command %s, argv[i]);}}if (argv[i][0] ! -) {break;}if (argv[i][1] - argv[i][2] 0) {i; // Skip --.break;}runtime.addOption(strdup(argv[i]));// The static analyzer gets upset that we dont ever free the above// string. Since the allocation is from main, leaking it doesnt seem// problematic. NOLINTNEXTLINEALOGV(app_process main add option %s, argv[i]);}// Parse runtime arguments. Stop at first unrecognized option.bool zygote false;bool startSystemServer false;bool application false;String8 niceName;String8 className;//步骤3整理zygote进程的传参.--------------------------------------------i; // Skip unused parent dir argument.while (i argc) {const char* arg argv[i];if (strcmp(arg, --zygote) 0) {zygote true;niceName ZYGOTE_NICE_NAME;} else if (strcmp(arg, --start-system-server) 0) {startSystemServer true;} else if (strcmp(arg, --application) 0) {application true;} else if (strncmp(arg, --nice-name, 12) 0) {niceName (arg 12);} else if (strncmp(arg, --, 2) ! 0) {className arg;break;} else {--i;break;}}//步骤4根据整理的zygote传参判断是否是zygote进程并根据判断结果补充“--abi-list”和“start-system-server”传参.--------------------------------------------VectorString8 args;if (!className.empty()) {// Were not in zygote mode, the only argument we need to pass// to RuntimeInit is the application argument.//// The Remainder of args get passed to startup class main(). Make// copies of them before we overwrite them with the process name.args.add(application ? String8(application) : String8(tool));runtime.setClassNameAndArgs(className, argc - i, argv i);if (!LOG_NDEBUG) {String8 restOfArgs;char* const* argv_new argv i;int argc_new argc - i;for (int k 0; k argc_new; k) {restOfArgs.append(\);restOfArgs.append(argv_new[k]);restOfArgs.append(\ );}ALOGV(Class name %s, args %s, className.c_str(), restOfArgs.c_str());}} else {// Were in zygote mode.maybeCreateDalvikCache();if (startSystemServer) {args.add(String8(start-system-server));}char prop[PROP_VALUE_MAX];if (property_get(ABI_LIST_PROPERTY, prop, NULL) 0) {LOG_ALWAYS_FATAL(app_process: Unable to determine ABI list from property %s.,ABI_LIST_PROPERTY);return 11;}String8 abiFlag(--abi-list);abiFlag.append(prop);args.add(abiFlag);// In zygote mode, pass all remaining arguments to the zygote// main() method.for (; i argc; i) {args.add(String8(argv[i]));}}if (!niceName.empty()) {runtime.setArgv0(niceName.c_str(), true /* setProcName */);}
//步骤5使用runtime调用“com.android.internal.os.ZygoteInit”类并传入传参启动zygote.--------------------------------------------if (zygote) {runtime.start(com.android.internal.os.ZygoteInit, args, zygote);} else if (!className.empty()) {runtime.start(com.android.internal.os.RuntimeInit, args, zygote);} else {fprintf(stderr, Error: no class name or --zygote supplied.\n);app_usage();LOG_ALWAYS_FATAL(app_process: no class name or --zygote supplied.);}
}AndroidRuntime解析
frameworks/base/core/jni/AndroidRuntime.cpp
Runtime的start方法
void AndroidRuntime::start(const char* className, const VectorString8 options, bool zygote)
{ALOGD( START %s uid %d \n,className ! NULL ? className : (unknown), getuid());static const String8 startSystemServer(start-system-server);// Whether this is the primary zygote, meaning the zygote which will fork system server.bool primary_zygote false;//步骤1必要的参数及环境变量检查。-----------------------------------/** startSystemServer true means runtime is obsolete and not run from* init.rc anymore, so we print out the boot start event here.*/for (size_t i 0; i options.size(); i) {if (options[i] startSystemServer) {primary_zygote true;/* track our progress through the boot sequence */const int LOG_BOOT_PROGRESS_START 3000;LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));}}const char* rootDir getenv(ANDROID_ROOT);if (rootDir NULL) {rootDir /system;if (!hasDir(/system)) {LOG_FATAL(No root directory specified, and /system does not exist.);return;}setenv(ANDROID_ROOT, rootDir, 1);}const char* artRootDir getenv(ANDROID_ART_ROOT);if (artRootDir NULL) {LOG_FATAL(No ART directory specified with ANDROID_ART_ROOT environment variable.);return;}const char* i18nRootDir getenv(ANDROID_I18N_ROOT);if (i18nRootDir NULL) {LOG_FATAL(No runtime directory specified with ANDROID_I18N_ROOT environment variable.);return;}const char* tzdataRootDir getenv(ANDROID_TZDATA_ROOT);if (tzdataRootDir NULL) {LOG_FATAL(No tz data directory specified with ANDROID_TZDATA_ROOT environment variable.);return;}//const char* kernelHack getenv(LD_ASSUME_KERNEL);//ALOGD(Found LD_ASSUME_KERNEL%s\n, kernelHack);//步骤2启动VM。-----------------------------------/* start the virtual machine */JniInvocation jni_invocation;jni_invocation.Init(NULL);JNIEnv* env;if (startVm(mJavaVM, env, zygote, primary_zygote) ! 0) {return;}onVmCreated(env);/** Register android functions.*/
//步骤3注册JNI方法。-----------------------------------if (startReg(env) 0) {ALOGE(Unable to register all android natives\n);return;}/** We want to call main() with a String array with arguments in it.* At present we have two arguments, the class name and an option string.* Create an array to hold them.*/jclass stringClass;jobjectArray strArray;jstring classNameStr;stringClass env-FindClass(java/lang/String);assert(stringClass ! NULL);strArray env-NewObjectArray(options.size() 1, stringClass, NULL);assert(strArray ! NULL);classNameStr env-NewStringUTF(className);assert(classNameStr ! NULL);env-SetObjectArrayElement(strArray, 0, classNameStr);for (size_t i 0; i options.size(); i) {jstring optionsStr env-NewStringUTF(options.itemAt(i).c_str());assert(optionsStr ! NULL);env-SetObjectArrayElement(strArray, i 1, optionsStr);}//步骤4利用java的反射调用com.android.internal.os.ZygoteInit类中的main方法创建zygote进程。-----------------------------------/** Start VM. This thread becomes the main thread of the VM, and will* not return until the VM exits.*/char* slashClassName toSlashClassName(className ! NULL ? className : );jclass startClass env-FindClass(slashClassName);if (startClass NULL) {ALOGE(JavaVM unable to locate class %s\n, slashClassName);/* keep going */} else {jmethodID startMeth env-GetStaticMethodID(startClass, main,([Ljava/lang/String;)V);if (startMeth NULL) {ALOGE(JavaVM unable to find main() in %s\n, className);/* keep going */} else {env-CallStaticVoidMethod(startClass, startMeth, strArray);#if 0if (env-ExceptionCheck())threadExitUncaughtException(env);
#endif}}free(slashClassName);ALOGD(Shutting down VM\n);if (mJavaVM-DetachCurrentThread() ! JNI_OK)ALOGW(Warning: unable to detach main thread\n);if (mJavaVM-DestroyJavaVM() ! 0)ALOGW(Warning: VM did not shut down cleanly\n);
}启动VM
该方法有600行都是收集VM参数并调用JNI_CreateJavaVM启动VM。参数是一个可以做性能优化的点。了解即可。
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote)
{JavaVMInitArgs initArgs;char propBuf[PROPERTY_VALUE_MAX];char jniOptsBuf[sizeof(-Xjniopts:)-1 PROPERTY_VALUE_MAX];char heapstartsizeOptsBuf[sizeof(-Xms)-1 PROPERTY_VALUE_MAX];char heapsizeOptsBuf[sizeof(-Xmx)-1 PROPERTY_VALUE_MAX];char heapgrowthlimitOptsBuf[sizeof(-XX:HeapGrowthLimit)-1 PROPERTY_VALUE_MAX];char heapminfreeOptsBuf[sizeof(-XX:HeapMinFree)-1 PROPERTY_VALUE_MAX];char heapmaxfreeOptsBuf[sizeof(-XX:HeapMaxFree)-1 PROPERTY_VALUE_MAX];char usejitOptsBuf[sizeof(-Xusejit:)-1 PROPERTY_VALUE_MAX];char jitpthreadpriorityOptsBuf[sizeof(-Xjitpthreadpriority:)-1 PROPERTY_VALUE_MAX];char jitmaxsizeOptsBuf[sizeof(-Xjitmaxsize:)-1 PROPERTY_VALUE_MAX];char jitinitialsizeOptsBuf[sizeof(-Xjitinitialsize:)-1 PROPERTY_VALUE_MAX];char jitthresholdOptsBuf[sizeof(-Xjitthreshold:)-1 PROPERTY_VALUE_MAX];char jitprithreadweightOptBuf[sizeof(-Xjitprithreadweight:)-1 PROPERTY_VALUE_MAX];char jittransitionweightOptBuf[sizeof(-Xjittransitionweight:)-1 PROPERTY_VALUE_MAX];char hotstartupsamplesOptsBuf[sizeof(-Xps-hot-startup-method-samples:)-1 PROPERTY_VALUE_MAX];char saveResolvedClassesDelayMsOptsBuf[sizeof(-Xps-save-resolved-classes-delay-ms:)-1 PROPERTY_VALUE_MAX];char profileMinSavePeriodOptsBuf[sizeof(-Xps-min-save-period-ms:)-1 PROPERTY_VALUE_MAX];char profileMinFirstSaveOptsBuf[sizeof(-Xps-min-first-save-ms:) - 1 PROPERTY_VALUE_MAX];char profileInlineCacheThresholdOptsBuf[sizeof(-Xps-inline-cache-threshold:) - 1 PROPERTY_VALUE_MAX];char madviseWillNeedFileSizeVdex[sizeof(-XMadviseWillNeedVdexFileSize:)-1 PROPERTY_VALUE_MAX];char madviseWillNeedFileSizeOdex[sizeof(-XMadviseWillNeedOdexFileSize:)-1 PROPERTY_VALUE_MAX];char madviseWillNeedFileSizeArt[sizeof(-XMadviseWillNeedArtFileSize:)-1 PROPERTY_VALUE_MAX];char gctypeOptsBuf[sizeof(-Xgc:)-1 PROPERTY_VALUE_MAX];char backgroundgcOptsBuf[sizeof(-XX:BackgroundGC)-1 PROPERTY_VALUE_MAX];char heaptargetutilizationOptsBuf[sizeof(-XX:HeapTargetUtilization)-1 PROPERTY_VALUE_MAX];char foregroundHeapGrowthMultiplierOptsBuf[sizeof(-XX:ForegroundHeapGrowthMultiplier)-1 PROPERTY_VALUE_MAX];char finalizerTimeoutMsOptsBuf[sizeof(-XX:FinalizerTimeoutMs)-1 PROPERTY_VALUE_MAX];char threadSuspendTimeoutOptsBuf[sizeof(-XX:ThreadSuspendTimeout)-1 PROPERTY_VALUE_MAX];char cachePruneBuf[sizeof(-Xzygote-max-boot-retry)-1 PROPERTY_VALUE_MAX];char dex2oatXmsImageFlagsBuf[sizeof(-Xms)-1 PROPERTY_VALUE_MAX];char dex2oatXmxImageFlagsBuf[sizeof(-Xmx)-1 PROPERTY_VALUE_MAX];char dex2oatCompilerFilterBuf[sizeof(--compiler-filter)-1 PROPERTY_VALUE_MAX];char dex2oatImageCompilerFilterBuf[sizeof(--compiler-filter)-1 PROPERTY_VALUE_MAX];char dex2oatThreadsBuf[sizeof(-j)-1 PROPERTY_VALUE_MAX];char dex2oatThreadsImageBuf[sizeof(-j)-1 PROPERTY_VALUE_MAX];char dex2oatCpuSetBuf[sizeof(--cpu-set)-1 PROPERTY_VALUE_MAX];char dex2oatCpuSetImageBuf[sizeof(--cpu-set)-1 PROPERTY_VALUE_MAX];char dex2oat_isa_variant_key[PROPERTY_KEY_MAX];char dex2oat_isa_variant[sizeof(--instruction-set-variant) -1 PROPERTY_VALUE_MAX];char dex2oat_isa_features_key[PROPERTY_KEY_MAX];char dex2oat_isa_features[sizeof(--instruction-set-features) -1 PROPERTY_VALUE_MAX];char dex2oatFlagsBuf[PROPERTY_VALUE_MAX];char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];char extraOptsBuf[PROPERTY_VALUE_MAX];char perfettoHprofOptBuf[sizeof(-XX:PerfettoHprof) PROPERTY_VALUE_MAX];char perfettoJavaHeapStackOptBuf[sizeof(-XX:PerfettoJavaHeapStackProf) PROPERTY_VALUE_MAX];enum {kEMDefault,kEMIntPortable,kEMIntFast,kEMJitCompiler,} executionMode kEMDefault;char localeOption[sizeof(-Duser.locale) PROPERTY_VALUE_MAX];char lockProfThresholdBuf[sizeof(-Xlockprofthreshold:)-1 PROPERTY_VALUE_MAX];char nativeBridgeLibrary[sizeof(-XX:NativeBridge) PROPERTY_VALUE_MAX];char cpuAbiListBuf[sizeof(--cpu-abilist) PROPERTY_VALUE_MAX];char corePlatformApiPolicyBuf[sizeof(-Xcore-platform-api-policy:) PROPERTY_VALUE_MAX];char methodTraceFileBuf[sizeof(-Xmethod-trace-file:) PROPERTY_VALUE_MAX];char methodTraceFileSizeBuf[sizeof(-Xmethod-trace-file-size:) PROPERTY_VALUE_MAX];std::string fingerprintBuf;char javaZygoteForkLoopBuf[sizeof(-XX:ForceJavaZygoteForkLoop) PROPERTY_VALUE_MAX];char jdwpProviderBuf[sizeof(-XjdwpProvider:) - 1 PROPERTY_VALUE_MAX];char opaqueJniIds[sizeof(-Xopaque-jni-ids:) - 1 PROPERTY_VALUE_MAX];char bootImageBuf[sizeof(-Ximage:) - 1 PROPERTY_VALUE_MAX];// Read if we are using the profile configuration, do this at the start since the last ART args// take precedence.std::string profile_boot_class_path_flag server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,PROFILE_BOOT_CLASS_PATH,/*default_value*/);bool profile_boot_class_path;switch (ParseBool(profile_boot_class_path_flag)) {case ParseBoolResult::kError:// Default to the system property.profile_boot_class_path GetBoolProperty(dalvik.vm.profilebootclasspath, /*default_value*/false);break;case ParseBoolResult::kTrue:profile_boot_class_path true;break;case ParseBoolResult::kFalse:profile_boot_class_path false;break;}if (profile_boot_class_path) {addOption(-Xcompiler-option);addOption(--count-hotness-in-compiled-code);addOption(-Xps-profile-boot-class-path);addOption(-Xps-profile-aot-code);addOption(-Xjitsaveprofilinginfo);}std::string use_jitzygote_image_flag server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,ENABLE_JITZYGOTE_IMAGE,/*default_value*/);// Use the APEX boot image for boot class path profiling to get JIT samples on BCP methods.// Also use the APEX boot image if its explicitly enabled via configuration flag.const bool use_apex_image profile_boot_class_path || (use_jitzygote_image_flag true);if (use_apex_image) {ALOGI(Using JIT Zygote image: %s\n, kJitZygoteImageOption);addOption(kJitZygoteImageOption);} else if (parseRuntimeOption(dalvik.vm.boot-image, bootImageBuf, -Ximage:)) {ALOGI(Using dalvik.vm.boot-image: %s\n, bootImageBuf);} else {ALOGI(Using default boot image);}std::string disable_lock_profiling server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,DISABLE_LOCK_PROFILING,/*default_value*/ );if (disable_lock_profiling true) {addOption(kLockProfThresholdRuntimeOption);ALOGI(Disabling lock profiling: %s\n, kLockProfThresholdRuntimeOption);} else {ALOGI(Leaving lock profiling enabled);}const bool checkJni GetBoolProperty(dalvik.vm.checkjni, false);if (checkJni) {ALOGD(CheckJNI is ON);/* extended JNI checking */addOption(-Xcheck:jni);/* with -Xcheck:jni, this provides a JNI function call trace *///addOption(-verbose:jni);}const bool odsignVerificationSuccess GetBoolProperty(odsign.verification.success, false);if (!odsignVerificationSuccess) {addOption(-Xdeny-art-apex-data-files);}property_get(dalvik.vm.execution-mode, propBuf, );if (strcmp(propBuf, int:portable) 0) {executionMode kEMIntPortable;} else if (strcmp(propBuf, int:fast) 0) {executionMode kEMIntFast;} else if (strcmp(propBuf, int:jit) 0) {executionMode kEMJitCompiler;}strcpy(jniOptsBuf, -Xjniopts:);if (parseRuntimeOption(dalvik.vm.jniopts, jniOptsBuf, -Xjniopts:)) {ALOGI(JNI options: %s\n, jniOptsBuf);}/* route exit() to our handler */addOption(exit, (void*) runtime_exit);/* route fprintf() to our handler */addOption(vfprintf, (void*) runtime_vfprintf);/* register the framework-specific is sensitive thread hook */addOption(sensitiveThread, (void*) runtime_isSensitiveThread);/* enable verbose; standard options are { jni, gc, class } *///addOption(-verbose:jni);addOption(-verbose:gc);//addOption(-verbose:class);// On Android, we always want to allow loading the PerfettoHprof plugin.// Even with this option set, we will still only actually load the plugin// if we are on a userdebug build or the app is debuggable or profileable.// This is enforced in art/runtime/runtime.cc.//// We want to be able to disable this, because this does not work on host,// and we do not want to enable it in tests.parseRuntimeOption(dalvik.vm.perfetto_hprof, perfettoHprofOptBuf, -XX:PerfettoHprof,true);// Enable PerfettoJavaHeapStackProf in the zygoteparseRuntimeOption(dalvik.vm.perfetto_javaheap, perfettoJavaHeapStackOptBuf,-XX:PerfettoJavaHeapStackProf, true);if (primary_zygote) {addOption(-Xprimaryzygote);}/** The default starting and maximum size of the heap. Larger* values should be specified in a product property override.*/parseRuntimeOption(dalvik.vm.heapstartsize, heapstartsizeOptsBuf, -Xms, 4m);parseRuntimeOption(dalvik.vm.heapsize, heapsizeOptsBuf, -Xmx, 16m);parseRuntimeOption(dalvik.vm.heapgrowthlimit, heapgrowthlimitOptsBuf, -XX:HeapGrowthLimit);parseRuntimeOption(dalvik.vm.heapminfree, heapminfreeOptsBuf, -XX:HeapMinFree);parseRuntimeOption(dalvik.vm.heapmaxfree, heapmaxfreeOptsBuf, -XX:HeapMaxFree);parseRuntimeOption(dalvik.vm.heaptargetutilization,heaptargetutilizationOptsBuf,-XX:HeapTargetUtilization);/* Foreground heap growth multiplier option */parseRuntimeOption(dalvik.vm.foreground-heap-growth-multiplier,foregroundHeapGrowthMultiplierOptsBuf,-XX:ForegroundHeapGrowthMultiplier);/** Finalizer and thread suspend timeouts.*/parseRuntimeOption(dalvik.vm.finalizer-timeout-ms,finalizerTimeoutMsOptsBuf,-XX:FinalizerTimeoutMs);parseRuntimeOption(dalvik.vm.thread-suspend-timeout-ms,threadSuspendTimeoutOptsBuf,-XX:ThreadSuspendTimeout);/** JIT related options.*/parseRuntimeOption(dalvik.vm.usejit, usejitOptsBuf, -Xusejit:);parseRuntimeOption(dalvik.vm.jitmaxsize, jitmaxsizeOptsBuf, -Xjitmaxsize:);parseRuntimeOption(dalvik.vm.jitinitialsize, jitinitialsizeOptsBuf, -Xjitinitialsize:);parseRuntimeOption(dalvik.vm.jitthreshold, jitthresholdOptsBuf, -Xjitthreshold:);parseRuntimeOption(dalvik.vm.jitpthreadpriority,jitpthreadpriorityOptsBuf,-Xjitpthreadpriority:);addOption(-Xjitsaveprofilinginfo);parseRuntimeOption(dalvik.vm.jitprithreadweight,jitprithreadweightOptBuf,-Xjitprithreadweight:);parseRuntimeOption(dalvik.vm.jittransitionweight, jittransitionweightOptBuf,-Xjittransitionweight:);/** Use default platform configuration as limits for madvising,* when no properties are specified.*/parseRuntimeOption(dalvik.vm.madvise.vdexfile.size,madviseWillNeedFileSizeVdex,-XMadviseWillNeedVdexFileSize:);parseRuntimeOption(dalvik.vm.madvise.odexfile.size,madviseWillNeedFileSizeOdex,-XMadviseWillNeedOdexFileSize:);parseRuntimeOption(dalvik.vm.madvise.artfile.size,madviseWillNeedFileSizeArt,-XMadviseWillNeedArtFileSize:);/** Profile related options.*/parseRuntimeOption(dalvik.vm.hot-startup-method-samples, hotstartupsamplesOptsBuf,-Xps-hot-startup-method-samples:);parseRuntimeOption(dalvik.vm.ps-resolved-classes-delay-ms, saveResolvedClassesDelayMsOptsBuf,-Xps-save-resolved-classes-delay-ms:);parseRuntimeOption(dalvik.vm.ps-min-save-period-ms, profileMinSavePeriodOptsBuf,-Xps-min-save-period-ms:);parseRuntimeOption(dalvik.vm.ps-min-first-save-ms, profileMinFirstSaveOptsBuf,-Xps-min-first-save-ms:);parseRuntimeOption(dalvik.vm.ps-inline-cache-threshold, profileInlineCacheThresholdOptsBuf,-Xps-inline-cache-threshold:);property_get(ro.config.low_ram, propBuf, );if (strcmp(propBuf, true) 0) {addOption(-XX:LowMemoryMode);}/** Garbage-collection related options.*/parseRuntimeOption(dalvik.vm.gctype, gctypeOptsBuf, -Xgc:);// If it set, honor the enable_generational_cc device configuration;// otherwise, let the runtime use its default behavior.std::string enable_generational_cc server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,ENABLE_GENERATIONAL_CC,/*default_value*/ );if (enable_generational_cc true) {addOption(kGenerationalCCRuntimeOption);} else if (enable_generational_cc false) {addOption(kNoGenerationalCCRuntimeOption);}parseRuntimeOption(dalvik.vm.backgroundgctype, backgroundgcOptsBuf, -XX:BackgroundGC);/** Enable/disable zygote native fork loop.*/parseRuntimeOption(dalvik.vm.force-java-zygote-fork-loop,javaZygoteForkLoopBuf,-XX:ForceJavaZygoteForkLoop);/** Enable debugging only for apps forked from zygote.*/if (zygote) {// Set the JDWP provider and required arguments. By default let the runtime choose how JDWP is// implemented. When this is not set the runtime defaults to not allowing JDWP.addOption(-XjdwpOptions:suspendn,servery);parseRuntimeOption(dalvik.vm.jdwp-provider,jdwpProviderBuf,-XjdwpProvider:,default);}// Only pass an explicit opaque-jni-ids to apps forked from zygoteif (zygote) {parseRuntimeOption(dalvik.vm.opaque-jni-ids,opaqueJniIds,-Xopaque-jni-ids:,swapable);}parseRuntimeOption(dalvik.vm.lockprof.threshold,lockProfThresholdBuf,-Xlockprofthreshold:);if (executionMode kEMIntPortable) {addOption(-Xint:portable);} else if (executionMode kEMIntFast) {addOption(-Xint:fast);} else if (executionMode kEMJitCompiler) {addOption(-Xint:jit);}// Extra options for JIT.parseCompilerOption(dalvik.vm.dex2oat-filter, dex2oatCompilerFilterBuf,--compiler-filter, -Xcompiler-option);parseCompilerOption(dalvik.vm.dex2oat-threads, dex2oatThreadsBuf, -j, -Xcompiler-option);parseCompilerOption(dalvik.vm.dex2oat-cpu-set, dex2oatCpuSetBuf, --cpu-set,-Xcompiler-option);// Copy the variant.sprintf(dex2oat_isa_variant_key, dalvik.vm.isa.%s.variant, ABI_STRING);parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant,--instruction-set-variant, -Xcompiler-option);// Copy the features.sprintf(dex2oat_isa_features_key, dalvik.vm.isa.%s.features, ABI_STRING);parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,--instruction-set-features, -Xcompiler-option);/** When running with debug.generate-debug-info, add --generate-debug-info to the compiler* options so that both JITted code and the boot image, if it is compiled on device, will* include native debugging information.*/property_get(debug.generate-debug-info, propBuf, );bool generate_debug_info (strcmp(propBuf, true) 0);if (generate_debug_info) {addOption(-Xcompiler-option);addOption(--generate-debug-info);}// The mini-debug-info makes it possible to backtrace through compiled code.bool generate_mini_debug_info property_get_bool(dalvik.vm.minidebuginfo, 0);if (generate_mini_debug_info) {addOption(-Xcompiler-option);addOption(--generate-mini-debug-info);}property_get(dalvik.vm.dex2oat-flags, dex2oatFlagsBuf, );parseExtraOpts(dex2oatFlagsBuf, -Xcompiler-option);/* extra options; parse this late so it overrides others */property_get(dalvik.vm.extra-opts, extraOptsBuf, );parseExtraOpts(extraOptsBuf, NULL);// Extra options for boot image generation.parseCompilerRuntimeOption(dalvik.vm.image-dex2oat-Xms, dex2oatXmsImageFlagsBuf,-Xms, -Ximage-compiler-option);parseCompilerRuntimeOption(dalvik.vm.image-dex2oat-Xmx, dex2oatXmxImageFlagsBuf,-Xmx, -Ximage-compiler-option);parseCompilerOption(dalvik.vm.image-dex2oat-filter, dex2oatImageCompilerFilterBuf,--compiler-filter, -Ximage-compiler-option);// If there is a dirty-image-objects file, push it.if (hasFile(/system/etc/dirty-image-objects)) {addOption(-Ximage-compiler-option);addOption(--dirty-image-objects/system/etc/dirty-image-objects);}parseCompilerOption(dalvik.vm.image-dex2oat-threads, dex2oatThreadsImageBuf, -j,-Ximage-compiler-option);parseCompilerOption(dalvik.vm.image-dex2oat-cpu-set, dex2oatCpuSetImageBuf, --cpu-set,-Ximage-compiler-option);// The runtime may compile a boot image, when necessary, not using installd. Thus, we need// to pass the instruction-set-features/variant as an image-compiler-option.// Note: it is OK to reuse the buffer, as the values are exactly the same between// * compiler-option, used for runtime compilation (DexClassLoader)// * image-compiler-option, used for boot-image compilation on deviceparseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant,--instruction-set-variant, -Ximage-compiler-option);parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,--instruction-set-features, -Ximage-compiler-option);if (generate_debug_info) {addOption(-Ximage-compiler-option);addOption(--generate-debug-info);}if (generate_mini_debug_info) {addOption(-Ximage-compiler-option);addOption(--generate-mini-debug-info);}property_get(dalvik.vm.image-dex2oat-flags, dex2oatImageFlagsBuf, );parseExtraOpts(dex2oatImageFlagsBuf, -Ximage-compiler-option);/* Set the properties for locale */{strcpy(localeOption, -Duser.locale);const std::string locale readLocale();strncat(localeOption, locale.c_str(), PROPERTY_VALUE_MAX);addOption(localeOption);}// Trace files are stored in /data/misc/trace which is writable only in debug mode.property_get(ro.debuggable, propBuf, 0);if (strcmp(propBuf, 1) 0) {property_get(dalvik.vm.method-trace, propBuf, false);if (strcmp(propBuf, true) 0) {addOption(-Xmethod-trace);parseRuntimeOption(dalvik.vm.method-trace-file,methodTraceFileBuf,-Xmethod-trace-file:);parseRuntimeOption(dalvik.vm.method-trace-file-siz,methodTraceFileSizeBuf,-Xmethod-trace-file-size:);property_get(dalvik.vm.method-trace-stream, propBuf, false);if (strcmp(propBuf, true) 0) {addOption(-Xmethod-trace-stream);}}}// Native bridge library. 0 means that native bridge is disabled.//// Note: bridging is only enabled for the zygote. Other runs of// app_process may not have the permissions to mount etc.property_get(ro.dalvik.vm.native.bridge, propBuf, );if (propBuf[0] \0) {ALOGW(ro.dalvik.vm.native.bridge is not expected to be empty);} else if (zygote strcmp(propBuf, 0) ! 0) {snprintf(nativeBridgeLibrary, sizeof(-XX:NativeBridge) PROPERTY_VALUE_MAX,-XX:NativeBridge%s, propBuf);addOption(nativeBridgeLibrary);}#if defined(__LP64__)const char* cpu_abilist_property_name ro.product.cpu.abilist64;
#elseconst char* cpu_abilist_property_name ro.product.cpu.abilist32;
#endif // defined(__LP64__)property_get(cpu_abilist_property_name, propBuf, );if (propBuf[0] \0) {ALOGE(%s is not expected to be empty, cpu_abilist_property_name);return -1;}snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), --cpu-abilist%s, propBuf);addOption(cpuAbiListBuf);// Dalvik-cache pruning counter.parseRuntimeOption(dalvik.vm.zygote.max-boot-retry, cachePruneBuf,-Xzygote-max-boot-retry);// If set, the property below can be used to enable core platform API violation reporting.property_get(persist.debug.dalvik.vm.core_platform_api_policy, propBuf, );if (propBuf[0] ! \0) {snprintf(corePlatformApiPolicyBuf,sizeof(corePlatformApiPolicyBuf),-Xcore-platform-api-policy:%s,propBuf);addOption(corePlatformApiPolicyBuf);}/** Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will* contain the fingerprint and can be parsed.* Fingerprints are potentially longer than PROPERTY_VALUE_MAX, so parseRuntimeOption() cannot* be used here.* Do not ever re-assign fingerprintBuf as its c_str() value is stored in mOptions.*/std::string fingerprint GetProperty(ro.build.fingerprint, );if (!fingerprint.empty()) {fingerprintBuf -Xfingerprint: fingerprint;addOption(fingerprintBuf.c_str());}initArgs.version JNI_VERSION_1_4;initArgs.options mOptions.editArray();initArgs.nOptions mOptions.size();initArgs.ignoreUnrecognized JNI_FALSE;/** Initialize the VM.** The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.* If this call succeeds, the VM is ready, and we can start issuing* JNI calls.*/if (JNI_CreateJavaVM(pJavaVM, pEnv, initArgs) 0) {ALOGE(JNI_CreateJavaVM failed\n);return -1;}return 0;
}注册JNI
将gRegJNI数组里的JNI方法进行注册。RegJNIRec 包含100个JNI方法。
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{ATRACE_NAME(RegisterAndroidNatives);/** This hook causes all future threads created in this process to be* attached to the JavaVM. (This needs to go away in favor of JNI* Attach calls.)*/androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);ALOGV(--- registering native functions ---\n);/** Every register function calls one or more things that return* a local reference (e.g. FindClass). Because we havent really* started the VM yet, theyre all getting stored in the base frame* and never released. Use Push/Pop to manage the storage.*/env-PushLocalFrame(200);//核心步骤将gRegJNI数组里的JNI方法进行注册。if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) 0) {env-PopLocalFrame(NULL);return -1;}env-PopLocalFrame(NULL);//createJavaThread(fubar, quickTest, (void*) hello);return 0;
}static const RegJNIRec gRegJNI[] {REG_JNI(register_com_android_internal_os_RuntimeInit),REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),REG_JNI(register_android_os_SystemClock),REG_JNI(register_android_util_CharsetUtils),REG_JNI(register_android_util_EventLog),REG_JNI(register_android_util_Log),REG_JNI(register_android_util_MemoryIntArray),REG_JNI(register_android_app_admin_SecurityLog),REG_JNI(register_android_content_AssetManager),REG_JNI(register_android_content_StringBlock),REG_JNI(register_android_content_XmlBlock),REG_JNI(register_android_content_res_ApkAssets),REG_JNI(register_android_content_res_ResourceTimer),REG_JNI(register_android_text_AndroidCharacter),REG_JNI(register_android_text_Hyphenator),REG_JNI(register_android_view_InputDevice),REG_JNI(register_android_view_KeyCharacterMap),REG_JNI(register_android_os_Process),REG_JNI(register_android_os_SystemProperties),REG_JNI(register_android_os_Binder),REG_JNI(register_android_os_Parcel),REG_JNI(register_android_os_PerformanceHintManager),REG_JNI(register_android_os_HidlMemory),REG_JNI(register_android_os_HidlSupport),REG_JNI(register_android_os_HwBinder),REG_JNI(register_android_os_HwBlob),REG_JNI(register_android_os_HwParcel),REG_JNI(register_android_os_HwRemoteBinder),REG_JNI(register_android_os_NativeHandle),REG_JNI(register_android_os_ServiceManager),REG_JNI(register_android_os_ServiceManagerNative),REG_JNI(register_android_os_storage_StorageManager),REG_JNI(register_android_service_DataLoaderService),REG_JNI(register_android_view_DisplayEventReceiver),REG_JNI(register_android_view_Surface),REG_JNI(register_android_view_SurfaceControl),REG_JNI(register_android_view_SurfaceControlHdrLayerInfoListener),REG_JNI(register_android_view_SurfaceSession),REG_JNI(register_android_view_InputApplicationHandle),// This must be called after register_android_view_SurfaceControl since it has a dependency// on the Java SurfaceControl object that references a native resource via static request.REG_JNI(register_android_view_InputWindowHandle),REG_JNI(register_android_view_CompositionSamplingListener),REG_JNI(register_android_view_TextureView),REG_JNI(register_android_view_TunnelModeEnabledListener),REG_JNI(register_com_google_android_gles_jni_EGLImpl),REG_JNI(register_com_google_android_gles_jni_GLImpl),REG_JNI(register_android_opengl_jni_EGL14),REG_JNI(register_android_opengl_jni_EGL15),REG_JNI(register_android_opengl_jni_EGLExt),REG_JNI(register_android_opengl_jni_GLES10),REG_JNI(register_android_opengl_jni_GLES10Ext),REG_JNI(register_android_opengl_jni_GLES11),REG_JNI(register_android_opengl_jni_GLES11Ext),REG_JNI(register_android_opengl_jni_GLES20),REG_JNI(register_android_opengl_jni_GLES30),REG_JNI(register_android_opengl_jni_GLES31),REG_JNI(register_android_opengl_jni_GLES31Ext),REG_JNI(register_android_opengl_jni_GLES32),REG_JNI(register_android_graphics_classes),REG_JNI(register_android_graphics_BLASTBufferQueue),REG_JNI(register_android_graphics_GraphicBuffer),REG_JNI(register_android_graphics_GraphicsStatsService),REG_JNI(register_android_graphics_SurfaceTexture),REG_JNI(register_android_database_CursorWindow),REG_JNI(register_android_database_SQLiteConnection),REG_JNI(register_android_database_SQLiteGlobal),REG_JNI(register_android_database_SQLiteDebug),REG_JNI(register_android_database_SQLiteRawStatement),REG_JNI(register_android_os_Debug),REG_JNI(register_android_os_FileObserver),REG_JNI(register_android_os_GraphicsEnvironment),REG_JNI(register_android_os_MessageQueue),REG_JNI(register_android_os_SELinux),REG_JNI(register_android_os_Trace),REG_JNI(register_android_os_UEventObserver),REG_JNI(register_android_net_LocalSocketImpl),REG_JNI(register_android_os_MemoryFile),REG_JNI(register_android_os_SharedMemory),REG_JNI(register_android_os_incremental_IncrementalManager),REG_JNI(register_com_android_internal_content_om_OverlayConfig),REG_JNI(register_com_android_internal_content_om_OverlayManagerImpl),REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),REG_JNI(register_com_android_internal_os_ClassLoaderFactory),REG_JNI(register_com_android_internal_os_LongArrayMultiStateCounter),REG_JNI(register_com_android_internal_os_LongMultiStateCounter),REG_JNI(register_com_android_internal_os_Zygote),REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),REG_JNI(register_com_android_internal_os_ZygoteInit),REG_JNI(register_com_android_internal_security_VerityUtils),REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),REG_JNI(register_android_hardware_Camera),REG_JNI(register_android_hardware_camera2_CameraMetadata),REG_JNI(register_android_hardware_camera2_DngCreator),REG_JNI(register_android_hardware_camera2_impl_CameraExtensionJpegProcessor),REG_JNI(register_android_hardware_camera2_utils_SurfaceUtils),REG_JNI(register_android_hardware_display_DisplayManagerGlobal),REG_JNI(register_android_hardware_HardwareBuffer),REG_JNI(register_android_hardware_OverlayProperties),REG_JNI(register_android_hardware_SensorManager),REG_JNI(register_android_hardware_SerialPort),REG_JNI(register_android_hardware_SyncFence),REG_JNI(register_android_hardware_UsbDevice),REG_JNI(register_android_hardware_UsbDeviceConnection),REG_JNI(register_android_hardware_UsbRequest),REG_JNI(register_android_hardware_location_ActivityRecognitionHardware),REG_JNI(register_android_media_AudioDeviceAttributes),REG_JNI(register_android_media_AudioEffectDescriptor),REG_JNI(register_android_media_AudioSystem),REG_JNI(register_android_media_AudioRecord),REG_JNI(register_android_media_AudioTrack),REG_JNI(register_android_media_AudioAttributes),REG_JNI(register_android_media_AudioProductStrategies),REG_JNI(register_android_media_AudioVolumeGroups),REG_JNI(register_android_media_AudioVolumeGroupChangeHandler),REG_JNI(register_android_media_MediaMetrics),REG_JNI(register_android_media_MicrophoneInfo),REG_JNI(register_android_media_RemoteDisplay),REG_JNI(register_android_media_ToneGenerator),REG_JNI(register_android_media_audio_common_AidlConversion),REG_JNI(register_android_media_midi),REG_JNI(register_android_opengl_classes),REG_JNI(register_android_ddm_DdmHandleNativeHeap),REG_JNI(register_android_backup_BackupDataInput),REG_JNI(register_android_backup_BackupDataOutput),REG_JNI(register_android_backup_FileBackupHelperBase),REG_JNI(register_android_backup_BackupHelperDispatcher),REG_JNI(register_android_app_backup_FullBackup),REG_JNI(register_android_app_Activity),REG_JNI(register_android_app_ActivityThread),REG_JNI(register_android_app_NativeActivity),REG_JNI(register_android_util_jar_StrictJarFile),REG_JNI(register_android_view_InputChannel),REG_JNI(register_android_view_InputEventReceiver),REG_JNI(register_android_view_InputEventSender),REG_JNI(register_android_view_InputQueue),REG_JNI(register_android_view_KeyEvent),REG_JNI(register_android_view_MotionEvent),REG_JNI(register_android_view_MotionPredictor),REG_JNI(register_android_view_PointerIcon),REG_JNI(register_android_view_VelocityTracker),REG_JNI(register_android_view_VerifiedKeyEvent),REG_JNI(register_android_view_VerifiedMotionEvent),REG_JNI(register_android_content_res_ObbScanner),REG_JNI(register_android_content_res_Configuration),REG_JNI(register_android_animation_PropertyValuesHolder),REG_JNI(register_android_security_Scrypt),REG_JNI(register_com_android_internal_content_F2fsUtils),REG_JNI(register_com_android_internal_content_NativeLibraryHelper),REG_JNI(register_com_android_internal_os_FuseAppLoop),REG_JNI(register_com_android_internal_os_KernelAllocationStats),REG_JNI(register_com_android_internal_os_KernelCpuBpfTracking),REG_JNI(register_com_android_internal_os_KernelCpuTotalBpfMapReader),REG_JNI(register_com_android_internal_os_KernelCpuUidBpfMapReader),REG_JNI(register_com_android_internal_os_KernelSingleProcessCpuThreadReader),REG_JNI(register_com_android_internal_os_KernelSingleUidTimeReader),REG_JNI(register_android_window_WindowInfosListener),REG_JNI(register_android_window_ScreenCapture),REG_JNI(register_jni_common),REG_JNI(register_android_tracing_PerfettoDataSource),REG_JNI(register_android_tracing_PerfettoDataSourceInstance),REG_JNI(register_android_tracing_PerfettoProducer),
};