JVM 一(八股文)

虚拟机的结构

类加载子系统

类加载子系统负责从文件系统或者网络中加载Class 信息,加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中可能还会存放运行时常量池信息,包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)。

Java堆:

在虚拟机启动的时候建立,它是Java程序最主要的内存工作区域。几乎所有的Java对象实例都存放于Java堆中。堆空间是所有线程共享的,这是一块与Java应用密切相关的内存区间。

直接内存

Java的NIO库允许Java程序使用直接内存。直接内存是在Java堆外的、直接向系统申请的内存区间。通常,访问直接内存的速度会优于Java堆。因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存。由于直接内存在Java堆外,因此它的大小不会直接受限于Xmx指定的最大堆大小,但是系统内存是有限的,Java 堆和直接内存的总和依然受限于操作系统能给出的最大内存。

垃圾回收系统

是Java虛拟机的重要组成部分,垃圾回收器可以对方法区、Java堆和直接内存进行回收。其中,Java 堆是垃圾收集器的工作重点。

java栈 (虚拟机栈 线程栈)

每一个Java虚拟机线程都有一个私有的 Java栈。一个线程的Java栈在线程创建的时候被创建。Java 栈中保存着帧信息,Java 栈中保存着局部变量、方法参数,同时和Java方法的调用、返回密切相关。

本地方法栈和Java栈非常类似,最大的不同在于Java栈用于Java方法的调用,而本地方

法栈则用于本地方法调用。作为对Java虛拟机的重要扩展,Java虚拟机允许Java直接调用本地方法(通常使用C编写)。

PC ( Program Counter)寄存器 程序计数器

PC ( Program Counter)寄存器也是每个线程私有的空间,Java 虚拟机会为每一个 Java线程

创建PC寄存器。在任意时刻,一个Java 线程总是在执行一个方法,这个正在被执行的方法称当前方法。

执行引擎

执行引擎是Java虚拟机的最核心组件之一, 它负责执行虚拟机的字节码。现代虚拟机为了提高执行效率,会使用即时编译技术将方法编译成机器码后再执行。

方法区

JDK1.7被称之为永久区 1.8之后消失变成元空间(Meta space)来进行存储我们的类

代替方法区的Meta space是分配到直接内存当中的

简述JVM内存模型

线程私有的运行时数据区:程序计数器,Java虚拟机栈,本地方法栈。

线程共享的运行时数据区:Java堆,方法区。

简述程序计数器

程序计数器表示当前线程所执行的字节码的行号指示器。

程序计数器不会产生StackOverflowError和OutOfMemoryError。

简述虚拟机栈

Java虚拟机栈用来描述Java方法执行的内存模型,线程创建时就会分配一个栈空间,线程结束后栈空间被回收。

栈中元素用于支持虚拟机进行方法调用,每个方法在执行时都会创建一个栈帧存储方法的局部变量表、操作栈、动态链接和返回地址等消息。

虚拟机栈会产生两类异常:

StackOverflowError:线程请求的栈深度大于虚拟机允许的深度抛出。

OutOfMemoryError:如果 JVM 栈容量可以动态扩展,虚拟机栈占用内存超出抛出。

简述本地方法栈

本地方法栈与虚拟机栈作用相似,不同的是虚拟机栈为虚拟机执行Java方法服务,本地方法栈为本地方法服务。可以将虚拟机栈看作普通的java函数对应的内存模型,本地方法栈看作由native关键词修饰的函数对应的内存模型。

本地方法栈会产生两类异常:

StackOverflowError:线程请求的栈深度大于虚拟机允许的深度抛出。

OutOfMemoryError:如果JVM栈容量可以动态扩展,虚拟机栈占用内存超出抛出。

简述JVM中的堆

堆主要作用是存放对象实例,Java里几乎所有对象实例都在堆上分配内存,堆也是内存管理中最大的一块。Java的垃圾回收主要就是针对堆这一区域进行。可通过-Xms和-Xmx设置堆的最小和最大容量。

堆会抛出OutOfMemoryError异常。

简述方法区

方法区用于存储被虚拟机加载的类信息、常量、静态变量等数据。

JDK6之前使用永久代实现方法区,容易内存溢出。JDK7把放在永久代的字符串常量池、静态变量等移出,JDK8中抛弃永久代、改用在本地内存中实现的元空间来实现方法区,把JDK7中永久代内容移到元空间。

方法区会抛出OutOfMemoryError异常。

简述运行时常量池

运行时常量池存放常量池表,用于存放编译器生成的各种字面量与符号引用。一般除了保存Class文件中描述的符号引用外,还会把符号引用翻译的直接引用也存储在运行时常量池。除此之外,也会存放字符串基本类型。

JDK8之前放在方法区,大小受限于方法区。JDK8将运行时常量池存放在堆中。

简述直接内存

直接内存也称为对外内存,就是把内存对象分配在JVM堆外的内存区域。这部分内存不是虚拟机管理,而是由操作系统来管理。Java通过DriectByteBuffer对其进行操作,避免了在java和Native堆来回复制数据。

以上就是这一篇文章的全部内容,请大家期待下一篇文章。

相关推荐
思麟呀9 小时前
C++11并发编程:call_once一次性执行+atomic原子类型+CAS无锁编程+自旋锁
linux·开发语言·jvm·c++·windows
Fanfanaas12 小时前
C++ 继承
java·开发语言·jvm·c++·学习·算法
周杰伦fans13 小时前
C# 异常继承深度解析:从设计原则到 sealed 关键字的奥秘
java·jvm·c#
小L写Java14 小时前
第三章:Java 内存模型 (JMM) 与运行时数据区
java·jvm
在繁华处17 小时前
Java从零到熟练(十):JVM基础与性能优化
java·jvm·性能优化
go不是csgo1 天前
GORM 上手:一个 main.go 跑通 Go 数据库增删改查
jvm·数据库·golang
KobeSacre2 天前
JVM G1 垃圾回收器
java·开发语言·jvm
右耳朵猫AI2 天前
Java & JVM技术周刊 2026年第20周
java·开发语言·jvm
小张小张爱学习2 天前
JVM高频面试题
java·jvm
Rick19932 天前
jstack和jstat有什么区别?
jvm·cpu飙高