返回顶部
首页 > 资讯 > 移动开发 >Android虚拟机与类加载机制详情
  • 907
分享到

Android虚拟机与类加载机制详情

2024-04-02 19:04:59 907人浏览 八月长安
摘要

目录JVM与Dalvik基于栈的虚拟机字节码指令执行过程基于寄存器的虚拟机寄存器基于寄存器的虚拟机ART与Dalvikdex2aotdexopt与dexaotAndroid N的运作

JVM与Dalvik

Android应用程序运行在Dalvik/ART虚拟机,并且每一个应用程序对应有一个单独的Dalvik虚拟机实例。Dalvik虚拟机实则也算是一个Java虚拟机,只不过它执行的不是class文件,而是dex文件。 Dalvik虚拟机与Java虚拟机共享有差不多的特性,差别在于两者执行的指令集是不一样的,前者的指令集是基本寄存器的,而后者的指令集是基于堆栈的。 

 JMV基于栈,Dalvik基于寄存器

基于栈的虚拟机

对于基于栈的虚拟机来说,每一个运行时的线程,都有一个独立的栈。栈中记录了方法调用的历史,每有一次方法调用,栈中便会多一个栈桢。最顶部的栈桢称作当前栈桢,其代表着当前执行的方法。基于栈的虚拟机通过操作数栈进行所有操作。 

字节码指令

在Androidstudio中搜索ASMPlugin,可以直接用这个插件查看字节码 

执行过程

基于寄存器的虚拟机

寄存器

寄存器是CPU的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。 

基于寄存器的虚拟机

基于寄存器的虚拟机中没有操作数栈,但是有很多虚拟寄存器。其实和操作数栈相同,这些寄存器也存放在运行时栈中,本质上就是一个数组。与JVM相似,在Dalvik VM中每个线程都有自己的PC和调用栈,方法调用的活动记录以帧为单位保存在调用栈上。 

 与JVM版相比,可以发现Dalvik版程序的指令数明显减少了,数据移动次数也明显减少了。

ART与Dalvik

Dalvik虚拟机执行的是dex字节码,解释执行。从Android 2.2版本开始,支持JIT及时编译(Just In Time)在程序运行的过程中进行选择热点代码(经常执行的代码)进行编译或者优化。 而ART(Android Runtime) 是在 Android 4.4 中引入的一个开发者选项,也是 Android 5.0 及更高版本的默认 Android 运行时。ART虚拟机执行的是本地机器码。Android的运行时从Dalvik虚拟机替换成ART虚拟机,并不要求开发者将自己的应用直接编译成目标机器码,APK仍然是一个包含dex字节码的文件。那么,ART虚拟机执行的本地机器码是从哪里来?

dex2aot

Dalvik下应用在安装的过程,会执行一次优化,将dex字节码进行优化生成odex文件。而Art下将应用的dex字节码翻译成本地机器码的最恰当AOT时机也就发生在应用安装的时候。ART 引入了预先编译机制(Ahead Of Time),在安装时,ART 使用设备自带的 dex2oat 工具来编译应用,dex中的字节码将被编译成本地机器码。 

 odex的目的:预先提取,减少RAM的占用,因为没有odex的话,系统要从apk包中提取dex再运行。

dexopt与dexaot

  • dexopt:Dalvik中虚拟机在加载一个dex文件时,对 dex 文件 进行 验证 和 优化的操作,其对 dex 文件的优化结果变成了 odex(Optimized dex) 文件,这个文件和 dex 文件很像,只是使用了一些优化操作码。
  • dex2oat:ART 预先编译机制,在安装时对 dex 文件执行AOT 提前编译操作,编译为OAT(实际上是ELF文件)可执行文件(机器码)。

Android N的运作方式

ART 使用预先 (AOT) 编译,并且从 Android N混合使用AOT编译,解释和JIT。 1、最初安装应用时不进行任何 AOT 编译(安装又快了),运行过程中解释执行,对经常执行的方法进行JIT,经过 JIT 编译的方法将会记录到Profile配置文件中。 2、当设备闲置和充电时,编译守护进程会运行,根据Profile文件对常用代码进行 AOT 编译。待下次运行时直接使用。 

ClassLoader

介绍

任何一个 Java 程序都是由一个或多个 class 文件组成,在程序运行时,需要将 class 文件加载到 JVM 中才可以使用,负责加载这些 class 文件的就是 Java 的类加载机制。ClassLoader 的作用简单来说就是加载 class 文件,提供给程序运行时使用。每个 Class 对象的内部都有一个 classLoader 字段来标识自己是由哪个ClassLoader 加载的。 

 ClassLoader是一个抽象类,而它的具体实现类主要有:

  • BootClassLoader:用于加载Android Framework层class文件。
  • PathClassLoader:用于Android应用程序类加载器。可以加载指定的dex,以及jar、zip、apk中的classes.dex
  • DexClassLoader:用于加载指定的dex,以及jar、zip、apk中的classes.dex

很多博客里说PathClassLoader只能加载已安装的apk的dex,其实这说的应该是在dalvik虚拟机上。但现在一般不用关心dalvik了。

Log.e(TAG, "Activity.class 由:" + Activity.class.getClassLoader() +" 加载");
Log.e(TAG, "MainActivity.class 由:" + getClassLoader() +" 加载");
//输出:
Activity.class 由:java.lang.BootClassLoader@d3052a9 加载
MainActivity.class 由:dalvik.system.PathClassLoader[DexPathList[[zip file
"/data/app/com.enjoy.enjoyfix-1/base.apk"],nativeLibraryDirectories=
[/data/app/com.enjoy.enjoyfix-1/lib/x86, /system/lib, /vendor/lib]]] 加载

ClassLoader加载流程与双亲委托机制

可以看到创建 ClassLoader 需要接收一个 ClassLoader parent 参数。这个 parent 的目的就在于实现类加载的双亲委托。即: 某个类加载器在加载类时,首先将加载任务委托给父类加载器,依次递归,如果父 类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务或者没有父类加载器时,才自己去加载。

1、避免重复加载,当父加载器已经加载了该类的时候,就没有必要子ClassLoader再加载一次。 2、安全性考虑,防止核心api库被随意篡改。 

因此我们自己创建的ClassLoader: new PathClassLoader("/sdcard/xx.dex", getClassLoader()); 并不仅仅只能加载 xx.dex中的class。

值得注意的是: c = findBootstrapClassOrNull(name); 按照方法名理解,应该是当parent为null时候,也能够加载 BootClassLoader 加载的类。 newPathClassLoader("/sdcard/xx.dex", null) ,能否加载Activity.class? 但是实际上,Android当中的实现为:(Java不同)

类加载

热修复

 PathClassLoader 中存在一个Element数组,Element类中存在一个dexFile成员表示dex文件,即:APK中有X个dex,则Element数组就有X个元素。

在 PathClassLoader 中的Element数组为:[patch.dex , classes.dex , classes2.dex]。如果存在Key.class位于patch.dex与classes2.dex中都存在一份,当进行类查找时,循环获得 dexElements 中的DexFile,查找到了Key.class则立即返回,不会再管后续的element中的DexFile是否能加载到Key.class了。

因此实际上,一种热修复实现可以将出现Bug的class单独的制作一份fix.dex文件(补丁包),然后在程序启动时,从服务器下载fix.dex保存到某个路径,再通过fix.dex的文件路径,用其创建 Element 对象,然后将这个 Element 对象插入到我们程序的类加载器 PathClassLoader 的 pathList 中的 dexElements 数组头部。这样在加载出现Bug的class时会优先加载fix.dex中的修复类,从而解决Bug。 

到此这篇关于Android虚拟机与类加载机制详情的文章就介绍到这了,更多相关Android虚拟机内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android虚拟机与类加载机制详情

本文链接: https://lsjlt.com/news/166907.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android虚拟机与类加载机制详情
    目录JVM与Dalvik基于栈的虚拟机字节码指令执行过程基于寄存器的虚拟机寄存器基于寄存器的虚拟机ART与Dalvikdex2aotdexopt与dexaotAndroid N的运作...
    99+
    2024-04-02
  • jvm虚拟机类加载机制详解
    目录1 概述2 类的加载时机3 类的加载过程3.1 加载3.2 验证3.3 准备3.4 解析3.5 初始化4 类加载器4.1 双亲委派模型4.2 破坏双亲委派模型1 概述 ​ Jav...
    99+
    2024-04-02
  • Java虚拟机JVM类加载机制(从类文件到虚拟机)
    目录一、类加载机制简介二、类加载机制过程 2.1、加载(Load)2.2、连接(Linking)2.3、初始化(Initialize)三、类加载器Classloader&n...
    99+
    2024-04-02
  • JAVA虚拟机(JVM)详细介绍(五)——类加载机制
    上篇中我们讲解了Class文件,这篇我们说说虚拟机是如何加载这些Class文件的?Class文件中的信息进入到虚拟机后会发生什么变化?这就涉及到了类加载机制。类加载机制是把类的数据从Class文件加载到内存,并对数据进行校验,转换解析和初始...
    99+
    2015-12-28
    java教程 JVM
  • Java虚拟机之类加载
    目录一、类加载流程1.1 类加载条件1.2 加载1.3 验证1.4 准备1.5 解析1.6 初始化二、ClassLoader2.1 Class...
    99+
    2024-04-02
  • java虚拟机JVM类加载机制原理(面试必问)
    目录1、类加载的过程。1)加载2)验证3)准备4)解析5)初始化2、Java 虚拟机中有哪些类加载器?1)启动类加载器(Bootstrap ClassLoader):2)扩展类加载器...
    99+
    2024-04-02
  • java虚拟机原理:类加载过程详解
    目录一、Java 类加载过程1、字节码编译2、加载3、连接4、初始化总结一、Java 类加载过程 1、字节码编译 编写好 Java 源码 Student.java , 使用 ja...
    99+
    2024-04-02
  • Java虚拟机类加载器之双亲委派机制模型案例
    1. 双亲委派模型是什么? 当某个类加载器需要加载某个.class字节码文件时,它首先把这个任务委托给它的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类...
    99+
    2024-04-02
  • 概述java虚拟机中类的加载器及类加载过程
    目录1. 类加载子系统 1.1 概述1.2 类的加载器2.类的加载过程2.1 类的加载过程简图2.2 加载阶段:Loading2.3 链接阶段:Linking2.4 初始化...
    99+
    2024-04-02
  • Java虚拟机之对象创建过程与类加载机制及双亲委派模型
    目录一、对象的创建过程: 1、对象的创建过程:2、对象的访问方式:二、类加载机制:2.1、加载阶段:2.2、验证阶段:2.3、准备阶段:2.4、解析阶段:2.5、初始化:2...
    99+
    2024-04-02
  • java类加载机制详细介绍
    文章转载自:http://www.pythonheidong.com/blog/article/1152/在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题:class Grandpa{ static ...
    99+
    2019-02-20
    java教程 java
  • 详细分析JVM类加载机制
    目录前言1. jvm 的组成2. 类加载1. 加载  2. 链接3. 初始化3. 类加载器引导类加载器(启动类加载器)扩展类加载器应用程序类加载器4. 双亲委派机...
    99+
    2024-04-02
  • Java 类加载机制详细介绍
    一、类加载器  类加载器(ClassLoader),顾名思义,即加载类的东西。在我们使用一个类之前,JVM需要先将该类的字节码文件(.class文件)从磁盘、网络或其他来源加载到内存中,并对字节码进行解析生成对应的Class对象,这就是类加...
    99+
    2023-05-31
    java 加载机制
  • Java虚拟机之类加载的示例分析
    小编给大家分享一下Java虚拟机之类加载的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序...
    99+
    2023-06-15
  • 【Java系列】Java虚拟机—类加载器介绍
    什么是Java虚拟机  Java虚拟机(Java Virtual Machine,JVM)是一个能够执行 Java 字节码的虚拟计算机。它是 Java 技术的核心部分,是 Java 应用程序运行的基础。 Java 程序在编译后会...
    99+
    2023-09-01
    java 开发语言 原力计划
  • Java高级之虚拟机加载机制的示例分析
    这篇文章给大家分享的是有关Java高级之虚拟机加载机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Jvm要加载的是二进制流,可以是.class文件形式,也可以是其他形式,按照它加载的标准来设计就不会有...
    99+
    2023-05-30
    java 虚拟机
  • Java的类加载机制
    很长一段时间里,我对 Java 的类加载机制都非常的抗拒,因为我觉得太难理解了。但为了成为一名优秀的 Java 工程师,我决定硬着头皮研究一下。01、字节码在聊 Java 类加载机制之前,需要先了解一下 Java 字节码,因为它和类加载机制...
    99+
    2018-10-24
    java教程 Java
  • JVM分析之类加载机制详解
    目录1、前言2、类加载是什么3、类加载过程3.1 加载3.2 链接3.3 初始化4、总结1、前言 JVM内部架构包含类加载器、内存区域、执行引擎等。日常开发中,我们编写的java文件...
    99+
    2022-11-13
    JVM类加载机制 JVM类加载
  • jvm类加载器,类加载机制是什么
    这篇文章主要介绍“jvm类加载器,类加载机制是什么”,在日常操作中,相信很多人在jvm类加载器,类加载机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jvm类加载器,类加载机制是什么”的疑惑有所帮助!...
    99+
    2023-06-16
  • JVM【类加载与GC垃圾回收机制】
    JVM【类加载与GC垃圾回收机制】 🍎一.JVM🍒1.1JVM简介🍒1.2JVM执行流程 🍎二.JVM运行时数据区...
    99+
    2023-09-06
    jvm java 开发语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作