Andriod ART虚拟机 启动和初始化

news/2025/2/6 4:08:09/

前言

之前整理了一系列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;
}

http://www.ppmy.cn/news/37980.html

相关文章

【新2023Q2押题JAVA】华为OD机试 - 最长合法表达式

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:最长合法表达式 题目 提取字…

Redis第十讲 Redis之Hash数据结构Dict-rehash扩容操作

Rehash 执行过程 字典的 rehash 操作实际上就是执行以下任务: 创建一个比 ht[0]->table 更大的 ht[1]->table ;将 ht[0]->table 中的所有键值对迁移到 ht[1]->table ;将原有 ht[0] 的数据清空,并将 ht[1] 替换为新的 ht[0] ; 经过以上步骤之后, 程序就在不改…

第十二届蓝桥杯省赛第二场 C/C++ B组 编程题与详解

文章目录 一、特殊年份 1、1 题目描述 1、2 题解关键思路与解答 二、小平方 2、1 题目描述 2、2 题解关键思路与解答 三、完全平方数 3、1 题目描述 3、2 题解关键思路与解答 四、负载均衡 4、1 题目描述 4、2 题解关键思路与解答 五、国际象棋 5、1 题目描述 5、2 题解关键思路…

scala匿名函数

我们在使用scala的时候经常会碰到>写法 官方文档给出的解释是&#xff1a;>箭头左边的元组是参数列表&#xff0c;右侧的表达式的值是返回的值 同时>在scala中代表匿名函数&#xff0c;表示创建了一个函数实例 所有的函数在scala中都是object 实例形式&#xff1a…

在职阿里6年,一个29岁女软件测试工程师的心声

简单的先说一下&#xff0c;坐标杭州&#xff0c;14届本科毕业&#xff0c;算上年前在阿里巴巴的面试&#xff0c;一共有面试了有6家公司&#xff08;因为不想请假&#xff0c;因此只是每个晚上去其他公司面试&#xff0c;所以面试的公司比较少&#xff09; 其中成功的有4家&am…

SSD容量翻倍价格骨折,新颗粒要让硬盘成消耗品

经过这么些年发展&#xff0c;固态硬盘&#xff08;SSD&#xff09;基本成了每台电脑的必备硬件之一。 相较于机械硬盘&#xff08;HDD&#xff09;&#xff0c;SSD 虽说速度读写性能虽说远远领先&#xff0c;但却存在擦写寿命限制。 SSD 闪存颗粒按寿命从高到低、容量从低到高…

centos7 搭建 tinyProxy代理

文章转载于&#xff1a;https://www.cnblogs.com/gezp/p/14962924.html 一、简介 Tinyproxy是一个轻量级的用于POSIX操作系统的http/https代理守护进程。在设计之初就遵循着更快并且更小的原则。在相关的运用案例中&#xff0c;它是一种理想的解决方案&#xff0c;例如在一个需…

Excel 制作动态甘特图

一、简单介绍一下甘特图 甘特图是一种时间轴表现形式的项目管理工具&#xff0c;用于展示项目任务、时间进度和完成情况。甘特图通过水平条形图表示每个任务的开始和结束时间&#xff0c;并使用不同颜色或标记来表示任务的状态和关键节点。 适用于各种需要规划、跟踪和管理进度…