深入理解jvm虚拟机读书笔记——运行时数据区(代码片段)

兴趣使然的草帽路飞 兴趣使然的草帽路飞     2022-12-07     626

关键词:

:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复 001 获取。

跨平台性是 Java 语言的重要特性,而这一特性本质上就是通过 JVM 虚拟机来实现的。下面就来通过深入学习 JVM 来进一步增加我们对 Java 这门编程语言的了解吧!(个人建议,最好能买来这本书去读一读,是非常有帮助的,当然,在看这本书之前,为了方便理解相关概念名词,可以先跟着某马程序员的视频课程大致过一遍 JVM 的内容体系:JVM 虚拟机基础入门视频教程视频教程的全套笔记

1. 运行时数据区

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里 面的人却想出来 —— 摘自(深入理解 Java 虚拟)。

Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域 有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。根据《Java虚拟机规范》的规定,Java虚拟机所管理的内存 将会包括以下几个运行时数据区域,如下图所示。

下面我们来逐个学习一下运行时数据区的 5 个部分。(注意:JVM 运行时数据区可不能等同于 JVM 内存模型,对于不太熟悉 JVM 的初学者,面试的时候很容易把这两个概念搞混~)

1.1 程序计数器

程序计数器(线程私有),是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。它的核心作用就是:用于存储下一条所要执行的 JVM 指令的内存地址。

这里所说的线程私有,即不会出现并发安全问题,JVM 运行时数据区的 5 个部分中,只有 Java 堆、方法区是线程共享的,其他三个均为线程私有,后面还会提到这个知识点。

如下图:

Java指令执行流程:

  • 每一条二进制字节码(JVM指令) 通过 解释器 转换成 机器码 然后 就可以被 CPU 执行了!
  • 解释器 将一条jvm 指令转换成 机器码后 其会 向程序计数器 递交 下一条 jvm 指令的执行地址
  • 程序计数器在硬件层面 其实是通过 寄存器 实现的!
  • 所以程序计数器的作用就是:用于保存JVM中下一条所要执行的指令的地址!

1.2 虚拟机栈

与程序计数器一样,虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是J ava 方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame),栈帧包含如下几个组成部分:

  • 局部变量表:存放基本数据类型(boolean、byte、char、short、int、 float、long、double)、对象引用(reference)等。这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)来表示,其中64位长度的 longdouble 类型的数据会占用两个变量槽,其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小(这里说的“大小”是指变量槽的数量)。
  • 操作数栈:也可以称之为表达式栈(Expression Stack),在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈(push)和 出栈(pop)。某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈,使用它们后再把结果压入栈,比如:执行复制、交换、求和等操作。操作数栈,主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间

  • 动态连接
  • 方法出口等信息

每个线程运行需要的内存空间,这一空间被称为虚拟机栈(Frames),每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

每个栈由多个栈帧(Frame) 组成,对应着每个方法运行时所占用的内存,每个线程只能有一个活动栈帧,对应着当前正在执行的方法,当方法执行时压入栈,方法执行完毕后弹出栈。

如下图:

1.3 本地方法栈

一些带有native 关键字的方法就是需要JAVA去调用本地的C或者C++方法,因为JAVA有时候没法直接和操作系统底层交互,所以需要用到本地方法!

如图:

1.4 堆

是Java内存区域中一块用来存放对象实例的区域【几乎所有的对象实例都在这里分配内存】,Java 堆(Java Heap)是 Java 虚拟机所管理的内存中最大的一块 Java 堆是被所有线程共享的一块内存区域。

Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过参数-Xmx-Xms设定)。如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

  • 内存中的对象都需要考虑线程安全问题
  • Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC 堆”(Garbage)。
  • -Xmx -Xms:JVM初始分配的堆内存由-Xms指定,64位的操作系统上,堆大小默认是物理内存的1/64

1.5 方法区

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

方法区只是一个抽象概念,其具体实现是通过以下 2 种方式:

  • 永久代:JDK1.7版本之前。
  • 元空间:JDK1.8版本之后。

永久代如下图所示:

元空间如下图所示:

由上图可以看出,1.6版本方法区是由PermGen永久代实现(使用堆内存的一部分作为方法区),且由JVM 管理,由Class ClassLoader 常量池(包括StringTable) 组成。

1.8 版本后,方法区交给本地内存管理,而脱离了JVM,由元空间实现(元空间不再使用堆的内存,而是使用本地内存,即操作系统的内存),由Class ClassLoader 常量池(StringTable 被移到了Heap 堆中管理) 组成。

2. 面试题案例

后续会陆续更新,这本书的笔记记的差不多了,排版和格式需要花时间整理,文章都会同步到公众号上,也欢迎大家通过公众号加入我的交流qun互相讨论jvm这块的知识内容!

深入理解jvm虚拟机读书笔记——运行时栈帧结构(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。Java虚拟机以方法作为最基本的执行单元,“栈帧”(StackFrame)则是用于支持虚拟... 查看详情

深入理解jvm虚拟机读书笔记——运行时栈帧结构(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。Java虚拟机以方法作为最基本的执行单元,“栈帧”(StackFrame)则是用于支持虚拟... 查看详情

深入理解jvm虚拟机读书笔记——内存模型与线程(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。1.Java内存模型JMM概述:Java内存模型指的是JMM,而不是运行时数据区哦~Java语言为了保证... 查看详情

深入理解jvm虚拟机读书笔记——内存模型与线程(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。1.Java内存模型JMM概述:Java内存模型指的是JMM,而不是运行时数据区哦~Java语言为了保证... 查看详情

java内存区域——深入理解jvm读书笔记

本内容由《深入理解java虚拟机》的部分读书笔记整理而成,本读者计划连载。通过如下图和文字介绍来了解几个运行时数据区的概念。方法区:它是各个线程共享的区域,用于内存已被VM加载的类信息、常量、静态变量、即时编... 查看详情

《深入理解jvm虚拟机》读书笔记

前言:《深入理解JVM虚拟机》是JAVA的经典著作之一,因为内容更偏向底层,比较枯燥难啃,所以之前一直没有好好的阅读过。最近因为刚好有空,又有了新目标。所以打算和《构架师的12项修炼》一起看,这样荤素搭配,吃饭不... 查看详情

jvm运行时数据区域(读书笔记)

最近在看《深入理解java虚拟机》这本是书算是国内写的比较好的讲述jvm原理的是书籍,看完后自己做下读书笔记增加印象。java虚拟机运行是区域主要分为五个程序计数器虚拟机栈本地方法栈堆方法区1.程序计数器程序计数器是... 查看详情

深入理解jvm读书笔记三:虚拟机类加载机制

Java虚拟机类加载机制是把Class类文件加载到内存,并对Class文件中的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程。7.1概述与那些在编译时需要进行链接工作的语言不同,在Java语言里面,... 查看详情

深入理解java虚拟机读书笔记三

深入理解Java虚拟机第三章内存管理读书笔记垃圾回收需要解决的三个问题是:哪些内存需要回收何时回收如何回收哪些内存需要回收对于Java内存运行时区域,程序计数器\虚拟机栈\本地方法栈三个部分是线程私有的,随线程而生,随... 查看详情

深入理解jvm虚拟机:jvm运行时数据区

概述:JVM将内存的管理进行封装,使得开发人员不必关心内存申请、释放操作。但是在高级程序开发、复杂业务场景开发的时候,如果出现内存溢出的情况,对于开发人员而言就很难去分析出原因。所以还是很有必要去了解一下... 查看详情

深入理解jvm虚拟机读书笔记——类的加载机制(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化&#... 查看详情

深入理解jvm虚拟机读书笔记——类的加载机制(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化&#... 查看详情

深入理解java虚拟机读书笔记---运行时数据区域

运行时数据区域1.程序计数器   程序计数器(ProgramCounterRegister)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行... 查看详情

深入理解jvm虚拟机读书笔记——锁优化(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号:兴趣使然的草帽路飞,回复001获取。1.Java语言中的线程安全按照线程安全的“安全程度”由强至弱来排... 查看详情

深入理解jvm虚拟机读书笔记——锁优化(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号:兴趣使然的草帽路飞,回复001获取。1.Java语言中的线程安全按照线程安全的“安全程度”由强至弱来排... 查看详情

深入理解jvm虚拟机读书笔记——对象的创建与内存布局(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》1.对象的创建过程在Java语言层面,创建对象一般是借助new关键字去实现:Useruser=newUser();而在虚拟机中,对象的创建过程如下:当Jav... 查看详情

深入理解jvm虚拟机读书笔记——垃圾回收器(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。如果说收集算法是内存回收的方法论,那垃圾收集器就是内存回收的实践者。《Java虚拟机... 查看详情

深入理解jvm虚拟机读书笔记——垃圾回收器(代码片段)

注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复001获取。如果说收集算法是内存回收的方法论,那垃圾收集器就是内存回收的实践者。《Java虚拟机... 查看详情