:本文参考自周志明老师的著作《深入理解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. 面试题案例

  • JVM面试题案例

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

深入理解JVM虚拟机读书笔记——运行时数据区相关推荐

  1. Java 虚拟机学习笔记 | 运行时数据区总结

    前言 要想学习好 Java,Java虚拟(JVM)的学习是绕不开的.学习 Java虚拟(JVM)首先就要先了解的就是Java虚拟(JVM)运行时数据区. 在Java语言和虚拟机规范中对运行时数据区进行 ...

  2. 深入理解JVM虚拟机读书笔记——内存模型与线程

    注:本文参考自周志明老师的著作<深入理解Java虚拟机(第3版)>,相关电子书可以关注WX公众号,回复 001 获取. 1. Java内存模型 JMM概述: Java 内存模型指的是 JM ...

  3. JVM(类加载、运行时数据区、堆内存、方法区、本地接口、执行引擎和垃圾回收)java虚拟机(JVM)的超详细知识点

    JVM虚拟机 一.JVM的概述 1.为什么要学习JVM 2.虚拟机 3.JVM的作用 作用 特点 4.JVM的位置 5.JVM的分类 6.各个组成部分的用途 7.Java 代码的执行流程 8.JVM ...

  4. Java #JVM(HotSpot) 运行时数据区 #程序计数器(PC寄存器)#虚拟机栈(栈帧:局部变量表、操作数栈……)#堆……

    目录 JVM中线程的说明 程序计数器(PC寄存器) 虚拟机栈 · 栈帧 ·· 局部变量表 ·· 操作数栈 ·· 动态链接 ·· 方法返回地址 ·· 本地方法栈 堆 · 查看堆的大小 · 堆的默认大小 ...

  5. JVM内存区域(运行时数据区)划分

    前言: 我们每天都在编写Java代码,编译,执行.很多人已经知道Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文 ...

  6. 深入理解JVM虚拟机读书笔记——锁优化

    注:本文参考自周志明老师的著作<深入理解Java虚拟机(第3版)>,相关电子书可以关注WX公众号:兴趣使然的草帽路飞,回复 001 获取. 1. Java语言中的线程安全 按照线程安全的& ...

  7. 深入理解JVM虚拟机读书笔记【第十二章】Java内存模型与线程

    12.1 概述 12.2 硬件的效率与一致性 12.3 Java内存模型 12.3.1 主内存与工作内存 12.3.2 内存间交互操作 12.3.3 对于volatile型变量的特殊规则 12.3.4 ...

  8. JVM学习笔记之-运行时数据区概述及线程概述,程序计数器(PC寄存器),虚拟机栈(栈,局部变量表,操作数栈,动态连接,方法调用,方法返回地址等),本地方法接口,本地方法栈

    运行时数据区概述及线程概述 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行.JVM内存布局规定了Java在运行过程中内存申请.分配.管理的策略,保证了JV ...

  9. 【JVM】运行时数据区介绍,程序计数器和虚拟机栈详解

    JVM越来越是Java面试中的重头戏,今天来总结一下JVM运行时数据区的相关内容. 文章目录 JVM运行时数据区 JVM运行时数据区内部结构 程序计数器(PC寄存器) 程序计数器的介绍 PC寄存器的实 ...

  10. 【JVM】运行时数据区概述(程序计数器、虚拟机栈、本地方法栈)

    前言 本节主要讲的是运行时数据区,也就是下图这部分,它是在类加载完成后的阶段 当我们通过前面的:类的加载-> 验证 -> 准备 -> 解析 -> 初始化 这几个阶段完成后,就会 ...

最新文章

  1. Entity Framework Core延期及弃用的特性
  2. 【搜索/推荐排序】NCF,DeepCross,Deep Crossing
  3. 常用API2 正则表达式
  4. 反编译工具Reflector ILSpy
  5. 编写一份代码,支持多种布署方式
  6. Google 杀死了 160 个产品!
  7. 练习--第一次课(运算if while 字符编码)
  8. 关于verilog的一些基础知识整理
  9. Yii 2.0 权威指南(7) 关键概念
  10. mysql表格字放大_删除MySQL表中内容,表大小反而变大了
  11. cisco 3750G 冗余备份
  12. CentOS安装NTFS-3G读写Windows 10的移动NTFS磁盘
  13. 网易音乐网站系统|前后端分离springboot+vue实现在线音乐网站
  14. Git 学习笔记:6 GitHub
  15. 速看!!带你揭秘3D建模行业内幕!!
  16. git remote add origin xxx.git 的问题解决
  17. 电影《可可西里》散记
  18. 从匿名聊聊被封停,看微信小程序坚持的线下策略
  19. Pyecharts 静态图片输出ppt中动态图表
  20. 晶振频率,时钟频率,时钟周期,时钟节拍,机器周期,指令周期的概念解析

热门文章

  1. 刷吉米多维奇系列小结(一)
  2. BackTrack 4 新功能
  3. 计算机操作系统(第四版)课后习题答案(完整版)[转载]
  4. 突破网吧及机房管理限制的方法(转)
  5. 数据挖掘方面的论文指导(转)
  6. native2ascii转译HTML字符,native2ascii转字符
  7. java scjp考试_通过Java认证 SCJP 考试之精辟总结
  8. 热血江湖游戏窗口化的方法
  9. 小白都懂的Python爬虫之网易云音乐下载
  10. CentOs7 安装Hadoop-3.1.0集群环境