Java虚拟机(JVM)快速复习指南
Java虚拟机(JVM)是Java程序的核心组件,它负责将Java源代码编译成可在各种平台上运行的字节码,并提供内存管理、垃圾回收、线程管理等功能。
Java Virtual Machine java程序的运行环境。(java进制字节码的运行环境)
好处:一次编写,到处运行自动内存管理,垃圾回收机制
以下是一些关于JVM的重要概念和知识点的快速复习:
一、JVM的组成和工作流程
1. JVM架构
-
类加载器(ClassLoader)
负责将类文件加载到JVM中。
类加载器负责将类文件加载到JVM中。Java中的类加载器遵循双亲委派模型,按照从上到下的顺序逐级委托父类加载器加载类。
主要的类加载器包括:
三种内建类加载器 分别是启动类加载器、扩展类加载器和应用程序类加载器。
-
启动类加载器(Bootstrap ClassLoader):负责加载Java的核心类,如
java.lang
包中的类,是最顶层的类加载器,通常由C++实现。 -
扩展类加载器(Extension ClassLoader):负责加载Java的扩展类,位于
JAVA_HOME/lib/ext
目录下的JAR文件中的类。 -
应用程序类加载器(Application ClassLoader):也称为系统类加载器,负责加载应用程序的类,通常从类路径中加载。
双亲委派模型 按照从上到下的顺序逐级委托父类加载器加载类。
什么是双亲委派模型?
加载某一个类,现委托上一级的加载器进行加载,如果上一级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类
JVM为什么采用双亲委派机制?
通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无须重复加载,保证唯一性,为了安全,保证类库API不会被修改
类装载的执行过程
运行时数据区域
JVM的运行时数据区域包括:
方法区(Method Area):用于存储类的结构信息、静态变量、常量池等数据。在HotSpot虚拟机中,方法区被称为永久代(Permanent Generation),但在Java 8之后,使用元空间(Metaspace)替代了永久代。
堆(Heap):用于存储对象实例和数组。堆是Java虚拟机中内存管理的核心区域,主要用于存放所有被实例化的对象。堆被所有线程共享,因此是线程安全的。
虚拟机栈(VM Stack):用于存储方法调用和局部变量。每个线程在执行Java方法时都会创建一个栈帧,用于存储方法的局部变量表、操作数栈、动态链接、方法返回地址等信息。
本地方法栈(Native Method Stack):为Java虚拟机使用到的Native方法服务,与虚拟机栈类似,但用于执行本地(非Java)方法。
程序计数器(Program Counter Register):当前线程执行的字节码行号指示器。每个线程都有自己的程序计数器,用于记录线程执行的当前字节码指令地址。
线程共享区域
主要用来保存对象实例,数组等,当堆中没有足够的内存空间分配给实例,也无法再拓展时,则抛出OutOfMemoryError异常。
java堆:
什么是虚拟机栈
Java Virtual machine Stacks(java虚拟机栈)
每一个线程运行时所需要的内存,称为虚拟机栈,先进后出每一个栈由多个栈帧(frame)组成,对应着每次方法调用时所占用的内存.。每一个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
垃圾回收是否涉及栈内存?
垃圾回收主要指的就是堆内存,当栈帧弹栈以后,内存就会释放
栈内存分配越大越好吗?
未必,默认的栈内存通常时1024k栈帧过大会导致线程数变少,例如,机器总内存为512m,目前能活动的线程数则为512个,如果把栈内存改为2028k,那么能活动的帧就会减半
方法内的同部变量是否线程安全?
如果方法内局部变量没有逃离方法的作用范围,它是线程安全的如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全;用图说明
栈内存溢出情况?
栈帧过多导致栈内存溢出,曲型问题:递归调用栈帧过大导致栈内存溢出
堆和栈的区别是什么?
栈内存一般用来存储局部变量和方法调用,但堆内存是用来存储Java对象和数组的。堆会GC垃圾回收,而栈不会
栈内存是线程私有的,而堆内存是线程共有的
两者异常错误不同,但如果栈内存或者堆内存不足都会抛出异常栈空间不足:java.lang.StackOverFlowError堆空间不足:java.ong.OutOfMemoryError
方法区
方法区(Method Area)是各个线程共享的内存区域主要存储类的信息、运行时常量池
虚拟机启动的时候创建,关闭虚拟机时释放如果方法区域中的内存无法满足分配请求,则会抛出OutOfMenoryError:Metaspace
常量池
可以看着是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名参数类型、字面量等信息
直接内存
直接内存:并不属于JVM中的内存结构,不由VM进行管理。是虚拟机的系统内存,常见于NIO操作时,用于数据缓冲区,它分配回收成本较高,但是读写性能高
垃圾回收(Garbage Collection)
- 垃圾回收算法:包括标记-清除、复制、标记-整理等。
- 垃圾收集器(Garbage Collector):包括Serial、Parallel、CMS、G1等。
- 垃圾回收时机:当对象不再被引用时,会被判定为垃圾,随后由垃圾回收器进行回收。
对象什么时候可以被垃圾回收器回收?
简单一句就是:如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收
1.定位垃圾的方式:
引用计数法:一个对象被引用了一次,在当前的对象头上递增一次引用次数,如果这个对象的引用次数为0,代表这个对象可回收
可达性算法
JVM垃圾回收器算法有哪些?
标记清除算法:
将垃圾回收分为2个阶段
分别是标记和清除
1.根据可达性分析算法得出的垃圾进行标记
2.对这些标记为可回收的内容进行垃圾回收
复制算法
标记整理算法
说一下JVM中的分代回收?
分代收集算法:
在Java8时,堆被分为了两份:新生代和老年代【1:2】
对于新生代,内部又被分为了三个区域
伊甸园区Eden,新生的对象都分配到这里
幸存者区survivor(分为from和to)
Eden区,from区、to区【8:1:1】
说一下JVM有哪些垃圾回收器?
在JVM中,实现了多种垃圾回收器,包括:
串行垃圾收集器
Serial和Serial Old串行垃圾收集器,是指使用单线程进行垃圾回收,堆内存较小,适合个人电脑
Serial:作用于新生代,采用复制算法
Serial Old: 作用于老年代,采用标记-整理算法
垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要智停(STW),等待垃圾回收完成。
.
并行垃圾回收器
CMS垃圾收集器
G1垃圾回收器
文章引用b站黑马课程整理而来新版Java面试专题视频教程,java八股文面试全套真题+深度详解(含大厂高频面试真题)_哔哩哔哩_bilibili