前言
之前整理了一系列Dalvik虚拟机的关于堆内存和GC的文章,轮到对ART内存进行分析优化了,继续整理输出一波,本篇为ART虚拟机系列的第一篇,介绍ART虚拟机的启动和初始化。
本ART系列基于7.0代码分析。
ART启动
app_main启动
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args);} else {return 10;}
}
AndroidRuntime.cpp
frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{/* start the virtual machine */JniInvocation jni_invocation;jni_invocation.Init(NULL);JNIEnv* env;if (startVm(&mJavaVM, &env) != 0) {return;}onVmCreated(env);/** Register android functions.*/if (startReg(env) < 0) {return;}
}int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{// JNI检测功能,用于native层调用jni函数时进行常规检测,比较弱字符串格式是否符合要求,资源是否正确释放。该功能一般用于早期系统调试或手机Eng版,对于User版往往不会开启,引用该功能比较消耗系统CPU资源,降低系统性能。bool checkJni = false;property_get("dalvik.vm.checkjni", propBuf, "");if (strcmp(propBuf, "true") == 0) {checkJni = true;} else if (strcmp(propBuf, "false") != 0) {property_get("ro.kernel.android.checkjni", propBuf, "");if (propBuf[0] == '1') {checkJni = true;}}if (checkJni) {addOption("-Xcheck:jni");}//虚拟机产生的trace文件,主要用于分析系统问题,路径默认为/data/anr/traces.txtparseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");//对于不同的软硬件环境,这些参数往往需要调整、优化,从而使系统达到最佳性能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=");...//preloaded-classes文件内容是由WritePreloadedClassFile.java生成的,//在ZygoteInit类中会预加载工作将其中的classes提前加载到内存,以提高系统性能if (!hasFile("/system/etc/preloaded-classes")) {return -1;}//初始化虚拟机,调用到JniInvocationif (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {return -1;}
}
JniInvocation.cpp
libnativehelper/JniInvocation.cpp,
5.x的代码里获取libart.so,再获取到JNI_CreateJavaVM、JNI_GetCreatedJavaVMs等的实现。
static const char* kLibraryFallback = "libart.so";bool JniInvocation::Init(const char* library) {library = GetLibrary(library, buffer);handle_ = dlopen(library, RTLD_NOW);if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),"JNI_GetDefaultJavaVMInitArgs")) {return false;}if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),"JNI_CreateJavaVM")) {return false;}if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),"JNI_GetCreatedJavaVMs")) {return false;}return true;
}extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) {return JniInvocation::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);
}extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);
}extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {return JniInvocation::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);
}
java_vm_ext.cc
art/runtime/java_vm_ext.cc
extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {// 虚拟机参数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;// 创建Runtime对象,它就是虚拟机的化身if (!Runtime::Create(options, ignore_unrecognized)) {return JNI_ERR;}Runtime* runtime = Runtime::Current();// 启动runtimeruntime->Start();// 获取JNI ENV和Java VM对象*p_env = Thread::Current()->GetJniEnv();*p_vm = runtime->GetJavaVM();return JNI_OK;
}
art初始化
art/runtime/runtime.h
art/runtime/runtime.cc
runtime.h
class Runtime {public:// Creates and initializes a new runtime.static bool Create(const RuntimeOptions& options, bool ignore_unrecognized)SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);// Starts a runtime, which may cause threads to be started and code to run.bool Start() UNLOCK_FUNCTION(Locks::mutator_lock_);static Runtime* Current() {return instance_;}gc::Heap* GetHeap() const {return heap_;}~Runtime();private:Runtime();void BlockSignals();bool Init(const RuntimeOptions& options, bool ignore_unrecognized)SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);// A pointer to the active runtime or NULL.static Runtime* instance_;gc::Heap* heap_;
}
Runtime::Create
bool Runtime::Create(const RuntimeOptions& options, bool ignore_unrecognized) {if (Runtime::instance_ != NULL) {return false;}instance_ = new Runtime;instance_->Init(options, ignore_unrecognized);return true;
}
Runtime()
Runtime::Runtime(): is_zygote_(false),is_concurrent_gc_enabled_(true),is_explicit_gc_disabled_(false),dex2oat_enabled_(true),default_stack_size_(0),heap_(nullptr),monitor_list_(nullptr),monitor_pool_(nullptr),thread_list_(nullptr),class_linker_(nullptr),signal_catcher_(nullptr),java_vm_(nullptr) {
}
Runtime::Init
bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) {// MemMap模块,用于管理内存映射。// ART大量使用了内存映射技术,比如.oat文件MemMap::Init();// 锁实现,和Java中的monitor有关,用于实现线程同步的模块Monitor::Init(runtime_options.GetOrDefault(Opt::LockProfThreshold), runtime_options.GetOrDefault(Opt::HookIsSensitiveThread));// 从raw_options转化为runtime_options,获取了n多参数...// 维护了一组Monitor对象monitor_list_ = new MonitorList;// 用于创建Monitor对象monitor_pool_ = MonitorPool::Create();// 用于管理ART中的线程对象,Thread.cpp对象thread_list_ = new ThreadList;// 和string intern table有关,即字符串常量池intern_table_ = new InternTable;// heap,堆内存了heap_ = new gc::Heap(xxx);// 内存池类ArenaPool,可管理多个内存单元Arenaconst bool use_malloc = IsAotCompiler();arena_pool_.reset(new ArenaPool(use_malloc, false));// 内存分配器LinearAlloc,即可在ArenaPool上分配任意大小的内存if (IsCompiler() && Is64BitInstructionSet(kRuntimeISA)) {// 4gb, no malloc. Explanation in header.low_4gb_arena_pool_.reset(new ArenaPool(false, true));linear_alloc_.reset(new LinearAlloc(low_4gb_arena_pool_.get()));} else {linear_alloc_.reset(new LinearAlloc(arena_pool_.get()));}// 和信号处理有关,ART虚拟机进程需要截获来自操作系统的某些信号BlockSignals();// 为某些信号设置自定义的信号处理函数InitPlatformSignalHandlers();// Always initialize the signal chain so that any calls to sigaction get// correctly routed to the next in the chain regardless of whether we// have claimed the signal or not.InitializeSignalChain();if (implicit_null_checks_ || implicit_so_checks_ || implicit_suspend_checks_) {// FaultManager,用于处理SIGENV信号fault_manager.Init();// 取值为false,启用隐式线程暂停thread suspension检查if (implicit_suspend_checks_) {new SuspensionHandler(&fault_manager);}// 取值为true,启动隐式堆栈溢出if (implicit_so_checks_) {new StackOverflowHandler(&fault_manager);}// 取值为true,启动隐式空指针检查if (implicit_null_checks_) {new NullPointerHandler(&fault_manager);}if (kEnableJavaStackTraceHandler) {new JavaStackTraceHandler(&fault_manager);}}// JavaVMExt是JNI中代表Java虚拟机的对象;// 根据JNI规范,一个进程只有唯一的一个JavaVM对象,对art虚拟机来说,这个JavaVm对象就是此处的java_vmjava_vm_ = new JavaVMExt(this, runtime_options);// 调用Thread.cpp线程的Startup和Attach方法以初始化虚拟机主线程Thread::Startup();Thread* self = Thread::Attach("main", false, nullptr, false);// 处理和Class有关的工作,解析某个类、寻找某个类、加载某个类class_linker_ = new ClassLinker(intern_table_);// 用于检验Java方法的模块,类检验时会用verifier::MethodVerifier::Init();// 抛出OutOfMemoryError、NoClassDefFoundError,并清楚,可以理解成清空方法栈吧self->ThrowNewException("Ljava/lang/OutOfMemoryError;","OutOfMemoryError thrown while trying to throw OutOfMemoryError; ""no stack trace available");pre_allocated_OutOfMemoryError_ = GcRoot<mirror::Throwable>(self->GetException());self->ClearException();self->ThrowNewException("Ljava/lang/NoClassDefFoundError;","Class not found using the boot class loader; no stack trace available");pre_allocated_NoClassDefFoundError_ = GcRoot<mirror::Throwable>(self->GetException());self->ClearException();return true;
}
runtime->start
bool Runtime::Start() {// Restore main thread state to kNative as expected by native code.Thread* self = Thread::Current();self->TransitionFromRunnableToSuspended(kNative);started_ = true;if (!IsZygote() && jit_options_->UseJIT()) {// 加载JNI编译模块对应的so库CreateJit();}// InitNativeMethods needs to be after started_ so that the classes// it touches will have methods linked to the oat file if necessary.// 初始化JNI层相关内容InitNativeMethods();// 完成Thread类初始化相关工作InitThreadGroups(self);Thread::FinishStartup();// 创建系统类加载器system_class_loader_ = CreateSystemClassLoader(this);// 启动虚拟机的daemon线程StartDaemonThreads();finished_starting_ = true;return true;
}