首页 > 编程语言 >Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机

时间:2023-06-28 12:32:02浏览次数:35  
标签:插件 垃圾 对象 虚拟机 算法 内存 JVM Android 引用


一、Java虚拟机(JVM)

1、JVM整体结构

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_android

  1. 使用javac将java文件编译成class文件。
  2. 类加载器(ClassLoader)将class字节码加载进JVM对应的内存中。
  3. JVM将内存分配给方法区、堆区、栈区、本地方式栈4个部分,这4个部分分别存储字节码不同的部分。
  4. 垃圾回收器(gc)会管理整个内存空间中的垃圾。

2、Java代码的编译和执行过程

下图是Java代码编译的详细流程(即,javac的执行过程),了解即可,一般只要知道java文件是通过javac命令编译成class文件,再通过java命令运行的就可以了,如:

javac Hello.java
java Hello

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_JVM_02

3、类加载器

1)Java中的类加载器

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_android_03

2)加载流程

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_Java_04

  • Loading:类的信息从文件中获取并载入到JVM的内存中。
  • Verifying:检查读入的结构是否符合JVM规范的描述。
  • Preparing:分配一个结构用来存储类信息。
  • Resolving:把类的常量池中的所有符号引用变成直接引用。
  • Initializing:执行静态初始化程序,把静态变量初始化成指定的值。

4、内存管理

java中的内存管理指的是下图中“内存空间”部分的内存操作。

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_java_05

1)Java栈区:

作用:存放java方法执行时所有的数据。 组成:由栈帧组成,一个栈帧代表一个方法的执行。

Java栈帧:每个方法从调用到执行完成就对应一个栈帧在虚拟机栈中入栈到出栈。它描述了一个方法的局部变量表、栈操作数、动态链接、方法出口。

2)本地方法栈

与Java栈区基于一致。

作用:本地方法栈是专门为native方法服务的。

3)方法区

存储被虚拟机加载的类信息、常量、静态常量、即时编译器编译后等数据(这些数据在程序启动后会永远占据内存)。

4)堆区

作用:所有通过new创建的对象的内存都在堆中分配。 特点:是虚拟机中最大的一块内存,是GC要回收的部分。

对于堆区,其内存结构还有些不一样的地方,先看下图:

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_JVM_06

简单来说,堆区分为新生代(Young Generation)与老年代(Old Generation),程序在创始对象时,对象会先被分配到新生代中,当新生代区内存不足时,JVM会通过一定的算法规则将新生代中的对象转移至老年代中,当新生代与老年代都没有足够的内存空间时,JVM就会抛出OOM异常。

5、垃圾回收

1、垃圾收集算法

1)引用记数算法(jdk1.2之前)

在内存创建对象的同时,会为它创建一个引用记数器,并将引用记数器加1,每次有引用引用到此对象时,记数器就会累计加1,而当其中一个引用销毁时,记数器就会减1,当引用记数器为0时,说明该对象已经是垃圾对象,下次gc时,对象就会被回收了。

弊端: 对象A与对象B互相引用时,这2个对象的引用记数器永远是正数,当这2个对象都没有被其他对象所引用时(对象不可达),会因为它们的引用记数器不为0导致它们不会被gc回收。

2)可达性算法(jdk1.2 +)

也称为根搜索算法。把程序所有的引用关系看做是一张图(有向图),从GC Root节点开始寻找所有的引用节点,当所有的引用节点寻找完毕之后,剩余的节点被认为是没有引用的节点,即不可达的节点,就是垃圾对象。

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_JVM_07

上图中ObjD、E、F因为没有路径可达,所以是垃圾对象。

2、引用的类型

java中的引用类型有4种:强引用、软引用、弱引用、虚引用。其中,强引用和弱引用在开发中最常用。

弱引用的创建

// 强引用
Object obj = new Object();
// 弱引用,此时obj与wf都引用了Object对象
WeakReference<Object> wf = new WeakReference<Object>(obj);
// 断开强引用,此时只有wf引用这个Object对象
obj = null;
// 通用弱引用获取Object对象(可能为null)
wf.get();

在使用wf.get()时,要判断获取到的对象是否为null,因为弱引用不会阻止对象的回收。

3、垃圾回收算法

1)标记-清除算法

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_jvm_08

从根集合遍历所有的引用,上图中,根集合引用了A,A引用了C,B是不可达的对象引用,在扫描阶段中,B会被标记为垃圾对象,当垃圾回收机制执行时,会直接将B对象置为空,此时内存块中就只剩下A、C对象引用,B就被垃圾回收给回收掉了。 优点:不需要进行对象的移动,仅对不存活的对象进行处理,在存活对象比较多的情况下极为高效。 缺点:由于标记-清除算法会直接回收掉不存活的对象,会造成内在碎片,不利于后续对象的分配

2)复制算法

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_Java_09

从根集合开始遍历,上图中,遍历到A时是可达的,就把A复制到另一块空闲的内存中,继续遍历,发现B不可达,直接跳过,往后,发现C可达,就把C同样地复制到这块空闲内存中,等所有复制都处理完时,把原来的内存空间清空,只保留复制后的这块内存空间。 优点:当存活对象比较少时,极为高效,且不会有产生内存碎片。 缺点:需要一块内存作为交换空间来进行对象的移动。

3)标记-整理算法

Android 中高级面试原理:热修复与插件化基础—Java与Android虚拟机_java_10

从根集合开始遍历,通过对整个内存区的扫描,将可回收对象扫描出来,上图中,到了第二阶段,就将B标记为可回收对象,到了第三个阶段,直接扫描并消除内存中被标记的对象,同时,在回收不存活对象占用的空间时,会将内存中所有存活对象往左端空闲处移动,并更新对应的指针。

这三种算法各有优劣,JVM在处理垃圾时会整合去使用,并不是只使用其中某个算法。当内存中存活的对象比较少时,采用“复制算法”去处理垃圾对象;当内存中存活的对象比较多时,会采用“标记-整理算法”或“标记-清除算法”去处理垃圾对象。

4、触发回收

  • Java虚拟机无法再为新对象分配内存空间了
  • 手动调用System.gc()方法(强烈不推荐,不会马上执行,却会加大虚拟机压力)
  • 低优先级的GC线程,被启动了。

二、Android 虚拟机

1、Dalvik VM 与 JVM 的不同

  • 执行的文件不同,一个是class,一个是dex。
  • 类加载的系统与JVM区别较大。
  • 可以同时存在多个DVM,但JVM只能存在一个。
  • Dalvik是基于寄存器的,而JVM是基于栈的。

2、Dalvik VM 与 ART 的不同

  • DVM使用JIT来将字节码转换成机器码,效率低。
  • ART采用了AOT预编译技术,执行速度更快。
  • ART会占用更多的应用安装时间和存储空间。

最后

最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

标签:插件,垃圾,对象,虚拟机,算法,内存,JVM,Android,引用
From: https://blog.51cto.com/u_16163453/6570441

相关文章

  • BAT 大厂Android研发岗必刷真题:Android异常与性能优化相关面试问题
    今天来讲一讲在面试中碰到的Android异常与性能优化相关问题:1、anr异常面试问题讲解a)什么是anr?应用程序无响应对话框b)造成anr的原因?**主线程中做了耗时操作c)android中那些操作是在主线程呢?activity的所有生命周期回调都是执行在主线程的Service默认是执行在主线程的BroadcastR......
  • Android LayoutManager高端玩家,实现花式表格!
    如果你对RecyclerView原理还不是特别了解,非常建议你读一下。本文的项目也是学习自定义LayoutManager绝佳资料,大家有需要的可以好好拜读。前言表格是自打我进公司以后就使用的控件,起初使用的是ScrollablePanel,从一开始的被花式吊打,到后期的熟练使用。大佬写的控件确实给我的工作带来......
  • Android ‘Handler()‘ is deprecated
    privateHandlerhandler=newHandler();Handler()此构造函数在Android11/R之后已弃用。在Handler构造期间隐式选择Looper会导致操作无声地丢失(如果Handler不期待新任务并退出)、崩溃(如果有时在没有Looper活动的线程上创建处理程序)或竞争条件,处理程序关联的线程不......
  • Android线程管理之ExecutorService线程池
    为什么要引入线程池?   1.)newThread()的缺点每次newThread()耗费性能调用newThread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪。不利于扩展,比如如定时执行、定期执行、线程中断  2.)采用线程池的优点重用存在的......
  • vscode插件
    bookmarksc/c++c/c++extensionpackCMakeCMakeToolsDevContainersDockerGitHistoryGitLenshighlight-wordsMarkdownAllinOneOneDarkProRemote-SSHROSTodoTreecatkin-tools......
  • vscode推荐插件
    js相关的插件JavaScript(ES6)codesnippetsBabelES6/ES7htmlcss汉化Chinese(Simplified)(简体中文)LanguagePackforVisualStudioCode标签自动闭合AutoCloseTaggit相关插件GitHistoryGitLens—Gitsupercharged......
  • 《深入理解Java虚拟机第3版》垃圾收集器与内存分配策略、虚拟机性能监控故障处理工具
    目录往期博客:Java课堂篇3_初识JMM、常量池简单理解(字符串常量池、静态常量池、大整型常量池)为什么要了解垃圾收集和内存分配?如何判断对象已死?引用计数算法可达性分析算法JDK1.2之后引用的扩充回收方法区垃圾收集算法分代收集理论标记清除标记复制标记整理对象分配虚拟机......
  • Taurus .Net Core 微服务开源框架:Admin 插件【3】 - 指标统计管理
    前言:继上篇:Taurus.NetCore微服务开源框架:Admin插件【2】-系统环境信息管理本篇继续介绍下一个内容:1、系统指标节点:Metric- API 界面界面图如下:1、简要说明:数据查看:该页面默认呈现API访问次数的统计,由于要显示的数据列有点多,24小时,因此用了全屏显示。同时提供快捷......
  • 实践篇:1 虚拟机使用rmp方式安装部署GitLab-ce
    01环境准备电脑:MACAir虚拟机:VMwareFusion12.2.3Linux环境:CentOS702rpm方式安装部署GitLab服务步骤1:centos7安装wget1、查看是否安装:rpm-qa|grep"wget"如果已安装会显示wget相关信息,如果不显示信息就表示没安装,wget命令自然不能使用。2、安装wgetyum-yinsta......
  • 【ubuntu22.04】设置了共享文件夹但是在虚拟机中找不到/mnt/hgfs文件夹的问题
    【ubuntu22.04】设置了共享文件夹但是在虚拟机中找不到/mnt/hgfs文件夹的问题问题描述vmware设置了共享文件夹,并且设置文件夹权限后,在虚拟机中找不到共享文件夹解决步骤:1、设置共享文件夹首先vmware-workstation需要安装Vmwaretools工具,我这里已经安装了,然后在Vmware菜单......