JVM 学习记录

一、Java

1.1 Java 技术体系包含什么?

Java 技术体系包含Java 程序设计语言Java 虚拟机Class 文件格式Java API 类库

image.png

  • Java 程序设计语言:也就是 Java 语言,包括各种定义、规范等;
  • Java 虚拟机:各种硬件平台上的虚拟机;
  • Class 文件格式:简单的说就是把 Java 代码转换为二进制、格式为 .class 的文件,方便在各个平台被虚拟机读取;
  • Java API 类库:Java 提供的 API,方便开发者日常使用。比如日历 Calendar,数学计算 Math 等;
  • 来自商业机构和开源社区的第三方 Java 类库:也就是第三方库。
1.2 什么是 JDK?

JDK 是 Java Development Kit(Java开发工具)的简称,也就是说要开发 Java 程序,需要的一些组件。

  • Java 语言;
  • Java 虚拟机;
  • Java API。

我们安装 JDK 的时候,一般都包含上述内容。

1.3 什么是 JRE?

Java Runtime Environment(Java运行环境)的简称,也就是说要跑 Java 代码,需要哪些什么样的运行环境支持。

  • 用户界面工具集:
  • 各种 API 库;
  • Java 虚拟机。

JRE 被包含于 JDK 中,我们可以只选择安装 JRE 用来跑 Java 而不是用来开发。

二、JVM

2.1 什么是 JVM?
定义:

Java 虚拟机是一种抽象化的计算机,在实际上的计算机模拟各种计算机功能来实现。

正是因为模拟了一台计算机,所以可以方便地在其它计算机环境下运行。
就比如市面上的 GBA、NES 游戏模拟器,模拟了游戏运行环境,可以在手机、电脑等设备上运行,实现执行游戏文件的功能。Java 也是类似的过程实现了跨平台运行。

JVM 数据类型

2.2 JVM 支持的数据类型

JVM 操作的数据类型也可以分为两类:

  • 原始类型:类似 int、short、byte、long。存在原始值,运行时可以利用虚拟机字节码进行数据操作。
  • 引用类型:存在引用值,用于变量赋值、参数传递、方法返回和运算操作。JVM 使用 reference 类型来表示对象的引用,可以指向实例或者数组。

JVM 希望尽可能多的在编译期完成类型检查,这样在运行期就无需动态确认类型了。

原始类型:
类型 位数 默认值 取值范围
byte 8位有符号 0 -128(-2^7)~ 127(2^7-1)
short 16位有符号 0 -32768(-2^15)~ 32767(2^15 - 1)
int 32位有符号 0 -2,147,483,648(-2^31)~ 2,147,483,647(2^31 - 1)
long 64位有符号 0 -9,223,372,036,854,775,808(-2^63)~ 9,223,372,036,854,775,807(2^63 -1)
char 16位无符号 Unicode 的 null ('\u0000') \u0000 ~ \uffff
float 单精度、32位 0 -
double 双精度、64位 0 -
boolean Oracle公司的虚拟机编码为 byte 数组,每个 boolean 占 8 位 0-false 1-true -
引用类型:

JVM 引用类型包含三种:

  • 类类型:指向类实例;
  • 数组类型:指向数组实例;
  • 接口类型:实现某个接口的类或数组实例。
2.3 JVM 运行时数据区域

虚拟机运行的时候会把内存划分为若干个不同的区域

image.png

1. 程序计数器(pc寄存器)
定义:

程序计数器又称 pc(program counter) 寄存器,用来储存下一条指令执行的地址。

作用:
  • 是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令;
  • 如果线程执行的 Java 方法,记录的是正在执行的虚拟机字节码指令的地址,如果是 Native 方法,计数器值为空(Undefined)。
特点:
  • 很小的内存区域;
  • 线程私有:每一条线程都会有自己的 pc寄存器,因为 cpu 可能会随时切换执行的任务,所以有必要给每条线程创建 pc寄存器 以确认下面该执行什么任务;
  • 唯一一个没有定义 OutOfMemoryError 的区域;
  • 跟随线程的生命周期。
2. Java 虚拟机栈

Java 虚拟机栈是Java方法运行过程的内存模型。

作用:
  • JVM 在每一个方法执行的同时创建 “栈帧”,这块区域包含 局部变量表、操作数栈、动态链接、方法出口等信息;
  • 当方法运行时需要创建局部变量时,就将局部变量的值存入栈帧的局部变量表中,当这个方法执行完毕后,这个方法所对应的栈帧将会出栈,并释放内存空间。
特点:
  • 线程私有:每个线程执行的方法可能不一样,所以需要分别创建;
  • 由一个个栈帧组成,栈帧包含方法出口信息,会在方法结束后该栈帧移出,释放内存;
  • 异常 StackOverflowError:如果栈帧数量超过虚拟机支持的最大容量,抛出这个异常;
  • 异常 OutOfMemoryError:动态扩展时,无法申请到足够内存,就会抛出此异常。

人们常说,Java的内存空间分为“栈”和“堆”,栈中存放局部变量,堆中存放对象。
这句话不完全正确!这里的“堆”可以这么理解,但这里的“栈”只代表了Java虚拟机栈中的局部变量表部分。真正的Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。

本地方法栈:

主要用于为 Native 方法服务,与 Java 虚拟机栈的实现类似,也是可以创建一个个栈帧、也会抛出 StackOverflowError 和 OutOfMemoryError 异常。

3. JVM 方法区
image.png
作用:
  • 方法区用来存储已被 JVM 加载的类信息、常量、静态变量、即时编译后的代码等数据。
方法区主要包含内容:
  • 类型信息:
    • 类以及其超类的全限定名,也就是类的 包名+名字。比如 在 Class 文件中是 java/lang/Thread
    • 直接超接口的全限定名;
    • 类型标志:是类还是接口等;
    • 类访问权限符:public、private、default、abstract、final、static。
  • 类型的常量池:Class 文件中除了有类的信息,还有一项是常量池(Constant Pool Table),用于存放编译期生成的常量和符号引用。运行时会被加载进运行时常量池,使用时会把符号引用解析为直接引用;

符号引用:字面上的一个引用,作为标识用。因为编译期无法获取到该类的实际地址,只能用符号来表示地址。

  • 字段信息:修饰符(public、protect、private、default)、字段的类型、字段名称;

  • 方法信息:也就是这些类的所有方法包含的信息

    • 方法的返回值,包含 void;
    • 方法参数的类型、数目以及顺序;
    • 方法的修饰符(public、protect、private、default)
    • 方法字节码:
    • 方法中局部变量区的大小、方法栈帧
    • 异常表
  • 类变量(静态变量):

  • ClassLoader 的引用:用于加载动态链接

  • 指向该 Class 实例的引用:通过Class.forName(StringclassName)来查找获得该实例的引用,然后创建该类的对象。

  • 方法表:为了提高访问效率,JVM 可能会创建一个数组来存放非抽象类方法的直接引用。

特点:
  • 线程共享;
  • 永久代:存放的内容生命周期较长;
  • 内存回收效率低;
  • 虚拟机对其实现要求较松:允许固定大小,也允许可扩展的大小,还允许不实现垃圾回收。
运行时常量池:

方法区中存放三种数据:类信息、常量、静态变量、即时编译器编译后的代码。其中常量存储在运行时常量池中。

作用:
  • 用于存放编译期生成的各种字面常量(public static final 声明的常量)和符号引用:
  • 运行时也可以创建常量并放入常量池中,比如 String 的 intern() 方法。
特点:
  • 具备动态性;
  • 会 OOM;
4. 堆

用来存放对象的空间。

作用:
  • 基本所有的对象都储存在堆中。
特点:
  • 线程共享;
  • 在虚拟机启动时创建;
  • 垃圾回收的主要场所;
  • 新生代、老年代:不同的区域存放具有不同生命周期的对象,便于回收;
  • 堆的大小既可以固定也可以扩展:当内存不足时,OOM。
5. 直接内存

直接内存是除Java虚拟机之外的内存,但也有可能被Java使用。

在NIO中引入了一种基于通道和缓冲的IO方式。它可以通过调用本地方法直接分配Java虚拟机之外的内存,然后通过一个存储在Java堆中的DirectByteBuffer对象直接操作该内存,而无需先将外面内存中的数据复制到堆中再操作,从而提升了数据操作的效率。

直接内存的大小不受Java虚拟机控制,但既然是内存,当内存不足时就会抛出OOM异常。

参考资料:

https://blog.csdn.net/dc2222333/article/details/82940649
https://blog.csdn.net/zero__007/article/details/100061611
https://blog.csdn.net/qq_41701956/article/details/81664921

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342