Java 虚拟机
文章平均质量分 85
Java 虚拟机
低吟不作语
这是最坏的时代,也是最好的时代
展开
-
JVM 参数配置
XX:SurvivorRatio: -XX:SurvivorRatio=8 表示 Eden 区和两个 Survivor 区的比值为 8:1,即 Eden:SurvivorTo=8:1、Eden:SurvivorFrom=8:1。-XX:NewRatio:-XX:NewRatio=3 表示设置新生代与老年代的比值为 1:3,因此新生代占整个堆栈的 1/4,老年代占整个堆内存的 3/4。-XX:NewSize:-XX:NewSize=1g 表示设置新生代的大小为 1GB,一般建议设置为总堆内存的 1/3。原创 2024-08-14 16:37:06 · 711 阅读 · 0 评论 -
后端编译与优化
本书部分摘自《深入理解 Java 虚拟机第三版》概述前面讲过前端编译是将 Java 源代码编译成 Class 字节码,那么后端编译就对应把 Class 文件转换成与本地机器相关的二进制机器码的过程。然后 JVM 把每一条要执行的字节码交给解释器,翻译成对应的机器码,由解释器执行,Java 程序就运行起来了即时编译器当虚拟机发现某个方法或代码块运行特别频繁,就会把这些代码认定为热点代码(HotSpot Code),为了提高热点代码的运行效率,在运行时,虚拟机将会把这些代码编译为本地机器码,并..原创 2021-02-07 15:29:23 · 316 阅读 · 0 评论 -
前端编译与优化
本文部分摘自《深入理解 Java 虚拟机第三版》概述前端编译器(也叫编译器的前端)中的前端是指把 Java 文件转变为 Class 字节码文件的过程,顾名思义,前端编译器就是完成这一部分编译工作的。前端编译器对代码的运行效率几乎没有任何优化措施可言,Java 虚拟机设计团队选择把对性能的优化全部集中到运行期的即时编译器中,这样可以让那些不是由 Javac 产生的 Class 文件也能享受到编译器优化措施所带来的性能红利。前端编译器的优化主要集中在提高程序员的编码效率上,例如语法糖就是靠前端编..原创 2021-02-04 20:26:46 · 308 阅读 · 0 评论 -
虚拟机字节码执行引擎 —— 方法调用
本文部分摘自《深入理解 Java 虚拟机第三版》概述方法调用并不等同于方法中的代码被执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法)。之前讲过,一切方法调用在 Class 文件里面都是以符号引用的形式存储,而非方法在实际运行时内存布局中的入口地址(直接引用)。这个特性给 Java 带来强大的动态扩展能力,但也使得 Java 方法调用过程变得相对复杂,某些调用需要在类加载期间,甚至到运行期间才能确定目标方法的直接引用解析所有方法调用的目标方法在 Class 文件里面都..原创 2021-01-30 14:41:35 · 131 阅读 · 0 评论 -
虚拟机字节码执行引擎 —— 运行时栈帧
本文部分摘自《深入理解 Java 虚拟机》执行引擎执行引擎是 Java 虚拟机核心的组成部分之一,作用就是用来执行字节码。在 Java 虚拟机规范中执行引擎只是一个概念模型,不同的虚拟机可以有不同的实现,通常会有解释执行(通过编译器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,或者二者兼备。但无论是何种实现,从外观上看,所有 Java 虚拟机的执行引擎的输入、输出都是一致的:输入的是字节码的二进制流,处理过程是解析并执行字节码,输出是执行结果运行时栈帧结构Java 虚拟机以方..原创 2021-01-23 17:14:17 · 131 阅读 · 0 评论 -
Java 虚拟机类加载机制
本文部分摘自《深入理解 Java 虚拟机第三版》概述Java 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这个过程被称作虚拟机的类加载机制与那些在编译时需要进行连接的语言不同,在 Java 语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的,这种做法虽然让类加载时稍微增加了一些性能开销,但也为 Java 应用提供了极高的扩展性和灵活性,Java 可动态扩展的语言特性就是依赖运行期动态加载和动..原创 2021-01-16 16:56:44 · 183 阅读 · 0 评论 -
JVM 字节码指令
本文部分摘自《深入理解 Java 虚拟机》简介Java 虚拟机的指令由操作码 + 操作数组成,其中操作码是代表某种特定操作含义的数字,长度为一个字节,而操作数就是此操作所需的一个或多个参数。由于 Java 虚拟机采用面向操作数栈而非寄存器的架构,所以大多数指令都不包括操作数,只有一个操作码既然限制了 JVM 操作码的长度为一个字节(0 ~ 255),也意味着指令集的操作码总数不超过 256 条。Class 文件格式放弃了编译后代码的操作数长度对齐,因此虚拟机在处理那些超过一个字节的数据时,不得..原创 2021-01-08 10:54:17 · 200 阅读 · 0 评论 -
Class 类文件结构
本文部分摘自《深入理解 Java 虚拟机第三版》概述我们知道,Java 具有跨平台性,其实现基础就是虚拟机和字节码存储格式。Java 虚拟机不与 Java 语言绑定,只与 Class 文件所关联。Java 虚拟机作为一个通用的、与机器无关的执行平台,任何语言都可以将 Java 虚拟机作为它们的运行基础,以 Class 文件作为它们产品的交付媒介。Class 文件是一组以 8 个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符,这使得整个 Class..原创 2021-01-06 16:16:05 · 100 阅读 · 0 评论 -
JVM 常用命令行工具
本文部分摘自《深入理解 Java 虚拟机第三版》基础故障处理工具Java 开发人员肯定都知道 JDK 的 bin 目录下有许多小工具,这些小工具除了用于编译和运行 Java 程序外,打包、部署、签名、调试、监控、运维等各种场景都可能会见到它们的影子本文主要介绍的是用于监视虚拟机运行状态和进行故障处理的工具,根据软件可用性和授权的不同,可以分成三类:商业授权工具:主要是 JMC(Java Mission Control)及它要使用到的 JFR(Java Flight Recorder)。JM..原创 2021-01-04 01:04:44 · 322 阅读 · 0 评论 -
JVM 低延迟垃圾收集器 Shenandoah 和 ZGC
本文部分摘自《深入理解 Java 虚拟机第三版》概述衡量垃圾收集器的三项指标分别是:内存占用、吞吐量和延迟。这三者共同构成一个“不可能三角”,即一款优秀的收集器最多可以同时达成其中两项随着硬件性能的提升,对内存占用和吞吐量也有所助益,但对延迟却并非如此。比如内存扩大了,对延迟反而会带来负面效果,因为回收 1TB 的堆内存毫无疑问会比回收 1GB 的堆内存耗费更多时间。因此,延迟成为了垃圾收集器最重视的性能指标在 CMS 和 G1 之前的全部收集器,其工作的所有步骤都会产生 Stop The ..原创 2020-12-31 14:10:26 · 474 阅读 · 0 评论 -
JVM HotSpot 可达性分析算法实现细节
本文部分摘自《深入理解 Java 虚拟机第三版》根节点枚举在之前关于可达性分析算法的介绍中我们讲过,我们需要先找出可固定作为 GC Roots 的节点,然后沿着引用链去寻找那些无用的垃圾对象。GC Roots 节点一般在全局性引用(例如常量和类静态属性)与执行上下文(例如栈帧中的本地变量表)中,尽管目标明确,但查找过程要做到高效并非一件易事,若要逐个查找可作为起源的引用肯定需要消耗不少时间迄今为止,所有收集器在根节点枚举这一步骤时都是必须暂停用户线程,也即 Stop The World,因为如..原创 2020-12-26 16:51:05 · 431 阅读 · 0 评论 -
JVM 经典垃圾收集器 —— CMS 收集器和 G1 收集器
本文部分摘自《深入理解 Java 虚拟机第三版》概述CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。由于大部分 Java 应用主要集中在互联网网站以及基于浏览器的 B/S 系统的服务端,这类应用通常会较为关注服务的响应速度,希望系统的停顿时间尽可能少,CMS 收集器就非常符合这类应用的需求步骤从名字可以知道,CMS 收集器是基于标记 - 清除算法实现的,它的运作过程分为四个步骤:初始标记(CMS initial mark)仅仅只..原创 2020-12-26 14:33:44 · 945 阅读 · 0 评论 -
JVM 经典垃圾收集器
本文部分摘自《深入理解 Java 虚拟机第三版》概述如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的实践者。Java 虚拟机规范中对垃圾收集器的实现做出规定,因此不同的厂商、不同版本的虚拟机所包含的垃圾收集器各有不同。所谓经典就是在 JDK7 Update 4 以后,JDK11 发布以前的在 OpenJDK HotSpot 虚拟机所包含的全部可用的垃圾收集器。尽管这些经典垃圾收集器已算不上最先进的技术,但它们都经历了千锤百炼,基本上都是可以放心使用的垃圾收集器。各款经典垃圾收集器之..原创 2020-12-25 10:57:06 · 117 阅读 · 0 评论 -
Java 虚拟机垃圾收集机制详解
本文摘自深入理解 Java 虚拟机第三版垃圾收集发生的区域之前我们介绍过 Java 内存运行时区域的各个部分,其中程序计数器、虚拟机栈、本地方法栈三个区域随线程共存亡。栈中的每一个栈帧分配多少内存基本上在类结构确定下来时就已知,因此这几个区域的内存分配和回收都具有确定性,不需要考虑如何回收的问题,当方法结束或线程结束,内存自然也跟着回收了而 Java 堆和方法区这两个区域则有显著的不确定性,只有在程序运行时我们才能知道程序究竟创建了哪些对象,创建了多少对象,所以这部分内存的分配和回收是动态的,..原创 2020-12-03 21:10:52 · 241 阅读 · 0 评论 -
JVM 堆中对象分配、布局和访问
本文摘自深入理解 Java 虚拟机第三版对象的创建Java 是一门面向对象的语言,Java 程序运行过程中无时无刻都有对象被创建出来。从语言层面看,创建对象只是一个 new 关键字而已,而在虚拟机中,对象(仅限于普通 Java 对象,不包括数组和 Class 对象等)的创建又是怎么一个过程呢?以 Hotspot 虚拟机为例,当虚拟机遇到一条字节码指令,首先会检查这个指令的参数是否能在常量池中定位到一个符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化,如果没有,那么会先执行对应的类..原创 2020-12-02 15:54:15 · 217 阅读 · 0 评论 -
Java 虚拟机运行时数据区详解
本文摘自深入理解 Java 虚拟机第三版概述Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有的区域则是依赖用户线程的启动和结束而创建和销毁。因此,我们可以根据这个特点将区域划为为线程公有区域和线程私有区域两部分程序计数器程序计数器(Program Counter Register)是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器..原创 2020-11-29 15:02:22 · 263 阅读 · 0 评论