JVM部分八股

devtools/2025/3/19 9:17:53/

什么是JVM?

有哪些好处?

索引越界可能导致程序覆盖其他程序内存中的代码

JVM是一套规范,有多种实现

JVM运行流程?

1.类加载器将java程序翻译为java字节码文件

2.运行数据区将字节码文件加载到内存,字节码文件是JVM规范的文件,不能直接运行,而是交给执行引擎运行

3.执行引擎中的解释器将字节码文件翻译为机器指令,交给CPU执行,执行过程中可能通过本地方法调用接口调用本地方法

类的生命周期?

加载:将class文件从磁盘导入内存

连接:生成虚方法表,确定每一个方法的地址

        验证:验证字节码文件是否符合JVM规范等

        准备:为类变量初始化默认值,如:0,false等

        解析:将字符引用变为直接引用,直接指向内存中的方法

初始化:使用的时候对其初始化,比如在new的时候

使用

卸载:使用结束后被垃圾回收器回收

JVM的类加载机制?

JVM类加载器结构:
启动类加载器:加载jre中lib目录下的核心类库

拓展类加载器:加载jre中lib目录下的ext拓展目录中的类包

应用程序类加载器:加载classpath路径下的类包,主要是自己写的类

自定义加载器:加载用户自定义路径下的类包

JVM加载类过程:

先将类加载请求交给自定义类加载器,自定义类加载器将加载类请求交给应用程序类加载器,应用程序类加载器再将请求给拓展类加载器,拓展类加载器再把请求给启动类加载器,如果启动类加载器能够加载就由启动类加载器加载,不能的话逐级交给子(下级)加载器加载,直到加载成功。

以上的这种加载方式叫做类加载器的双亲委派机制。

双亲委派机制的好处:

1.保证类只加载一次,不重复加载。

2.一定程度保证了类加载的安全性,比如:用户自定义了一个String类,那么在加载的时候就会由启动类加载器加载核心类库中的String类而不是加载用户自定义的String类,防止由于用户篡改核心类库导致的不安全。

双亲委派机制可以被打破:tomcat的例子,在tomcat上由不同的web应用,如果不同的web应用需要加载同一个类,由于双亲委派不重复加载的特性就会导致只能有一个web应用能够加载该类,在这种情况下,应该打破。

tomcat通过在自定义实现类加载器中的loadClass方法中覆盖默认的双亲委派行为实现。

对象的创建过程?

1.当接受到一条new指令时,首先在常量池中检查是否存在类的引用符号,判断类是否被加载,解析,初始化过,如果有进入下一过程;如果没有,执行类加载流程。

2.JVM为对象开辟内存空间(根据回收机制不同,选择指针碰撞或空闲列表的方式)。

什么是指针碰撞?什么是空闲列表?

3.为对象开辟内存后,将内存中的所有数据初始化为默认值,int为0,boolean为false等。

4.在对象头内设置信息,如:是哪个类的对象,属于哪一代,是否加锁(偏向锁,轻量级锁,重量级锁)等。

5.调用构造方法初始化对象,赋予对象有意义的值。

静态常量池(class常量池)和运行时常量池?

静态常量池:每个class文件里有一个class常量池,包含符号引用和字面量(数值型和字符型)。

运行时常量池:当class被加载时,class常量池中的符号引用和数值型字面量会被加载到直接内存方法区中的运行时常量池和数值型字面量,其中符号引用会被替换为直接引用,而字符型字面量则会被加载到队中的字符串常量池中,用来节省空间。

class常量池到运行时常量池的转变发生在类加载过程的解析阶段。

CPU飙高排查?

OOM原因及如何排查?

JVM如何实现多态?

在实现多态的类加载过程中,由于无法确定具体到底该使用哪一个方法,所以多态方法部分的符号引用并不会替换为直接引用,而是等到真正调用时通过调用对象类型来决定具体使用哪一个方法。通过查询虚方法表来查找对应方法。

为什么将永久代移除,而在内存里加入了元空间?

永久代在堆内存中,使用堆内存空间,较为局限,而元空间在操作系统管理的本地内存中,本地内存与虚拟机使用内存相隔离,不受堆内存大小限制,这也是解决永久代频繁导致OOM异常的方法。

什么是虚拟机栈?

虚拟机栈是线程执行时所占用的内存,一个栈由多个栈帧构成,栈帧对应于调用方法所使用的内存空间,但一个栈只有一个活动栈帧,对应着当前正在执行的方法。

栈帧的结构:

局部变量表

操作数栈

动态链接

方法出口

栈帧弹起就会释放内存,不需要垃圾回收。

栈帧大小和可活动线程数相互制约。

方法内局部变量是否线程安全?未逃出方法作用范围安全,否则需要考虑线程安全问题。

栈溢出,StackOverFlow异常,递归调用。

什么是堆?

线程共享的内存区域,主要用来存储类的实例对象和数组等,当堆内存满且无法扩展时,抛出OutOfMemory异常。堆内主要分为年轻代和老年代,年轻代分为伊甸园区和两个大小相等的幸存区,年轻代的数据经过一定次数的垃圾回收后仍然存在的将被转移到老年代。老年代用来存储存活时间长的数据。JDK8以前堆中还有一个永久代,但如果加载大量类容易大量占用堆内存,导致OOM异常,所以移出堆,放到本地内存中,叫做元空间,但元空间,方法区,永久代其实是类似的。

为什么使用直接内存的NIO读写性能比常规I/O更高?

常规I/O在数据读写时,比如一个从磁盘中读取文件的操作,需要在内核态将磁盘写入内核态缓冲区,内核态缓冲区的数据再写入用户态的java缓冲区,而使用直接内存的NIO则直接将磁盘文件写入直接内存,JVM可以直接操作直接内存,不需要在堆中开辟额外空间,同时减少了两个缓冲区间传输数据的时间,大大提高了数据读写的效率。


http://www.ppmy.cn/devtools/168298.html

相关文章

【计算机视觉】工业表计读数(2)--表计检测

1. 简介 工业表计(如压力表、电表、气表等)在工控系统、能源管理等领域具有重要应用。然而,传统人工抄表不仅工作量大、效率低,而且容易产生数据误差。近年来,基于深度学习的目标检测方法在工业检测中展现出极大优势&…

【第13节】windows sdk编程:GDI编程

目录 一、GDI 概述 二、设备环境概念 三、使用 GDI 绘图对象 四、使用 GDI 坐标系统 五、使用GDI绘图 5.1 输出文字 5.2 画点和线 5.3 画矩形框、圆和多边形 5.4 画位图和图标 5.5 双缓冲技术 六、综合代码示例 一、GDI 概述 Windows 应用程序不支持标准输出函数&am…

【最佳实践】Go 状态模式

设计思路 状态模式的核心在于将对象的行为封装在特定的状态类中,使得对象在不同的状态下表现出不同的行为。每个状态实现同一个接口,允许对象在运行时通过改变其内部状态对象来改变其行为。状态模式使得状态转换更加明确,并且易于扩展新的状…

蓝桥杯学习-01好数

01枚举 1.好数 问题描述 一个整数如果按从低位到高位的顺序,奇数位 (个位、百位、万位 ⋯⋯ ) 上的数字是奇数,偶数位 (十位、千位、十万位 ⋯⋯ ) 上的数字是偶数,我们就称之为 “好数”。 给定一个正整数 NN,请计算从 1 到 …

NAT技术-初级总结

NAT–网络地址转换 NAT基本逻辑是实现公网IP地址和私网IP地址的转换 华为设备所有NAT相关的配置都是在边界路由器的出接口上配置 1.静态NAT–一对一 就是在我们私网边界路由器上建立维护一张静态地址映射表,这张表 反映的是公网IP地址和私网IP地址之间一一对应的关系 只能一个…

[K!nd4SUS 2025] Crypto

最后一个把周末的补完。这个今天问了小鸡块神终于把一个补上,完成5/6,最后一个网站也上不去不弄了。 Matrices Matrices Matrices 这个是不是叫LWE呀,名词忘了,但意思还是知道。 b a*s e 这里的e是高斯分成,用1000…

使用Azure CDN进行子域名接管

目录: 寻找子域名 寻找潜在的子域名接管 创建 PoC(概念验证) 本文的重点描述我发现的一起利用 Microsoft Azure 的 CDN (azureedge.net) 实现的子域名接管案例。我使用自己的域名重现了该问题,并会介绍我发现它的过程以及如何创建…

Qwen2.5-VL 开源视觉大模型,模型体验、下载、推理、微调、部署实战

一、Qwen2.5-VL 简介 Qwen2.5-VL,Qwen 模型家族的旗舰视觉语言模型,比 Qwen2-VL 实现了巨大的飞跃。 欢迎访问 Qwen Chat (Qwen Chat)并选择 Qwen2.5-VL-72B-Instruct 进行体验。 1. 主要增强功能 1)直观地理解事物&…