
JVM内存模型
文章平均质量分 62
本资料参考:
尚硅谷Java宋红康
缘起->猿灭
一名小开发
展开
-
18.10 字节码指令集与解析举例 - 同步控制指令
组成java虚拟机支持两种同步结构:方法级的同步和方法内部一段指令序列的同步,这两种同步都是使用monitor来支持的。方法级的同步:是隐式的,即无须通过字节码指令来控制,它实现在方法调用和返回操作之中。虚拟机可以从方法常量池的方法表结构中的ACC_ SYNCHRONIZED 访问标志得知一个方法是否声明为同步方法;当调用方法时,调用指令将会检查方法的ACC_ SYNCHRONIZED访问标志是否设置。注意:一个方法无论是否添加synchronized,你都无法在字节码中看出区别,例如:是否是同步方法在字原创 2022-12-07 23:50:22 · 348 阅读 · 1 评论 -
18.9 字节码指令集与解析举例 - 异常处理指令
注意:如果使用throw new 异常名称()这种形式来抛出异常,那就会在代码中出现athrow指令,而在方法上面添加throw 异常名称这种形式来抛出异常,然后使用jclasslib的时候就会出现在方法下面多出现一个属性Exceptions,如下图所示:处理异常:在Java虚拟机中,处理异常(catch语句)不是由字节码指令来实现的(早期使用jsr、ret指令),而是采用异常表来完成的。异常表如果一个方法定义了一个try-catch或者try-finally的异常处理,就会创建一个异常表。 它包含了每原创 2022-12-07 23:49:17 · 164 阅读 · 0 评论 -
18.8 字节码指令集与解析举例 - 控制转义指令
程序流程离不开条件控制,为了支持条件跳转,虚拟机提供了大量字节码指令,大体上可以分为1)比较指令、2)条件跳转指令、3)比较条件跳转指令、4)多条件分支跳转指令、5)无条件跳转指令等。该内容在 【算术指令】 中介绍条件跳转指令通常和比较指令结合使用。在条件跳转指令执行前,一般可以先用比较指令进行栈顶元素的准备,然后进行条件跳转。条件跳转指令有:ifeq,iflt,ifle,ifne,ifgt,ifge,ifnull,ifnonnull。这些指令都接收两个字节的操作数,用于计算跳转的位置(16位符号整数作原创 2022-12-07 23:48:17 · 198 阅读 · 0 评论 -
18.7 字节码指令集与解析举例 - 操作数栈管理指令
如同操作一个普通数据结构中的堆栈那样,JVM提供的操作数栈管理指令,可以用于直接操作操作数栈的指令。这类指令包括如下内容:将一个或两个元素从栈顶弹出,并且直接废弃:pop,pop2;复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶:dup, dup2,dup_x1,dup2_x1,dup_x2, dup2_×2;将栈最顶端的两个Slot数值位置交换:swap。Java虚拟机没有提供交换两个64位数据类型(long、double)数值的指令。指令nop,是一个非常特殊的指令,它的字节码为0x00。和原创 2022-12-07 23:46:46 · 116 阅读 · 0 评论 -
18.6 字节码指令集与解析举例 - 方法调用与返回指令
以下5条指令用于方法调用:注意:方法调用结束前,需要进行返回。方法返回指令是根据返回值的类型区分的。举例:通过ireturn指令,将当前函数操作数栈的顶层元素弹出,并将这个元素压入调用者函数的操作数栈中(因为调用者非常关心函数的返回值),所有在当前函数操作数栈中的其他元素都会被丢弃。如果当前返回的是synchronized方法,那么还会执行一个隐含的monitorexit指令,退出临界区。最后,会丢弃当前方法的整个帧,恢复调用者的帧,并将控制权转交给调用者。对应的代码:原创 2022-12-07 23:46:15 · 96 阅读 · 0 评论 -
18.5 字节码指令集与解析举例 - 对象的创建与访问指令
Java是面向对象的程序设计语言,虚拟机平台从字节码层面就对面向对象做了深层次的支持。有一系列指令专门用于对象操作,可进一步细分为创建指令、字段访问指令、数组操作指令、类型检查指令。虽然类实例和数组都是对象,但Java虚 拟机对类实例和数组的创建与操作使用了不同的字节码指令:创建类实例的指令:创建数组的指令:上述创建指令可以用于创建对象或者数组,由于对象和数组在Java中的广泛使用,这些指令的使用频率也非常高。对象创建后,就可以通过对象访问指令获取对象实例或数组实例中的字段或者数组元素。举例:以getst原创 2022-12-07 23:45:45 · 135 阅读 · 0 评论 -
18.4 字节码指令集与解析举例 - 类型转换指令
转换规则:Java虚拟机直接支持以下数值的宽化类型转换(widening numeric conversion, 小范围类型向大范围类型的安全转换)。也就是说,并不需要指令执行,包括:从int类型到1ong、float或者double类型。对应的指令为:i2l、 i2f、i2d从long类型到float、double类型。对应的指令为:l2f、l2d从float类型到double类型。对应的指令为:f2d简化为:int --> long --> float --> double精度损失问题尽管宽化类型转换原创 2022-12-07 23:44:34 · 97 阅读 · 0 评论 -
18.3 字节码指令集与解析举例 - 算数指令
作用:算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新压入操作数栈。分类:大体上算术指令可以分为两种:对整型数据进行运算的指令与对浮点类型数据进行运算的指令。byte、short、char 和boolean类型说明在每一大类中,都有针对Java虚拟机具体数据类型的专用算术指令。但没有直接支持byte、short、 char和boolean类型的算术指令,对于这些数据的运算,都使用int类型的指令来处理。此外,在处理boolean、byte、 short和char类型的数组时,也会转换为使原创 2022-12-07 23:43:30 · 186 阅读 · 0 评论 -
18.2 字节码指令集与解析举例 - 加载与存储指令
加载和存储指令用于将数据从栈帧的局部变量表和操作数栈之间来回传递。上面所列举的指令助记符中,有一部分是以尖括号结尾的(例如iload_)。这些指令助记符实际上代表了一组指令(例如iload_代表 了iload_0、iload_1、iload_2和iload_3这几个指令)。这几组指令都是某个带有一个操作数的通用指令(例如iload) 的特殊形式,对于这若干组特殊指令来说,它们表面上没有操作数,不需要进行取操作数的动作,但操作数都隐含在指令中。比如:iload_0:将 局部变量表中索引为0位置上的数据压入操原创 2022-12-07 23:39:01 · 130 阅读 · 0 评论 -
18.1 字节码指令集与解析举例 - 概述
如果不考虑异常处理的话,那么Java虚拟机的解释器可以使用下面这个伪代码当做最基本的执行模型来理解字节码与数据类型在Java虚拟机的指令集中,大多数的指令都包含了其操作所对应的数据类型信息。例如,iload指令用于从局部变量表中加载 int 型的数据到操作数栈中,而 fload 指令加载的则是float类型的数据。对于大部分与数据类型相关的字节码指令**,它们的操作码助记符中都有特殊的字符来表明专门为哪种数据类型服务**:也有一些指令的助记符中没有明确地指明操作类型的字母,如 arraylength 指原创 2022-12-07 23:36:52 · 261 阅读 · 0 评论 -
17.4 class文件结构 - 使用javap指令解析Class文件
通过反编译生成的字节码文件,我们可以深入的了解java代码的工作机制。但是,自己分析类文件结构太麻烦了!除了使用第三方的jclasslib工具之外,oracle官方也提供了工具:javap。原创 2022-07-14 13:22:26 · 577 阅读 · 0 评论 -
17.3 class文件结构 - Class文件结构
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html任何一个Class文件都对应着唯一个类或接口的定义信息,但反过来说,Class文件实际上它并不一定以磁盘文件的形式存在。原创 2022-07-14 13:21:18 · 129 阅读 · 0 评论 -
17.2 class文件结构 - 虚拟机的基石:Class文件
源代码经过编译器编译之后便会生成一个字节码文件,字节码是一种二进制的类文件,它的内容是JVM的指令,而不像C、C++经由编译器直接生成机器码。Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的操作码( opcode)以及跟随其后的零至多个代表此操作所需参数的操作数(operand) 所构成。虚拟机中许多指令并不包含操作数,只有一个操作码。...原创 2022-07-14 13:16:42 · 346 阅读 · 0 评论 -
17.1 class文件结构 - 概述
Java虚拟机:跨语言的平台Java虚拟机不和包括Java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联。无论使用何种语言进行软件开发,只要能将源文件编译为正确的Class文件,那么这种语言就可以在Java虚拟机上执行。可以说,统一而强大的Class文件结构,就是Java虚拟机的基石、 桥梁。想要让一个Java程序正确地运行在JVM中, Java源码就必须要被编译为符合JVM规范的字节码。前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符合JVM规范的字节原创 2022-07-14 13:15:24 · 162 阅读 · 0 评论 -
3.2 运行时数据区内部结构 - 线程
线程线程是一个程序里的运行单元。JVM允许一个应用有 多个线程并行的执行。在Hotspot JVM里,每个线程都与操作系统的本地线程直接映射。➢当一个Java线程准备好执行以后,此时一个操作系统的本地线程也同时创建。Java线 程执行终止后,本地线程也会回收。如果当前是最后一个普通线程/非守护线程,JVM虚拟机也会被停掉。操作系统负责所有线程的安排调度到任何一个可用的CPU上。一旦本地线程初始化成功,它就会调用Java线程中的run()方法。如果你使用jconsole或者是任何一个原创 2022-03-10 13:23:02 · 114 阅读 · 0 评论 -
19.6 类的加载过程(类的生命周期)详解 - 过程五:类的Unloading(卸载)
在类加载器的内部实现中,用一个Java集合来存放所加载类的引用。另一方面,一个Class对象总是会引用它的类加载器调用Class对象的getClassLoader()方法,就能获得它的类加载器。由此可见,代表某个类的Class实例与其类的加载器之间为双向关联关系。一个类的实例总是引用代表这个类的Class对象。在Object类中定 义了getClass()方法,这个方法返回代表对象所属类的Class对象的引用。此外,所有的Java类都有一个静态属性class,它引用代表这个类的Class对象。原创 2022-10-02 10:44:38 · 426 阅读 · 0 评论 -
19.5 类的加载过程(类的生命周期)详解 - 过程四:类的Using(使用)
任何一个类型在使用之前都必须经历过完整的加载、链接和初始化3个类加载步骤。一旦一个类型成功经历过这3个步 骤之后,便“万事俱备,只欠东风”,就等着开发者使用了。开发人员可以在程序中访问和调用它的静态类成员信息(比如:静态字段、静态方法),或者使用new关键字为其创建对象实例。原创 2022-10-02 10:43:45 · 140 阅读 · 0 评论 -
19.4 类的加载过程(类的生命周期)详解 - 过程三:Initialization(初始化)阶段
如果前面的步骤都没有问题,那么表示类可以顺利装载到系统中。此时,类才会开始执行Java字节码。原创 2022-10-02 10:43:07 · 488 阅读 · 0 评论 -
19.3 类的加载过程(类的生命周期)详解 - 过程二:Linking(链接)阶段
当类加载到系统后,就开始链接操作,验证是链接操作的第一步。验证的步骤比较复杂,实际要验证的项目也很繁多,大体上Java虚拟机需要做以下检查,如图所示。验证的内容则涵盖了类数据信息的格式验证、语义检查、字节码验证,以及符号引用验证等。链接阶段的验证虽然拖慢了加载速度,但是它避免了在字节码运行时还需要进行各种检查。(磨刀不误砍柴工) 栈映射帧(StackMapTable)就是在这个阶段,用于检测在特定的字节码处,其局部变量表和操作数栈是否有着正确的数据类型。原创 2022-10-02 10:40:36 · 181 阅读 · 0 评论 -
19.2 类的加载过程(类的生命周期)详解 - 过程一:Loading(加载)阶段
所谓类模板对象,其实就是Java类在JVM内存中的一个快照, JVM将从字节码文件中解析出的常量池、 类字段、类方法等信息存储到类模板中,这样JVM在运行期便能通过类模板而获取Java类中的任意信息,能够对Java类的成员变量进行遍历,也能进行Java方法的调用。反射的机制即基于这一基础。如果JVM没有将Java类的声明信息存储起来,则JVM在运行期也无法反射。原创 2022-10-02 10:39:00 · 102 阅读 · 0 评论 -
19.1 类的加载过程(类的生命周期)详解 - 概述
我们所说的加载完毕包括:加载、链接、初始化三个阶段都完成之后类进入方法区中。其中,验证、准备、解析3个部分统称为链接(Linking)在Java中数据类型分为基本数据类型和引用数据类型。原创 2022-10-02 10:38:22 · 118 阅读 · 0 评论 -
18.10 字节码指令集与解析举例 - 同步控制指令
java虚拟机支持两种同步结构:方法级的同步**和**方法内部一段指令序列的同步,这两种同步都是使用monitor来支持的。原创 2022-07-30 23:26:50 · 424 阅读 · 0 评论 -
18.9 字节码指令集与解析举例 - 异常处理指令
异常处理指令原创 2022-07-30 23:25:11 · 165 阅读 · 0 评论 -
18.8 字节码指令集与解析举例 - 控制转义指令
程序流程离不开条件控制,为了支持条件跳转,虚拟机提供了大量字节码指令,大体上可以分为1)比较指令、2)条件跳转指令、3)比较条件跳转指令、4)多条件分支跳转指令、5)无条件跳转指令等。...原创 2022-07-30 23:23:33 · 543 阅读 · 0 评论 -
18.7 字节码指令集与解析举例 - 操作数栈管理指令
复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶dup,dup2,dup_x1,dup2_x1,dup_x2,dup2_×2;指令nop,是一个非常特殊的指令,它的字节码为0x00。Java虚拟机没有提供交换两个64位数据类型(long、double)数值的指令。如同操作一个普通数据结构中的堆栈那样,JVM提供的操作数栈管理指令,可以用于直接操作操作数栈的指令。将一个或两个元素从栈顶弹出,并且直接废弃pop,pop2;这些指令属于通用型,对栈的压入或者弹出无需指明数据类型。...原创 2022-07-30 23:22:08 · 118 阅读 · 0 评论 -
18.6 字节码指令集与解析举例 - 方法调用与返回指令
通过ireturn指令,将当前函数操作数栈的顶层元素弹出,并将这个元素压入调用者函数的操作数栈中(因为调用者非常关心函数的返回值),所有在当前函数操作数栈中的其他元素都会被丢弃。如果当前返回的是synchronized方法,那么还会执行一个隐含的monitorexit指令,退出临界区。最后,会丢弃当前方法的整个帧,恢复调用者的帧,并将控制权转交给调用者。方法调用结束前,需要进行返回。...原创 2022-07-30 23:21:30 · 256 阅读 · 0 评论 -
18.5 字节码指令集与解析举例 - 对象的创建与访问指令
Java是面向对象的程序设计语言,虚拟机平台从字节码层面就对面向对象做了深层次的支持。有一系列指令专门用于对象操作,可进一步细分为创建指令、字段访问指令、数组操作指令、类型检查指令。...原创 2022-07-30 23:20:44 · 138 阅读 · 0 评论 -
18.4 字节码指令集与解析举例 - 类型转换指令
Java虚拟机直接支持以下数值的宽化类型转换(wideningnumericconversion,小范围类型向大范围类型的安全转换)。尽管数据类型窄化转换可能会发生上限溢出、下限溢出和精度丢失等情况,但是Java虚拟机规范中明确规定数值类型的窄化转换指令永远不可能导致虚拟机抛出运行时异常。窄化类型转换可能会导致转换结果具备不同的正负号、不同的数量级,因此,转换过程很可能会导致数值丢失精度。一方面可以减少实际的数据类型,如果为short和byte都准备一套指令,那么指令的数量就会大增,而。...原创 2022-07-30 23:19:44 · 217 阅读 · 0 评论 -
18.3 字节码指令集与解析举例 - 算数指令
作用算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新压入操作数栈。分类大体上算术指令可以分为两种对进行运算的指令与对进行运算的指令。原创 2022-07-30 23:18:56 · 741 阅读 · 0 评论 -
18.2 字节码指令集与解析举例 - 加载与存储指令
加载和存储指令用于将数据从栈帧的局部变量表和操作数栈之间来回传递。上面所列举的指令助记符中,有一部分是以尖括号结尾的(例如iload_)。这些指令助记符实际上代表了一组指令(例如iload_代表 了iload_0、iload_1、iload_2和iload_3这几个指令)。这几组指令都是某个带有一个操作数的通用指令(例如iload) 的特殊形式,对于这若干组特殊指令来说,它们表面上没有操作数,不需要进行取操作数的动作,但操作数都隐含在指令中。...原创 2022-07-30 23:14:18 · 427 阅读 · 0 评论 -
18.1 字节码指令集与解析举例 - 概述
编译器会在编译期或运行期将byte和short类型的数据带符号扩展(Sign-Extend)为相应的int类型数据,将boolean和char类型数据零位扩展(Zero-Extend)为相应的int类型数据。与之类似,在处理boolean、byte、short和char类型的数组时,也会转换为使用对应的int类型的字节码指令来处理。例如,iload指令用于从局部变量表中加载int型的数据到操作数栈中,而fload指令加载的则是float类型的数据。...原创 2022-07-30 23:10:30 · 91 阅读 · 0 评论 -
16.9 垃圾回收器 - GC日志分析
GC日志分析通过阅读GC日志,我们可以了解Java虚拟机内存分配与回收策略。内存分配与垃圾回收的参数列表XX: +PrintGC 输出Gc日志。类似: -verbose:gcXX: +PrintGCDetails 输出GC的详细日志-XX: +PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)-XX: +PrintGCDateStamps 输出GC的时间戳(以日期的形式,如2013-05-04T21 :53:59.234+0原创 2022-03-18 13:30:46 · 4555 阅读 · 0 评论 -
16.8 垃圾回收器 - 垃圾回收器总结
垃圾回收器总结7种经典垃圾回收器总结截止JDK 1.8,一共有7款不同的垃圾收集器。每一款不同的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选用不同的垃圾收集器。GC发展阶段:Serial=>Parallel(并行)=>CMS(并发)=>G1=>ZGC垃圾回收器组合不同厂商、不同版本的虚拟机实现差别很大。HotSpot虚拟机在JDK7/8后所 有收集器及组合(连线),如下图:两个收集器间有连线,表明它们可以搭配使用:Serial/Serial原创 2022-03-18 13:27:39 · 158 阅读 · 0 评论 -
16.7 垃圾回收器 - G1回收器:区域化分代式
G1回收器:区域化分代式既然我们已经有了前面几个强大的GC,为什么还要发布Garbage First (G1 ) GC?原因就在于应用程序所应对的业务越来越庞大、复杂,用户越来越多,没有GC就不能保证应用程序正常进行,而经常造成STW的GC又跟不上实际的需求,所以才会不断地尝试对GC进行优化。G1 (Garbage- First)垃圾回收器是在Java7 update 4之 后引入的一个新的垃圾回收器,是当今收集器技术发展的最前沿成果之一。与此同时,为了适应现在不断扩大的内存和不断增加的处理器数量,进原创 2022-03-18 13:26:21 · 993 阅读 · 0 评论 -
16.6 垃圾回收器 - CMS回收器 低延迟
CMS回收器 低延迟在JDK 1.5时期,HotSpot推出了一款在强交互应用中几乎可认为有划时代意义的垃圾收集器: CMS (Concurrent -Mark-Sweep )收集器,这款收集器是HotSpot虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上原创 2022-03-18 13:24:06 · 155 阅读 · 0 评论 -
16.5 垃圾回收器 - Parallel回收器:吞吐量优先
Parallel回收器:吞吐量优先HotSpot的年轻代中除了拥有ParNew收集器是基于并行回收的以外,Parallel Scavenge收集器同样也采用了复制算法、并行回收和"Stop the World"机制。那么Parallel收集器的出现是否多此一举?和ParNew收集器不同,Parallel Scavenge收集 器的目标则是达到一个可控制的吞吐量(Throughput),它也被称为吞吐量优先的垃圾收集器。自适应调节策略也是Parallel Scavenge 与ParNew一个原创 2022-03-18 13:23:21 · 304 阅读 · 0 评论 -
16.4 垃圾回收器 - ParNew回收器:并行回收
ParNew回收器:并行回收如果说Serial GC是年轻代中的单线程垃圾收集器,那么ParNew收集器则是Serial收集器的多线程版本。Par是Parallel的缩写, New:只能处理的是新生代ParNew收集器除了采用并行回收的方式执行内存回收外,两款垃圾收集器之间几乎没有任何区别。ParNew收集器在年轻代中同样也是采用复制算法、"Stop- the-World"机制。ParNew是很多JVM运行在server模式下新生代的默认垃圾收集器。对于新生代,回收次数频繁,原创 2022-03-18 13:22:43 · 181 阅读 · 0 评论 -
16.3 垃圾回收器 - Serial回收器:串行回收
Serial回收器:串行回收Serial收集器是最基本、历史最悠久的垃圾收集器了。JDK1.3之 前回收新生代唯一的选择。Serial收集器作为HotSpot中Client模式下的默认新生代垃圾收集器。Serial收集器采用复制算法、串行回收和"Stop-the-World"机制的方式执行内存回收。除了年轻代之外,Serial收集器还提供用于执行老年代垃圾收集的Serial 0ld收集器。Serial 0ld收集器同样也采用了串行回收和"Stop the World"机制,只不过内存回收算法使用原创 2022-03-18 13:22:11 · 263 阅读 · 0 评论 -
16.2 垃圾回收器 - 不同的垃圾回收器概述
不同的垃圾回收器概述7款经典的垃圾收集器串行回收器: Serial、 Serial Old并行回收器: ParNew、 Parallel Scavenge、 Parallel Old并发回收器: CMS、G17款经典收集器与垃圾分代之间的关系新生代收集器: Serial、 ParNew、Parallel Scavenge;老年代收集器: Serial Old、 Parallel Old、CMS;整堆收集器: G1;垃圾收集器的组合关系1.两个收集器间有连线,表明原创 2022-03-18 13:21:37 · 197 阅读 · 0 评论 -
16.1 垃圾回收器 - GC分类与性能指标
GC分类与性能指标垃圾回收器分类按线程数分,可以分为串行垃圾回收器和并行垃圾回收器。串行回收指的是在同一时间段内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾收集工作结束。在诸如单CPU处理器或者较小的应用内存等硬件平台不是特别优越的场合,串行回收器的性能表现可以超过并行回收器和并发回收器。所以,串行回收默认被应用在客户端的Client模式下的JVM中在并发能力比较强的CPU.上,并行回收器产生的停顿时间要短于串行回收器。和串行回收相反,并行收集可以运用多个CPU同原创 2022-03-18 13:20:38 · 635 阅读 · 0 评论