前言
上一篇说到了在启动zygote的时候,会启动art虚拟机,并且已经到了虚拟机的JNI_CreateJavaVM函数入口处。我们接着往下分析。
ART中的JNI_CreateJavaVM
源代码在ART虚拟机中的java_vm_ext.cc中
// JNI Invocation interface.
extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
ScopedTrace trace(__FUNCTION__);
const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
if (JavaVMExt::IsBadJniVersion(args->version)) {
LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
return JNI_EVERSION;
}
RuntimeOptions options;
for (int i = 0; i < args->nOptions; ++i) {
JavaVMOption* option = &args->options[i];
options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
}
bool ignore_unrecognized = args->ignoreUnrecognized;
if (!Runtime::Create(options, ignore_unrecognized)) {
return JNI_ERR;
}
// Initialize native loader. This step makes sure we have
// everything set up before we start using JNI.
android::InitializeNativeLoader();
Runtime* runtime = Runtime::Current(); //创建当前的runtime
bool started = runtime->Start(); // 启动
if (!started) {
delete Thread::Current()->GetJniEnv();
delete runtime->GetJavaVM();
LOG(WARNING) << "CreateJavaVM failed";
return JNI_ERR;
}
*p_env = Thread::Current()->GetJniEnv();
*p_vm = runtime->GetJavaVM();
return JNI_OK;
}
此时可以看到,通过runtime进行初始化,然后进行start完成虚拟机的创建。这一块的逻辑比较复杂,可以先来一张图整理一下。流程如图:
Runtime()->Create()
bool Runtime::Create(RuntimeArgumentMap&& runtime_options) {
...
instance_ = new Runtime;
Locks::SetClientCallback(IsSafeToCallAbort);
if (!instance_->Init(std::move(runtime_options))) {
instance_ = nullptr;
return false;
}
return true;
}
创建runtime的过程中,需要进行init操作
Runtime()->init()
bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
...
// 获取各种启动参数
// 获取到默认的栈大小
default_stack_size_ = runtime_options.GetOrDefault(Opt::StackSize);
//创建堆空间
heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),
runtime_options.GetOrDefault(Opt::HeapGrowthLimit),
runtime_options.GetOrDefault(Opt::HeapMinFree),
runtime_options.GetOrDefault(Opt::HeapMaxFree),
runtime_options.GetOrDefault(Opt::HeapTargetUtilization),
foreground_heap_growth_multiplier,
runtime_options.GetOrDefault(Opt::MemoryMaximumSize),
runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity),
GetBootClassPath(),
GetBootClassPathLocations(),
image_location_,
instruction_set_,
// Override the collector type to CC if the read barrier config.
kUseReadBarrier ? gc::kCollectorTypeCC : xgc_option.collector_type_,
kUseReadBarrier ? BackgroundGcOption(gc::kCollectorTypeCCBackground)
: runtime_options.GetOrDefault(Opt::BackgroundGc),
runtime_options.GetOrDefault(Opt::LargeObjectSpace),
runtime_options.GetOrDefault(Opt::LargeObjectThreshold),
runtime_options.GetOrDefault(Opt::ParallelGCThreads),
runtime_options.GetOrDefault(Opt::ConcGCThreads),
runtime_options.Exists(Opt::LowMemoryMode),
runtime_options.GetOrDefault(Opt::LongPauseLogThreshold),
runtime_options.GetOrDefault(Opt::LongGCLogThreshold),
runtime_options.Exists(Opt::IgnoreMaxFootprint),
runtime_options.GetOrDefault(Opt::UseTLAB),
xgc_option.verify_pre_gc_heap_,
xgc_option.verify_pre_sweeping_heap_,
xgc_option.verify_post_gc_heap_,
xgc_option.verify_pre_gc_rosalloc_,
xgc_option.verify_pre_sweeping_rosalloc_,
xgc_option.verify_post_gc_rosalloc_,
xgc_option.gcstress_,
xgc_option.measure_,
runtime_options.GetOrDefault(Opt::EnableHSpaceCompactForOOM),
use_generational_cc,
runtime_options.GetOrDefault(Opt::HSpaceCompactForOOMMinIntervalsMs),
runtime_options.Exists(Opt::DumpRegionInfoBeforeGC),
runtime_options.Exists(Opt::DumpRegionInfoAfterGC),
image_space_loading_order_);
// 标记线程为启动状态
Thread::Startup();
// 设置当前线程为虚拟机的主线程
Thread* self = Thread::Attach("main", false, nullptr, false);
{
// 通过dlopen加载native bridge
std::string native_bridge_file_name = runtime_options.ReleaseOrDefault(Opt::NativeBridge);
is_native_bridge_loaded_ = LoadNativeBridge(native_bridge_file_name);
}
}
其中比较关键的堆的操作,我们放到后面来进行分析。 现在我们继续关注虚拟机启动的流程。
android::INitializeNativeLoader
void InitializeNativeLoader() {
#if defined(__ANDROID__)
std::lock_guard<std::mutex> guard(g_namespaces_mutex);
g_namespaces->Initialize();
#endif
}
Runtime()->start()
bool Runtime::Start() {
{
ScopedTrace trace2("InitNativeMethods");
// 初始化native方法
InitNativeMethods();
}
// 完成初始化
Thread::FinishStartup();
// 创建系统类加载器
system_class_loader_ = CreateSystemClassLoader(this);
// 创建守护进程
StartDaemonThreads();
}
StartDewmonThreads
void Runtime::StartDaemonThreads() {
// 获取到java/lang/daemon,并且调用start方法。
JNIEnv* env = self->GetJniEnv();
env->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons,
WellKnownClasses::java_lang_Daemons_start);
}
private static final Daemon[] DAEMONS = new Daemon[] {
HeapTaskDaemon.INSTANCE,
ReferenceQueueDaemon.INSTANCE,
FinalizerDaemon.INSTANCE,
FinalizerWatchdogDaemon.INSTANCE,
};
@UnsupportedAppUsage
public static void start() {
for (Daemon daemon : DAEMONS) {
daemon.start();
}
}
启动了我们熟知的四个守护线程。
总结:
梳理一下,在init创建zygote的过程中,zygote创建了Android世界的第一个虚拟机,而这个虚拟机是根据properties来进行配置的。在虚拟机创建的过程中,进行了堆的创建,以及守护进程等创建。