当前位置: 首页 > 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…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...