JVM虚拟机——面试中的八股文

这个部分呢,纯粹就是八股,只是面试要考的,日常工作却用不到,但在这一阶段仍要好好掌握。

面试里关于JVM常考的内容,分为三个方面,一是JVM内存区域划分;二是类加载机制;三是垃圾回收机制。

JVM内存区域划分

为什么要划分区域

JVMJava虚拟机是仿照真实的机器、真实的操作系统进行设计的,在真实的操作系统中,对于进程的地址空间是进行了分区域的设计,于是JVM也就仿照了操作系统的情况,也进行了分区域的设计。

JVM具体是怎么划分的呢?

核心区域有四个:

1.程序计数器

这个是一个很小的区域,保存在内存空间当中,只是用来记录当前指令执行到哪个地址了。

2.元数据区

这里用来保存当前类被加载好的数据。

我们都知道,我们写Java代码,把.java变成.class文件,要想运行这个代码,就需要把.class加载到内存里面(类加载)。

这里的类对象,就是图中的Test.class。

3.栈

栈的作用是保存方法的调用关系。当然,这里谈到的栈和堆与数据结构里的栈和堆是没有关系的。

写代码的时候,肯定会有方法调用,每次调用方法,就会进入方法的内部执行,当方法执行完毕,返回到调用位置,然后继续往后走。

在栈中,执行main方法,main方法在栈中申请一块空间,在main方法中,执行到调用的test1方法时,test1方法里面有参数、局部变量、返回值、返回的地址(test1结束后继续执行哪里),这个就是"栈帧"。

而JVM这个进程,是C++代码实现的程序,这个进程本身就是存在一系列方法调用的。

就像下图,操作系统原生的栈,叫做"本地方法栈",在这之后在C++代码中,构成了一个JVM虚拟机程序,通过这些C++代码,解释执行.class中的字节码,这些操作是操作系统实现的,不需要C++代码干预。

解释执行字节码的时候,又会涉及到一些Java的方法调用,通过上述C++代码,又构造出一个Java的栈,C++的栈帧中,其中有一个方法就在里面构造了Java的栈,这些操作是由C++代码实现的,放Java方法的栈(JVM栈),无法被Java代码干预。

当然,这两个栈之间还会有很多的联系,Java代码中有时候可能会调用到C++的代码,比如Thread.sleep这样的操作,本质上还是要调用操作系统的api的。

4.堆

堆的作用是保存new的对象。

图中的new Test()部分一定会保存在堆中,而对象t不一定,t保存了new Test()的地址,但要判定t保存在哪里,这要看t的成分:

如果t是一个局部变量,t就是在栈上

如果t是一个成员变量,t就是在堆上

如果t是一个静态成员变量,t就是在元数据区上

堆是JVM中最大的空间区域,可以为集合类里面添加元素,如果堆上的对象不再使用的话,就需要被释放掉(垃圾回收)。

这里是这四个划分的结构:

其中,元数据区和堆,整个Java进程共用同一份,程序计数器和栈,一个进程中可能有多份(因为一个进程可能有多个线程,每个线程有一份)。

JVM类加载

类加载本身是一个复杂的事情。

在面试角度,类加载主要关心两个方面:

1.类加载步骤有哪些

Java的官方文档上,也有对应的描述。一共有三个大的阶段,其中第二个阶段又分成三个步骤,一共是5个步骤。

(1)加载:找到.class文件

根据类的全限定名(包名+类名,形如java.lang.String),然后打开文件,读取文件内容到内存里。

(2)验证:解析、校验.class文件读到的内容是否是合法的,并且把这里的内容转成结构化的数据

这里的.class文件是二进制的文件,他的格式是有明确要求的。

这个表格中,constant_pool是常量池,这里用数组表示;this_class、super_class分别为子类与父类;interface是接口(同样用数组表示),校验这个.class文件是否符合表格中的格式。

(3)准备:给类对象申请内存空间

此处申请的内存空间,相当于是"全0"的空间。

(4)解析:针对字符串常量进行初始化

字符串常量本身就包含在.class文件中,就需要.class文件里解析出来的字符串常量放到内存空间里(在元数据区的常量池中)。

(5)初始化:针对刚才谈到的类对象进行最终的初始化

针对类对象的各种属性进行填充,包括类中的静态成员,因为刚申请到内存空间,类对象是"全0"的,当然,如果这个类还有父类,并且父类还没有加载,此环节也会触发父类的类加载。

2.类加载中的"双亲委派模型"是怎么回事

这里的内容,明天我们继续。

这些八股文该背还是要背的,希望大家好好掌握。

相关推荐
z4424753262 小时前
CSS如何保证移动端顶部Fixed头部的安全区域
jvm·数据库·python
A-Jie-Y2 小时前
JAVA设计模式-单例模式
java·设计模式
编程之升级打怪2 小时前
设计模板引擎类的主要接口
java
weixin_458580122 小时前
golang如何优化反射性能_golang反射性能优化技巧
jvm·数据库·python
步辞2 小时前
CSS如何解决小屏幕上的长单词截断版面
jvm·数据库·python
ffqws_2 小时前
Spring Boot 整合 PageHelper 实现分页查询
java·spring boot·mybatis
qq_460978402 小时前
如何在无向图中找出从任意节点可达的所有节点(连通分量识别)
jvm·数据库·python
大龄码农-涵哥2 小时前
Java调用AI大模型API入门:从零开始接入ChatGPT/通义千问
java·人工智能·chatgpt
ch.ju2 小时前
Java程序设计(第3版)第二章——for嵌套输出图形
java