谈谈 Java Virtual Machine 以及 GC

本文详细解析JVM(Java虚拟机)的五大核心模块,包括类装载器子系统、运行时数据区、执行引擎、本地方法接口及垃圾收集机制。探讨了字节码执行、对象存储、线程栈管理、本地方法调用以及GC策略,帮助读者全面掌握JVM的工作原理。

JVM(Java Virtual Machine),Java 虚拟机,它是一种标准,通过这种标准它不需要依赖硬件,通过 jvm 虚拟的硬件操作实现“一次编译,多次运行”。

JVM 总共分为五个模块,分别是:类装载器子系统、运行时数据区、执行引擎、本地方法接口和垃圾收集模块

大家可以看看下面这个图,把重点的部分都已经呈现出来了。

类装载子系统:

 负责将字节码文件加载到运行时数据区中,完成程序的装载功能

字节码执行引擎:

根据运行平台环境不同,对字节码指令进行翻译,让硬件去做相应的工作

堆:

堆主要是用来存储在程序运行过程种产生的对象信息,当然,它自身也有非常复杂的结构,后面提到的GC也是和它密切相关的

栈:

栈,又称线程栈,当执行 main 函数时候,就会生成一个 main 线程栈帧,同时将这个线程入栈到当前线程栈中,当发生函数调用时候,会对新的方法生成一块栈帧结构,入栈到当前线程栈中。

栈帧内部也是有很复杂的数据结构,其中最重要的 4 块内容已经在图上标注出来了。

局部变量表:

用来存放函数局部变量的

操作数栈:

用来存放当前正在使用的数据,是以栈的结构组织存储的

动态链接:

程序中会存在大量的地址引用,但是程序中的地址引用都是逻辑地址引用,并不是物理内存地址引用,动态链接的作用就是实现逻辑地址到物理地址的变换工作

方法出口:

当函数调用执行完毕后,需要回到调用程序段继续程序的运行,所以需要方法出口来进行记录

本地方法栈:

在 Java 诞生的时候还是 C 语言的天下,当时的 JVM 是由 C 语言编写的,所以需要使用 java 去调用 c 语言的类库,这就称为本地方法。所以本地方法栈就是用来存储调用本地方法所产生的临时信息

方法区:

方法区,在JDK1.8以后被改名为元空间,主要就是存储类元信息,常量,静态变量,方法等等

通过 new 字段生成的对象都是对这个区域类元信息的引用

程序计数器:

程序计数器,就是用来表明程序当前运行到那里的位置信息,程序运行无非就三种结构:顺序、循环、选择,但是无论是什么方式都需要通过一个标识来一行一行的运行程序,这个标识就是程序计数器

GC

 Java 垃圾回收机制,主要回收的区域就是

堆主要分为两大块:年轻代和老年代。每 new 一个对象都被放在 Eden 区,如果 Eden 满的话会触发一次 minor GC 操作,将 Eden 中无引用的对象回收掉,将剩下的对象剪切到 from 区域,如果再一次 Eden 区域满的话,会将 Eden 区域和 from 区域都进行回收,将剩下的对象放入 to 区域。每个对象头部都有一条分代年龄字段,初始为 0,最大为 15 ,没进行一次 minor GC后,幸存下来的对象分代年龄字段会加一,当分代年龄为 15 时,GC就会认为这个对应老了,不能够再年龄代中活跃了,将他放到老年代区域中。但是总有一个时候老年代区域也会被放满吧?当老年代被放满的时候系统就会触发一次 full GC,注意执行这个 GC 操作后系统将停止运行,专门用来垃圾回收。

所以 JVM 调优首先要做的就是合理分配他们的内存大小,减少其 full GC 执行的频率。另外就是调整 GC 算法,这个就是更深层次的问题了,想要了解 GC 算法小伙伴自行下去百度~

以下为部分 Java 测试相关的面试题: ### 基础概念类 1. 请解释 JRE、JDK、JVM 和 JIT 的区别。 JRE 代表 Java 运行时(Java run - time),是运行 Java 引用所必须的。JDK 代表 Java 开发工具(Java development kit),是 Java 程序的开发工具,如 Java 编译器,它也包含 JRE。JVM 代表 Java 虚拟机(Java virtual machine),它的责任是运行 Java 应用。JIT 代表即时编译(Just In Time compilation),当代码执行的次数超过一定的阈值时,会将 Java 字节码转换为本地代码,像主要的热点代码会被转换为本地代码,这样有利于大幅度提高 Java 应用的性能[^2]。 2. 简述 Java 内存模型 JMM。 ### 代码执行结果类 3. 分析以下代码的执行结果: ```java public class TryDemo { public static void main(String[] args) { System.out.println(test1()); } public static int test1() { int i = 0; try { i = 2; return i; } finally { i = 3; } } } ``` 答案是结果为 2。因为 `finally` 代码块会执行,且在 `return` 之前执行,但如果 `finally` 有 `return` 那么 `try` 的 `return` 才会失效,此代码中 `finally` 没有 `return`,所以返回 `try` 中的 `i` 值 2 [^1]。 ### 性能与内存类 4. 谈谈 JVM 运行时内存区域划分,以及内存溢出 OOM 和堆栈溢出 SOE 的示例及原因。 5. 常见的 GC 回收算法有哪些,它们的含义是什么? 6. 列举常见的 JVM 性能监控和故障处理工具,并说明其用途。 ### 类加载相关类 7. 解释类加载器、双亲委派模型以及一个类的生命周期。 8. 简述类加载的过程。 ### 引用类型类 9. 解释强引用、软引用、弱引用、虚引用的区别。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值