JVM 从入门到实战 --- 01 JVM 基本介绍

什么是 JVM

先来看下百度百科的解释:

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

晦涩难懂有没有,简单理解就是说虚拟机是物理机的软件实现。

Java 的设计理念是 WORA(Write Once Run Anywhere,一次编写到处运行)。编译器将 Java 文件编译为 Java .class 文件,然后将 .class 文件输入到 JVM 中,JVM 执行类文件的加载和执行,最后转变成机器可以识别的机器码进行最终的操作。

为什么要学习 JVM

每个 Java 开发人员都知道字节码经由 JRE(Java 运行时环境)执行。但他们或许不知道 JRE 其实是由 Java 虚拟机(JVM)实现,JVM 分析字节码,解释并执行它。作为开发人员,了解 JVM的 架构是非常重要的,因为它使我们能够编写出更高效的代码。

但是 JVM 在帮我们实现 Write Once Run Anywhere 的同时,有利有弊,因为在这个过程中涉及到了内存管理,尤其是多线程情况下的内存管理问题,所以我们更应该学习 JVM 的知识来帮助自己写出更好的代码。

根据上边对 JVM 的概念介绍我们知道,JVM 的主要作用在于以下两方面,之后我们的介绍也会以此着手。

  • 软件层面的机器码翻译
  • 内存管理

最近也在学习《深入理解 Java 虚拟机》这本书,此处贴个书中的图过来:

image.png

下边就详细介绍一下这张图中的各个组件

运行时数据区

这个区域描述的是 Java 代码运行时的状态,是我们非常关注的一个状态-程序运行状态,因为我们写代码就是为了运行,不运行的状态对我们是没什么吸引力的。说白了 Java 代码不外乎 数据 指令 控制 这三类型语句,所以我们将 JVM 运行时数据区可以划分为如下两大类:

  • 数据
    • 方法区
    • 堆(Heap)
  • 指令
    • 虚拟机栈
    • 本地方法栈
    • 程序计数器

程序计数器

定义:指向当前线程正在执行的字节码指令的地址 也就是行号

注意:我们需要思考一个问题,我的当前线程本身已经在执行了,为什么还要找个寄存器把他的执行行号记录下来呢?

因为我们程序执行的最小单位是线程,而线程在 CPU 上执行的时候是抢占式的,这样的话就存在线程被挂起的情况,例如:有 A B 两个线程,如果 A 线程执行过程被 B 线程抢占了 CPU,则需要把挂起的 A 线程 当前执行到的行号存储下来,等到 A 重新获得 CPU 时间片执行权的时候去程序计数器获得上一次执行的行号以便于继续执行这个程序。

所以,每个线程都有自己的 程序计数器,而且是互不干扰的,属于线程私有区域

  • 如果执行的是一个 Java 方法,计数器记录的是正在执行的虚拟机字节码指令的地址
  • 如果执行的是一个 Native 方法,计数器的值则为空(undefined)

虚拟机栈

定义:存储当前线程运行方法所需要的数据、指令和返回地址,生命周期与线程相同,同样属于线程私有区域

每个 Java 方法在执行的同时都会创建一个栈帧用于存储局部变量、操作数栈、方法出口等信息,

如下所示,这个栈帧会存储的信息包括:

  • 局部变量表

  • 操作数栈

  • 动态链接

  • 出口

  • ... ...

每一个方法从调用直至执行完成的过程,其实真正对应的是一个栈帧在虚拟机栈中入栈到出栈的过程。

其中局部变量表存放了编译器可知的各种基本数据类型、引用对象等。需要注意的是因为局部变量表空间长度只有 32 位,如果是 long 和 double 类型的话会占用 2 个局部变量表空间,其他数据类型只占用 1 个。

注意:局部变量表所需的内存空间在编译期间就会车队分配完成,因为在进入一个方法时,这个方法需要在栈帧中分配多大的局部空间是完全确定的,方法运行期间局部变量大小是不会改变的。

本地方法栈

和虚拟机栈类似,只不过他存储的是当前线程调用的本地方法所需要的数据、指令和返回地址等,本地方法时标识有 Native 关键字的方法,此处就不展开描述了,参考上述虚拟机栈的介绍。

另外,根据《深入理解 Java 虚拟机》这本书的介绍,有些虚拟机(如 Sun HotSpot 虚拟机)直接就把本地方法栈和虚拟机栈合二为一了。

方法区

这块区域属于线程共享群与,主要存储的信息包括已被虚拟机你加载的类信息(类的元信息)、常量、静态变量、JIT(编译器编译后的代码)等数据。

方法区有一块区域我们称之为 运行时常量池,存放编译期生成的各种字面量和符号引用,运行时常量池有一个重要特征是具备动态性,也就是说在运行期间依然可以将新的常量放入池中,我们开发常用的有 String 类的 intern() 方法

堆(Heap)

属于线程共享区域,在虚拟机启动时创建,是虚拟机管理的内存中最大的一块。它的唯一作用就是存放对象实例。

根据虚拟机规范的描述是:所有的对象实例及数组都要在堆上分配。当然随着现在技术的发展优化这个也变得没有那么绝对,后续会进行分享。

这块区域也是垃圾收集器管理的主要区域,现如今流行的垃圾回收器基本都采用的是分代收集算法,所以也就衍生了一些分代方式,

比如对于内存模型的划分,在 JDK1.8 以前的版本基本是这样的:

1552365212876.png
  • 新生代

    • Eden
    • s0
    • s1
  • 老年代

  • 永久代

在 JDK 1.8 以后的版本:

1552365244555.png
  • 新生代

  • 老年代

  • Meta Space

此处小提一下,之所以在 JDK 1.8 以后 有了 Meta Space,其设计的目的在于规避永久代溢出的问题,因为 Meta Space 是可以自动扩容的,就跟 Java 中的集合一样。

以上种种的划分方式,都是为了更好地回收内存或者分配内存,从下一篇开始就开始学习内存分配及垃圾回收相关算法啦!

总结

  • JVM 负责软件层面的机器码翻译,可以把我们写的 .java 文件翻译成机器可以识别的机器码
  • JVM 负责内存管理
  • JVM 的运行时数据区包括方法区、堆、虚拟机栈、本地方法栈和程序计数器
  • JVM 中的方法区和堆区是所有线程共享的,其他区域都是线程独享的
欢迎关注公众号获取资料 一起进步
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • A good teacher can inspire hope, ignite imagination, and ...
    LiveFromHeart阅读 153评论 0 1
  • 1.关于财富 金融里面,在针对个人投资者进行财产配置的建议的时候,一般会把个人的资本分为两部分,一部分是人力资本(...
    profligacy阅读 331评论 0 2
  • 如果说三年能换来什么,初高中可以毕业,学会一种技能,孩子也可能三岁等等,那么我的三年了,嗯,想想是我经历了我经历的...
    张秒秒阅读 230评论 0 1
  • 想起自己曾写过的一句话~ 有些事情时过境迁就不要记起—— 有些人过去了就不要联系,免得自取其辱~ 可是有些话安慰别...
    is罗小爬阅读 99评论 0 0
  • 打卡日期:2018年04月6日 打卡累计天数:33/60 #宣言(你什么都会,只是需要被唤醒!)# �孩子第二个3...
    静雪恋阅读 73评论 0 0