Android ART虚拟机 启动和初始化
Posted baiiu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ART虚拟机 启动和初始化相关的知识,希望对你有一定的参考价值。
前言
之前整理了一系列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.txt
parseRuntimeOption("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;
//初始化虚拟机,调用到JniInvocation
if (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();
// 启动runtime
runtime->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,可管理多个内存单元Arena
const 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_vm
java_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;
以上是关于Android ART虚拟机 启动和初始化的主要内容,如果未能解决你的问题,请参考以下文章