专栏首页一猿小讲程序员进阶系列:多图教你掌握JVM

程序员进阶系列:多图教你掌握JVM

提及 JVM 这个词,估计大家都能简单说两句,但是根据身边朋友以及诸多粉丝提出的疑问,能系统讲出来 JVM 的却真心很少。

网上讲解 JVM 这块的文章非常多,不过鱼龙混杂,鉴于 JVM 也是最考验 Java 程序员的基础功底啦,今天静下来,一起画画图,一起梳理梳理,好好填补一下这块,争取无论走到哪里,大家在脑海中都能有行走的 JVM 内存模型图。

1

JVM 初识

在讲解 JVM 之前,先来揭秘一下 Java 程序是如何实现一次编译到处运行的?

步骤一:用文本编辑器或者 IDE,快速编写 HelloWorld.java 的源代码文件; 步骤二:用 Java 编译器(javac)把源代码(*.java)编译成字节码文件(*.class); 步骤三:字节码文件(.class)便可以在任何安装了 JVM 的操作系统中运行,JVM 会将字节码翻译成可以被机器执行的本地机器码。

那么重点来了,Java 是如何实现一次编译到处运行的呢?通过上图应该很清晰找到解。

解一:Java 一次编译,到处运行,跨平台的特性是通过 JVM 来实现的,通过 JVM 来屏蔽底层操作系统的差异; 解二:Java 通过 JVM 来实现跨平台,但是 JVM 是不跨平台的,也就是说不同操作系统之上的 JVM 是不同的,Linux 系统上的 JVM 不能用在 Windows 系统上。

2

JVM 窥探

既然已经知晓 Java 程序可以通过 JVM 来实现一次编译,到处运行的跨平台特性,那么 JVM 到底是什么呢?

JVM 是 Java Virtual Machine(Java虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的 —— 百度百科。

上面是引了一段百度百科对 JVM 的解释,大意就是 Java 虚拟机是在计算机上虚构出来的一个计算机,既然是虚构的就意味着看不到,只在于内存之中。

(图片来源于网络)

如上图所示,计算机主要有运算器、控制器、内外存储器、输入和输出设备组成,那么 JVM 结构长啥样子呢?

还是以开篇的 HelloWorld 为例,窥探一下 JVM 的运行流程。

1. Java 源代码文件会被 Java 编译器编译为字节码文件(.class); 2. JVM 中的类加载器进行加载各个类的字节码文件,将所有类结构和方法变量放入运行时数据区; 3. 字节码文件加载完毕之后,交给 JVM 执行引擎进行执行。

JVM = 类加载器 ClassLoader + 执行引擎 Execution Engine + 运行时数据区域 Runtime Data Area。

在程序执行过程中,会分配内存空间来存储程序执行期间需要用到的数据相关信息,分配的内存空间被称作为 Runtime Data Area(运行时数据区),也就是常说的 JVM 内存,接下来就重点说一说 JVM 运行时数据区。

(JDK 1.7 内存模型)

如上图所示,JVM 运行时数据区主要分为程序计数器、虚拟机栈、本地方法栈、方法区、堆。

如上图所示,按照内存共享来划分 JVM 内存,主要划分为线程共享内存区域(堆、方法区)、线程私有内存区域(程序计数器、虚拟机栈、本地方法栈)、直接内存。

3

JVM 运行时数据区解剖

从上面介绍,可以清晰知道 JVM 运行时数据区,主要分为程序计数器、虚拟机栈、本地方法栈、方法区、堆。接下来就逐步解剖,简单了解一下。

1. 程序计数器

程序计数器(PC Register),也有人称它为 PC 寄存器。

主要是为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器。

2. 虚拟机栈

虚拟机栈(VM Stack),也有人称它为 Java 虚拟机栈、栈或者 JVM 栈,这块就是大家经常分析一段程序执行时要关注的区域。

JVM 栈是每个线程私有的,线程创建的同时都会创建对应的 JVM 栈。

JVM 栈中存放的是当前线程中局部基本类型的变量、返回结果以及 Stack Frame,而非基本类型的对象在 JVM 栈上仅存放一个指向堆上的地址。

3. 本地方法栈

本地方法栈(Native Method Stack)与 JVM 栈很相似,本地方法栈也是每个线程私有的,只不过是服务的对象不同,JVM 栈是为执行 Java 方法服务,而本地方法栈则是为执行本地方法(Native Method)服务。

4. 方法区

方法区(Method Area),也有人称它为永久代,是线程共享的区域。

在方法区中,主要存放静态变量、常量、类信息、运行时常量池以及所有的方法的信息。运行时常量池(Runtime Constant Pool)是方法区的重要一部分,用于存储编译器生成的常量和引用。

(JDK 1.8 内存模型)

如上图所示,值得注意的是 JDK 1.8 相比 JDK 1.7,JVM 运行时数据区划分中的方法区(持久代)从 JVM 运行时数据区拿掉了,而在本地内存加入了元数据区(Metadata Memory),简而言之在 JDK 1.8 中,元数据区替代了方法区(持久代)。

5. 堆

堆(Heap),所有 new 出来的对象实例都存储在该区域,这块区域也是线程共享的,也是分析 Java 程序时关注较多的一块。

6. 其它

直接内存(Direct Memory),有时也称作堆外内存,是不受 JVM控制的内存。

在 JDK 1.4 中加入了 NIO,引入了一种基于通道(Channel)与缓冲区(Buffer)的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆里面的DirectByteBuffer 对象作为这块内存的引用进行操作。 避免了在 Java 堆和 Native 堆中来回复制数据,能在一些场景中显著提高性能。

4

寄语写最后

本次,主要让大家了解一下 JVM 的内存结构,希望通过本次分享,大家对 JVM 能有个梗概的认识,想要彻底掌握还需针对性的弥补,说句心里话,希望能够把这些图都记在脑子里,只要做到脑中有图,心就不慌。

好了,本次就谈到这里,一起聊技术、谈业务、喷架构,少走弯路,不踩大坑。会持续输出原创精彩分享,敬请期待!

本文分享自微信公众号 - 一猿小讲(yiyuanxiaojiangV5),作者:一猿小讲

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 硬核!万字长文!Java零基础入门到精通知识点汇总

    其实学习 Java 学到什么程度算是精通,这个其实没有盖棺定论的,也不是说你拿个年薪几十万的 offer 就可以自诩精通了。

    牛仔码农
  • Java程序员必看书籍推荐

    不管你是转行来学习Java编程,还是你本来就是计算机专业并且继续在这一领域深耕的。除了,大学专业课程的学习以及工作中的实践之外;业余时间的充电,成了技术人员提升...

    刘文正
  • Java后端学习路线图,你真的只需要这一张!

    学习路线图往往是学习一样技术的入门指南。网上搜到的Java学习路线图也是一抓一大把。

    黄小斜学Java
  • Java教程到处都是,究竟怎样能学好Java课程?

    Java如今已经是全球编程语言排名第一的语言,运用广泛,前景广阔,而且很多软件的开发都离不开Java,而在以Java为核心的开发领域中,JavaEE程序员的需求...

    企鹅号小编
  • 超硬核Java学习路线图+学习资源+实战项目汇总,看完以后不用再问我怎么学Java了!

    于是这次黄小斜决定来一波狠的,把所有这些内容都整理起来,做成一份非常硬核的Java学习指南+路线图,一篇文章搞定Java学习,360度无死角(可能)如果你们喜欢...

    黄小斜学Java
  • ​ 之前写过很多次关于Java学习指南、Java技术路线图的文章。

    之前写过很多次关于Java学习指南、Java技术路线图的文章。但是总还是有小伙伴来问我,Java怎么学,项目怎么做,资源怎么找,真是让人头秃。

    黄小斜学Java
  • 你离架构师还有多远?

      软件架构师在整个软件开发过程中都起着重要的作用,并随着开发进程的推进而其职责或关注点不断地变化,总结下面几点。   在需求阶段,软件架构师主要负责理解和管...

    欢醉
  • 还未成为优秀的安卓工程师,是差在时代还是败在机遇?看了这份进阶指南后,我茅塞顿开

    移动研发火热不停,越来越多人开始学习Android开发。但很多人感觉入门容易成长很难,对未来比较迷茫,不知道自己技能该怎么提升,到达下一阶段需要补充哪些内容。市...

    Android技术干货分享
  • 2019 最新 Java 核心技术教程,都在这了!

    以下是Java技术栈微信公众号发布的所有关于 Java 的技术干货,会从以下几个方面汇总,本文会长期更新。

    Java技术栈
  • Java教程到处都是,究竟怎样能学好Java课程?

    Java如今已经是全球编程语言排名第一的语言,运用广泛,前景广阔,而且很多软件的开发都离不开Java,而在以Java为核心的开发领域中,JavaEE程序员的需求...

    企鹅号小编
  • C 语言与 C++ 学习路线

    诸如Windows平台VC系列:VC++6.0(比较古老) ;Visual Studio2013, Visual Studio 2015,Visual Stud...

    C语言与CPP编程
  • Java学习之路 -- Java怎么学?

    当时,作为懵懂的小白,大一学习了c和c++,还有数据结构,后来才自学的java。有了c++的基础,其实学java确实感觉挺容易上手。如果没有c或者c++的基础,...

    秦怀杂货店
  • 这有一份廖雪峰大牛的Java高级架构师教程,请查收!

    已经工作3年了,每个项目都会保质保量的完成,薪资却依旧不如意,多次提出加薪,领导总说哦哦哦知道了。 不止一次想象自己用Mac电脑和Cherry键盘撸代码的兴奋场...

    JAVA高级架构开发
  • JVM入门指南

    JVM简介: JVM是Java Virtual Machine的缩写,中文翻译为Java虚拟机,是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际...

    CSDN技术头条
  • JVM(一)史上最佳入门指南

    提到Java虚拟机(JVM),可能大部分人的第一印象是“难”,但当让我们真正走入“JVM世界”的时候,会发现其实问题并不像我们想象中的那么复杂。唯一真正令我们恐...

    Java中文社群-磊哥
  • Java程序员修炼之路

    大多数人选择Java可能只是因为听说Java前景好、Java比较好找工作、Java语言在TIOBE排行榜上一直位于前三等等之类的原因,但是Java具体好在哪里,...

    Java团长
  • 想要快速进阶Java架构师?这份超强(长)学习计划单 请签收!

    而Java程序员一向比别人更难,如果说大家都在修仙的话,java程序员简直神似“剑修”,入行枯燥精通难,要想变得强大,需要能力也需要运气,更需要持之以恒。

    秃顶的Java程序员
  • 转:成为Java高级程序员需要掌握哪些?

    1、Core Java,就是Java基础、JDK的类库,很多童鞋都会说,JDK我懂,但是懂还不足够,知其然还要知其所以然,JDK的源代码写的非常好,要经常查看,...

    技术zhai
  • 成为java高级程序员需要掌握哪些

    精讲java

扫码关注云+社区

领取腾讯云代金券