当前位置: 首页 > news >正文

Android ART虚拟机 启动和初始化

前言

之前整理了一系列Dalvik虚拟机的关于堆内存和GC的文章,轮到对ART内存进行分析优化了,继续整理输出一波,本篇为ART虚拟机系列的第一篇,介绍ART虚拟机的启动和初始化。

Android Rumtime.cppjni_internal.ccruntime.ccJNI_CreateJavaVMRuntime::CreateRuntime::Init、new gc::HeapRuntime::StartRuntime::InitNativeMethods、StartDaemonThreadsAndroid Rumtime.cppjni_internal.ccruntime.cc

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) 
{// 拼接一大堆参数if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {ALOGE("JNI_CreateJavaVM failed\n");goto bail;}
}

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);
}

jni_internal.cc

art/runtime/jni_internal.cc

extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);//  创建虚拟机if (!Runtime::Create(options, ignore_unrecognized)) {return JNI_ERR;}Runtime* runtime = Runtime::Current();runtime->Start();*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) {Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_);heap_ = new gc::Heap(options->heap_initial_size_,options->heap_growth_limit_,options->heap_min_free_,options->heap_max_free_,options->heap_target_utilization_,options->foreground_heap_growth_multiplier_,options->heap_maximum_size_,options->heap_non_moving_space_capacity_,options->image_,options->image_isa_,options->collector_type_,options->background_collector_type_,options->parallel_gc_threads_,options->conc_gc_threads_,options->low_memory_mode_,options->long_pause_log_threshold_,options->long_gc_log_threshold_,options->ignore_max_footprint_,options->use_tlab_,options->verify_pre_gc_heap_,options->verify_pre_sweeping_heap_,options->verify_post_gc_heap_,options->verify_pre_gc_rosalloc_,options->verify_pre_sweeping_rosalloc_,options->verify_post_gc_rosalloc_,options->use_homogeneous_space_compaction_for_oom_,options->min_interval_homogeneous_space_compaction_by_oom_);dump_gc_performance_on_shutdown_ = options->dump_gc_performance_on_shutdown_;BlockSignals();InitPlatformSignalHandlers();InitializeSignalChain();java_vm_ = new JavaVMExt(this, options.get());Thread::Startup();class_linker_ = new ClassLinker(intern_table_);//...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()) {ScopedObjectAccess soa(self);gc::space::ImageSpace* image_space = heap_->GetImageSpace();if (image_space != nullptr) {Runtime::Current()->GetInternTable()->AddImageStringsToTable(image_space);Runtime::Current()->GetClassLinker()->MoveImageClassesToClassTable();}}// InitNativeMethods needs to be after started_ so that the classes it touches will have methods linked to the oat file if necessary.InitNativeMethods();// Initialize well known thread group values that may be accessed threads while attaching.InitThreadGroups(self);Thread::FinishStartup();system_class_loader_ = CreateSystemClassLoader();StartDaemonThreads();finished_starting_ = true;return true;
}

相关文章:

Android ART虚拟机 启动和初始化

前言 之前整理了一系列Dalvik虚拟机的关于堆内存和GC的文章&#xff0c;轮到对ART内存进行分析优化了&#xff0c;继续整理输出一波&#xff0c;本篇为ART虚拟机系列的第一篇&#xff0c;介绍ART虚拟机的启动和初始化。 #mermaid-svg-8iNdLFTpOHLgRjHA {font-family:"tre…...

宇视科技一二三面

一面 1、自我介绍 2、堆和栈的区别&#xff0c;堆在数据结构中是如何表示的 3、有用过Linux吗&#xff1f;虚拟空间中用户态是3G&#xff0c;假如计算机的内存是4G&#xff0c;为什么计算机可以运行这些进程 4、虚拟地址到物理地址的映射过程 5、进程间的通信方式 6、共享内存…...

优思学院|盘点,精益生产25个工具!【必需收藏】

精益生产方法需要一种全面的方法才能有效实施。精益这个概念是每个接触产品供应链的人都要实践的&#xff0c;无论是在计划方面还是在分析方面。 精益生产工具有助于持续改进生产效率和产品或服务质量。精益工具是要减少 Muda &#xff08;浪费&#xff09;&#xff0c;从生产过…...

Linux中将多块新硬盘合并成一个,挂载到/mysqldata目录下

需求&#xff1a; 将两块空硬盘合并为“一块”&#xff0c;挂载到指定目录&#xff08;/data&#xff09;下&#xff0c;达到在一个目录使用2块硬盘所有空间的效果。 使用 fdisk -l 命令查看当前系统中的硬盘&#xff0c;如下图&#xff1a; 系统中存在两块未分配的硬盘&#…...

Git的SSH密钥配置

Git的SSH密钥配置简记Githttps和ssh的区别基本需求SSH密钥类型ED25519 SSH 密钥RSA SSH 密钥查看您是否有现有的 SSH 密钥对设置流程设置user name和emailssh密钥配置检查是否存在ssh Key创建新的ssh key将ssh密钥添加到您的Git帐户验证您是否可以连接使用Git有一段时间了&…...

C++回顾(九)——多继承

9.1 多继承 9.1.1 概念 一个类有多个直接基类的继承关系称为多继承&#xff08;多个父类&#xff09;多继承声明语法 class 派生类名 : 访问控制 基类名1 , 访问控制 基类名2 , … , 访问控制 基类名n {数据成员和成员函数声明 }&#xff1b;类 C 可以根据访问控制同时…...

交流约瑟夫森效应

定理 根据约瑟夫森效应的基本方程&#xff0c;当隧道结两端施加恒定电压V0V_0V0​时&#xff0c;结两边超导体波函数的位相差为 Δϕ2eℏV0tΔϕ0\begin{align} \Delta\phi\frac{2e}{\hbar}V_0t\Delta\phi_0 \end{align} Δϕℏ2e​V0​tΔϕ0​​​ 得到超导电流密度为 JsJcs…...

大数据项目实战之数据仓库:用户行为采集平台——第3章 用户行为日志

第3章 用户行为日志 3.1 用户行为日志概述 用户行为日志的内容&#xff0c;主要包括用户的各项行为信息以及行为所处的环境信息。收集这些信息的主要目的是优化产品和为各项分析统计指标提供数据支撑。收集这些信息的手段通常为埋点。 目前主流的埋点方式&#xff0c;有代码…...

centos6下为Rstudio安装多版本R

之前的R版本太旧,不少包装不上,需要安装新版本的R: R --version R version 3.6.0 (2019-04-26) -- "Planting of a Tree"于是下载最新版R: 因为没有证书,需要加上最后面的参数. wget https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/base/R-4/R-4.2.2.tar.gz --no…...

TCL 拥抱云原生,实现 IT 成本治理优化

作者&#xff1a;行疾 TCL 工程师团队基于阿里云企业云原生 IT 成本治理方案沉淀了一套成熟的 IT 企业成本治理流程与系统&#xff0c;通过阿里云容器服务提供的开箱即用的成本洞察、资源智能画像等功能&#xff0c;进行业务成本拆分、闲置资源可视化发现&#xff0c;并制定弹性…...

什么是API接口

API接口是指应用程序接口&#xff0c;是一种让不同的应用程序之间进行数据交互的方式。在现代软件开发中&#xff0c;API接口已经成为了必不可少的一部分。它们让开发者们可以将不同的功能组合在一起&#xff0c;同时也让不同的应用程序之间可以相互连接和通讯。API接口的作用A…...

基于单片机的波形发生器设计

单片机可以用来设计各种类型的波形发生器&#xff0c;下面是一种基于单片机的波形发生器设计方案。所需材料&#xff1a;单片机&#xff1a;可以选择常见的Atmel AVR单片机&#xff0c;如ATmega328P等。调制器&#xff1a;可以使用AD9833或AD9851等常用的调制器。时钟&#xff…...

phpmyadmin SQL注入 (CVE-2020-5504)

文章目录 0x01 漏洞介绍0x02 影响版本0x03 漏洞编号0x04 漏洞查询0x05 漏洞环境0x06 漏洞复现方法一:写入shell方法二:报错注入0x07 修复建议免责声明摘抄0x01 漏洞介绍 phpMyAdmin是phpMyAdmin团队的一套免费的、基于Web的MySQL数据库管理工具。该工具能够创建和删除数据库,…...

华为机试题:HJ107 求解立方根(python)

文章目录&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;Python3实现&#xff08;3&#xff09;知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…...

论文公式符号规范

参考自1&#xff0c;记录论文公式的符号规范&#xff1a; 1.变量和公式符号表达 物理量 物理量符号用英文斜体字母或希腊斜体字母&#xff0c;表示物理量大小用数字加单位&#xff0c;单位使用正体。 例如&#xff1a; m10.05gx10.12ζ35.36mVm10.05 \mathrm{~g} \quad x10…...

哈工大面向服务的软件系统 期末开卷提纲

引言本课程期末考试为开卷&#xff0c;博主2022年期末卷面94/100&#xff0c;总分92.9排名第2/82&#xff0c;现分享复习提纲以供学弟学妹们参考。本提纲仅供参考&#xff0c;切勿进行其他目的的使用。基于2021秋季考试题的思考一、Spring Boot的优点是&#xff1a;1. 非常快速…...

Adding Conditional Control to Text-to-Image Diffusion Models

安全验证 - 知乎知乎&#xff0c;中文互联网高质量的问答社区和创作者聚集的原创内容平台&#xff0c;于 2011 年 1 月正式上线&#xff0c;以「让人们更好的分享知识、经验和见解&#xff0c;找到自己的解答」为品牌使命。知乎凭借认真、专业、友善的社区氛围、独特的产品机制…...

C++从头再来:知识点速通

1. 关于scanf 1.1 读入数字 scanf 的返回值表示成功输入的变量个数&#xff0c;当输入结束时&#xff0c;scanf将无法再次读取数据&#xff0c;返回0 # include <stdio.h> # include <math.h> # include <time.h># define M 1000000; // compute the max,…...

LearnDash Groups学习群组:您需要了解的一切

大约131k 网站使用 LearnDash。因此&#xff0c;毫无疑问&#xff0c;LearnDash是 WordPress 领域中最受欢迎的 LMS。而且&#xff0c;这是因为它具有强大的功能。但让它更受欢迎的是它与大多数第 3 方扩展很好地集成&#xff0c;并且比现有的任何其他 LMS 都更灵活。群组和群组…...

软件开发过程中遇到一个傻嘚业主能让你抓狂

背景 之前的一个网站交付了之后&#xff0c;业主一直未验收&#xff0c;今天忽然间开始了他的扯淡需求调整。 问题1 有一个问题是pdf文件上传显示问题&#xff0c;目前是pdf有一个封面要上传&#xff0c;排序字段可自动调整控制。但是就这么好用的功能&#xff0c;被他给pas…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...