【Android面试】2023最新面试专题:Java虚拟机原理(一)

1 描述JVM类加载过程

这道题想考察什么?

了解JVM是如何加载类的,并且通过JVM类加载过程能更直观了解掌握如APT注解处理器执行、热修复等技术的本质

考察的知识点

JVM类加载过程

考生如何回答

类加载的本质

一般情况下,类的数据都是在Class文件中。将描述类的数据 从Class文件加载到内存 同时 对数据进行校验、转换解析 和 初始化,最终形成可被虚拟机直接使用的Java使用类型。

类加载过程

java类加载过程:加载–>验证–>准备–>解析–>初始化,之后类就可以被使用了。绝大部分情况下是按这

样的顺序来完成类的加载全过程的。但是是有例外的地方,解析也是可以在初始化之后进行的,这是为了支持

java的运行时绑定,并且在一个阶段进行过程中也可能会激活后一个阶段,而不是等待一个阶段结束再进行后一个阶段。

在这里插入图片描述

1.加载

加载时jvm做了这三件事:

​ 1)通过一个类的全限定名来获取该类的二进制字节流

​ 2)将这个字节流的静态存储结构转化为方法区运行时数据结构

​ 3)在内存堆中生成一个代表该类的java.lang.Class对象,作为该类数据的访问入口

2.验证

验证、准备、解析这三步可以看做是一个连接的过程,将类的字节码连接到JVM的运行状态之中

验证是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,不会威胁到jvm的安全

验证主要包括以下几个方面的验证:

1)文件格式的验证,验证字节流是否符合Class文件的规范,是否能被当前版本的虚拟机处理

​ 2)元数据验证,对字节码描述的信息进行语义分析,确保符合java语言规范

3)字节码验证 通过数据流和控制流分析,确定语义是合法的,符合逻辑的

4)符号引用验证 这个校验在解析阶段发生

3.准备

为类的静态变量分配内存,初始化为系统的初始值。对于final static修饰的变量,直接赋值为用户的定义值。如下面的例子:这里在准备阶段过后的初始值为0,而不是7:

public static int a=7
4.解析

解析是将常量池内的符号引用转为直接引用(如物理内存地址指针)

5.初始化

到了初始化阶段,jvm才真正开始执行类中定义的java代码

​ 1)初始化阶段是执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译器自动收集

​ 类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。

​ 2)当初始化一个类的时候,如果发现其父类还没有进行过初始化、则需要先触发其父类的初始化。

​ 3)虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步。


2 请描述new一个对象的流程

这道题想考察什么?

对JVM的理解

考察的知识点

JVM 对象分配、并发安全

考生应该如何回答

JVM创建对象的过程如下图:

在这里插入图片描述

虚拟机遇到一条new指令时,首先检查是否被类加载器加载,如果没有,那必须先执行相应的类加载过程。类加载就是把class加载到JVM的运行时数据区的过程。

检查加载

首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查类是否已经被加载、解析和初始化过。

符号引用:以一组符号来描述所引用的目标。符号引用可以是任何形式的字面量,JAVA在编译的时候一个每个java类都会被编译成一个class文件,但在编译的时候虚拟机并不知道所引用类的地址(实际地址),就用符号引用来代替,而在类的解析阶段就是为了把这个符号引用转化成为真正的地址的阶段。

假设People类被编译成一个class文件时,如果People类引用了Tool类,但是在编译时People类并不知道引用类的实际内存地址,因此只能使用符号引用(org.simple.Tool)来代替。而在类装载器装载People类时,此时可以通过虚拟机获取Tool类的实际内存地址,因此便可以既将符号org.simple.Tool替换为Tool类的实际内存地址。

分配内存

完成类的加载检查后,虚拟机将为新生对象分配内存。为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。

指针碰撞

如果Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为—指针碰撞。

空闲列表

如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为—空闲列表。

选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

  • 如果是Serial、ParNew等带有压缩的整理的垃圾回收器的话,系统采用的是指针碰撞,既简单又高效。
  • 如果是使用CMS这种不带压缩(整理)的垃圾回收器的话,理论上只能采用较复杂的空闲列表。
并发安全

除如何划分可用空间之外,还有另外一个需要考虑的问题是对象创建在虚拟机中是非常频繁的行为,即使是仅仅修改一个指针所指向的位置,在并发情况下也并不是线程安全的,可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。

解决这个问题有两种方案:

CAS

对分配内存空间的动作进行同步处理—实际上虚拟机采用CAS配上失败重试的方式保证更新操作的原子性。

在这里插入图片描述

分配缓冲

把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块私有内存,也就是本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。

JVM在线程初始化时,同时也会申请一块指定大小的内存,只给当前线程使用,这样每个线程都单独拥有一个Buffer,如果需要分配内存,就在自己的Buffer上分配,这样就不存在竞争的情况,可以大大提升分配效率,当Buffer容量不够的时候,再重新从Eden区域申请一块继续使用。

TLAB的目的是在为新对象分配内存空间时,让每个Java应用线程能在使用自己专属的分配指针来分配空间,减少同步开销。

TLAB只是让每个线程有私有的分配指针,但底下存对象的内存空间还是给所有线程访问的,只是其它线程无法在这个区域分配而已。当一个TLAB用满(分配指针top撞上分配极限end了),就新申请一个TLAB。

默认情况下启用允许在年轻代空间中使用线程本地分配块(TLAB)。要禁用TLAB,需要指定-XX:-UseTLAB

内存空间初始化

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值。这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。(如int值为0,boolean值为false等等)。

设置

完成空间初始化后,虚拟机对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息(Java classes在Java hotspot VM内部表示为类元数据)、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头之中。

对象初始化

在以上工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了。但从Java程序的视角来看,对象创建才刚刚开始,所有的字段都还为零值。所以,一般来说,执行new指令之后会接着把对象按照程序员的意愿进行初始化(构造方法),这样一个真正可用的对象才算完全产生出来。

3 Java对象会不会分配到栈中?

这道题想考察什么?

创建的对象是否都在堆中,如果不是,对照JVM运行时数据区堆栈相关内容,能够把控对象不在堆中对程序的影响

考察的知识点

逃逸分析

考生应该如何回答

Java对象可能会分配到栈中。

逃逸分析

逃逸分析指的是分析对象动态作用域,当一个对象在方法中定义后,它可能被外部方法所引用。比如:调用参数传递到其他方法中,这种称之为方法逃逸。甚至还有可能被外部线程访问到,例如:赋值给其他线程中访问的变量,这个称之为线程逃逸。从不逃逸到方法逃逸到线程逃逸,称之为对象由低到高的不同逃逸程度。

如果确定一个对象不会逃逸出线程之外,那么让对象在栈上分配内存可以提高JVM的效率。如果是逃逸分析出来的对象可以在栈上分配的话,那么该对象的生命周期就跟随线程了,就不需要垃圾回收,如果是频繁的调用此方法则可以得到很大的性能提高。

逃逸分析的触发前提条件必须触发JIT执行

public class EscapeAnalysisTest{public static void main(String[] args){long start = System.currentTimeMillis();for (int i = 0; i < 50000000; i++){allocate();}System.out.println((System.currentTimeMillis() - start) + " ms");}static void allocate(){Object obj = new Object();}
}

在上述代码中,Object对象属于不可逃逸,JVM可以做栈上分配。在启动JVM时候,通过 -XX:-DoEscapeAnalysis 参数可以关闭逃逸分析(JVM默认开启)。

开启逃逸分析:

在这里插入图片描述

关闭逃逸分析:

在这里插入图片描述

测试结果可见,开启逃逸分析对代码的执行性能有很大的影响!

最后

此面试题会持续更新,请大家多多关注!!!!

有需要以上面试题的朋友,可以扫描下方二维码免费领取~~

扫码还可以享受ChatGPT机器人的服务,可不要错过!!!

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/56828.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM 锁优化和逃逸分析详解

1 锁优化 JVM 在加锁的过程中&#xff0c;会采用自旋、自适应、锁消除、锁粗化等优化手段来提升代码执行效率。 1.1 自旋锁和自适应自旋 现在大多的处理器都是多核处理器 &#xff0c;如果在多核心处理器&#xff0c;有让两个或者以上的线程并行执行&#xff0c;我们可以让一个…

kubernetes学习之路--BadPods(Part1)

摘要&#xff1a;对Pod配置进行实战学习&#xff0c;以BadPods项目为例学习危险配置。 目录 一.BadPods介绍及使用 二.BadPods配置学习 2.1 less1--Everything allowed 基本操作学习 2.2 less1--Everything allowed 渗透学习 一.BadPods介绍及使用 项目地址&#xff1a;h…

基于GPT3.5实现本地知识库解决方案-利用向量数据库和GPT向量接口-实现智能回复并限制ChatGPT回答的范围...

标题有点长&#xff0c;但是基本也说明出了这篇文章的主旨&#xff0c;那就是利用GPT AI智能回答自己设置好的问题 既能实现自己的AI知识库机器人&#xff0c;又能节省ChatGPT调用的token成本费用。 代码仓库地址 document.ai: 基于GPT3.5的通用本地知识库解决方案 下面图片是整…

英语语法大全

文章目录 一、主语1、名词、代词和动词做主语2、主语从句做主语&#xff0c;谓语动词用单数3、主语从句练习 二、谓语动词1、谓语动词种类2、主谓一致 三、宾语1、单宾语2、双宾语3、复合宾语4、宾语从句 四、定语1、定语从句2、定语从句的翻译 五、状语1、分词做状语2、独立主…

规模效应和网络效应

前几天小米造车、华为造车、大疆造车、滴滴造车、百度造车集中PR。群中讨论智能新能源汽车的未来集中。甚至延伸讨论到了&#xff1a;云计算的未来集中度、SaaS的未来集中度。怎么能提高行业集中度&#xff0c;是我们都在苦苦思考的。 于是就讨论到两个词&#xff1a;规模效应、…

真*加班狗聚众舔福豹《打工人的那些事》

真*加班狗聚众舔福豹《打工人的那些事》 文章目录 近日的杭州金钱豹外逃新闻&#xff0c;相信大家都听说了。 没看过的也不急&#xff0c;我在这里帮大家简单理一理。 根据杭州市富阳区8日官方发布&#xff0c;5月7日20时许&#xff0c;群众报警称在富阳区银湖街道受降四联村…

国内“风口”转变,中国游戏公司纷纷“外逃”,东南亚是个好去处

中国游戏开发商正在加强对国际市场&#xff0c;特别是东南亚市场的承诺&#xff0c;因为他们的国内公司正在努力应对更困难的中国市场&#xff0c;以便实施在下一阶段发展布局。 根据移动应用市场情报公司Sensor Tower的一份报告&#xff0c;按收入排名的前100名全球移动游戏中…

chatgpt赋能python:Python编译成库的利与弊

Python编译成库的利与弊 Python作为一种高级编程语言&#xff0c;具有简洁易读的语法和强大的生态系统&#xff0c;在数据科学、Web开发、游戏开发等领域得到广泛应用。然而&#xff0c;Python解释器的执行效率较低&#xff0c;因此为了提高Python程序的性能&#xff0c;常使用…

产业大模型刚开卷,京东跑进“最后半公里”

点击关注 文&#xff5c;姚 悦 编&#xff5c;王一粟 “京东一直在探索哪些产品、技术、场景可以真正把大模型用起来&#xff0c;在我们内部的场景中反复验证后&#xff0c;才决定在7月份对外发布&#xff0c;现在我们在零售、健康、物流、金融等业务场景里已经积累了一些经…

赠书 | 写作、绘画、游戏、音视频编辑…AIGC为内容生产带来了什么?

文中有数据派THU福利哦 当AIGC产品不断涌向社会&#xff0c;人们纷纷认为美图app“危了“的时候&#xff0c;美图公司创始人兼首席执行官吴欣鸿表示&#xff0c;影像和 AIGC 的创新结合&#xff0c;将带来影像生产力的大爆发&#xff0c;同时会为相关领域带来新的职业和新的创业…

中文公开聊天语料库

源 / 专知 语料内容 该库搜集了包含chatterbot、豆瓣多轮、PTT八卦语料、青云语料、电视剧对白语料、贴吧论坛回帖语料、微博语料小黄鸡语料共8个公开闲聊常用语料和短信&#xff0c;并对其进行了统一化规整和处理&#xff0c;达到直接可以粗略使用的目的。 使用方法 语料下载&…

获得文本语料和词汇资源(基于nltk)

在自然语言处理的实际项目中&#xff0c;通常要使用大量的语言数据或者语料库。本章的目的是要回答下列问题&#xff1a; 什么是有用的文本语料和词汇资源&#xff0c;我们如何使用 Python 获取它们&#xff1f;哪些 Python 结构最适合这项工作&#xff1f;编写 Python 代码时…

NLP领域中文对话系统数据集总结(有下载地址)

一、豆瓣多轮对话数据集 1、简介&#xff1a; 测试数据包含 1000 个对话上下文&#xff0c;对于每个上下文&#xff0c;创建 10 个响应作为候选。正确的响应意味着响应可以自然地回复给定上下文的消息。每对收到三个标签&#xff0c;大多数标签被视为最终决定。 2、数据格式&…

肠道病毒组识别早产儿坏死性小肠结肠炎发病前的特异性病毒特征

期刊&#xff1a;Nature microbiology 影响因子&#xff1a;30.964 发表时间&#xff1a;2022 样本类型&#xff1a;粪便样本 研究背景 坏死性小肠结肠炎&#xff08;NEC&#xff09;是早产的严重后果&#xff0c;通常与肠道细菌微生物群的改变有关。然…

新型病毒来了【PcaPatchDbTask】

急报&#xff01;&#xff01;新型病毒来了【PcaPatchDbTask】 1.什么是PcaPatchDbTask PcaPatchDbTask是一种新型的木马 2.PcaPatchDbTask的危害 【1】他会劫持你的浏览器主页 【2】他会读取你的键盘信息 【3】他会获取你电脑的联系人菜单 【4】它甚至不会被安全软件查杀 3.…

Nature Reviews:给医生的菌群分析指南(下)

本文转载自“态昌基因”&#xff0c;己获授权。 Nature Reviews&#xff1a;给医生的菌群分析指南(上&#xff09;&#xff0c;主要从实验阶段介绍了以下7方面&#xff0c;不清楚的请点击链接跳转原文阅读。 1. 样本选择 2. 样本的采集 3. 样本的保存与保护剂 4. DNA提取 5.我到…

关于儿童急性感染性腹泻

腹泻是一种常见的症状&#xff0c;可导致儿童生长发育迟滞和营养不良。根据世界卫生组织&#xff08;WHO&#xff09;发布的数据显示&#xff0c;急性腹泻在5岁以下儿童死亡原因中排第二位&#xff0c;仅次于肺炎。引起儿童腹泻的原因包括感染和非感染因素&#xff0c;后者主要…

MPO抗体对丨CalBioreagents 中英文说明书

艾美捷CalBioreagents MPO抗体对英文参数说明&#xff1a; CATALOG NUMBER: M684 PRODUCT DESCRIPTION: Mouse Monoclonal anti-human Insulin IMMUNOGEN: Purified human MPO IMMUNOGLOBULIN ISOTYPE: IgG1 PURIFICATION: Purified by DEAE chromatography. BUFFER: Sup…

PICRUSt2菌群功能预测分析

生科云网址&#xff1a;https://www.bioincloud.tech 01 课程简介 PICRUSt2的原理是基于已测微生物基因组的序列&#xff0c;推断它们的共同祖先的基因功能谱&#xff0c;对数据库中其它未测物种&#xff08;基因组未知&#xff09;的基因功能谱进行推断&#xff0c;构建微生物…

病毒组学数据分析 -03 CheckV病毒序列识别

CheckV 是一个完全自动化的命令行管道&#xff0c;用于评估单重叠群病毒基因组的质量&#xff0c;包括识别集成原病毒的宿主污染、估计基因组片段的完整性以及识别封闭基因组。 管道可以分为4个主要步骤&#xff1a;A&#xff1a;去除原噬菌体上的宿主污染 根据与自定义 HMM 数…