Java 虚拟机
Java虚拟机
槑!
这个作者很懒,什么都没留下…
展开
-
【JVM系列】后端编译优化
后端编译器优化主要指的运行时的即时编译器方法内联最重要的优化技术之一:方法内联。优点一是去除方法调用的成本(如查找方法版本、建立栈帧等)二是为其他优化建立良好的基础。方法内联膨胀之后可以便于在更大范围上进行后续的优化手段,可以获取更好的优化效果。实现内联与虚方法之间会产生“矛盾”。大多数的Java方法都无法进行内联,只有使用invokespecial指令调用的私有方法、实例构造器、父类方法和使用invokestatic指令调用的静态方法才会在编译期进行解析,其他的Java方法调用原创 2020-10-27 09:52:23 · 204 阅读 · 3 评论 -
【JVM系列】前端编译与语法糖
编译与优化前端编译器Javac从Javac代码的总体结构来看,编译过程大致可以分为1个准备过程和3个处理过程,它们分别如下所示。准备过程:初始化插入式注解处理器。解析与填充符号表过程,包括:词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树。填充符号表。产生符号地址和符号信息。插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段分析与字节码生成过程,包括:标注检查。对语法的静态信息进行检查。数据流及控制流分析。对程序动态运行过程进行检查。解语法原创 2020-10-27 00:12:11 · 185 阅读 · 5 评论 -
【JVM系列】方法执行指令详解
方法执行分类jvm 有 5 条调用方法的字节码指令invokestatic。用于调用静态方法。invokespecial。用于调用实例构造器<init>()方法、私有方法和父类中的方法。invokevirtual。用于调用所有的虚方法。invokeinterface。用于调用接口方法,会在运行时再确定一个实现该接口的对象。invokedynamic。先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法。可以分为三类(说到底是因为方法的多态性)invokesta原创 2020-10-27 00:12:00 · 1630 阅读 · 2 评论 -
【JVM系列】类加载器详解(JDK9+)
模块化如何向前兼容具名模块(Named Module)具名模块也称为应用模块(Application Module),通常在模块根目录下有 module-info.java 文件的话,那么该模块就称为具名模块,我们编写的模块一般都属于这种类型。无名模块(Unnamed Module):不分模块的 jar 包,放到 不分模块的路径(即这个项目类路径下)无名模块指的就是不包含 module-info.java 的 jar 包,通常这些 jar 包都是 Java 9 之前构建的。无名模块可以读取原创 2020-10-27 00:11:48 · 4584 阅读 · 7 评论 -
【JVM系列】类加载过程
加载过程阶段一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)七个阶段。其中验证、准备、解析三个部分统称为连接(Linking)。顺序加载、验证、准备、初始化和卸载这五个阶段的开始顺序是确定的,类型的加载过程必须按照这种顺序按部就班地开始,而解析阶段则原创 2020-10-27 00:11:33 · 148 阅读 · 0 评论 -
【JVM系列】类加载时机
调优问题无非就是两种抛出异常:如果抛出 oom,怎么解决没抛出异常:如果没抛出异常,只是 gc 停顿时间过长,或者频率高,或者影响到了系统吞吐量,怎么解决分析工具进程查询工具jpsjps 主要用来输出JVM中运行的进程状态信息jps [options] [hostid]options-q:不输出类名、Jar名 和传入main方法的参数-m:输出传入main方法的参数-l:输出main类或Jar的全限名-v:输出传入JVM的参数hostid如果不指定h原创 2020-10-27 00:07:17 · 1271 阅读 · 1 评论 -
【JVM系列】故障处理工具与六种OOM
参数分代通用参数补充说明-XX:+UseAdaptiveSizePolicy:如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到-XX:MaxTenuringThreshold中要求的年龄。-XX:+HandlePromotionFailure:在发生Minor GC之前,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象总空间如果这个条件成立,那这一次Minor GC可以确保是安全的原创 2020-10-26 23:53:36 · 203 阅读 · 3 评论 -
【JVM系列】无操作Epsilon与回收器参数
无操作Epsilon收集器自动内存管理子系统Epsilon,是一款以不能够进行垃圾收集为“卖点”的垃圾收集器,被形容成一个无操作的收集器(A No-Op Garbage Collector)。而事实上只要Java虚拟机能够工作,垃圾收集器便不可能是真正“无操作”的。原因是“垃圾收集器”这个名字并不能形容它全部的职责,更贴切的名字应该是“自动内存管理子系统”。一个垃圾收集器除了垃圾收集这个本职工作之外,它还要负责堆的管理与布局、对象的分配、与解释器的协作、与编译器的协作、与监控子系统协作等职责,其中原创 2020-10-26 23:50:42 · 264 阅读 · 0 评论 -
【JVM系列】低延迟回收器 ZGC
ZGC收集器ZGC主要特征基于Region内存布局的,(暂时)不设分代的,使用了读屏障、染色指针和内存多重映射等技术来实现可并发的标记-整理算法的,以低延迟为首要目标的一款垃圾收集器。内存布局(ZGC的Region有大、中、小三类容量)小型Region(Small Region):容量固定为2MB,用于放置小于256KB的小对象。中型Region(Medium Region):容量固定为32MB,用于放置大于等于256KB但小于4MB的对象。大型Region原创 2020-10-26 23:50:11 · 195 阅读 · 0 评论 -
【JVM系列】低延迟回收器 Shenandoah
Shenandoah收集器比起G1改进最重要的当然是支持并发的整理算法,G1的回收阶段是可以多线程并行的,但却不能与用户线程并发,这点是Shenandoah最核心的功能其次,Shenandoah(目前)是默认不使用分代收集的,换言之,不会有专门的新生代Region或者老年代Region的存在,没有实现分代,并不是说分代对Shenandoah没有价值,这更多是出于性价比的权衡,基于工作量上的考虑而将其放到优先级较低的位置上。最后,Shenandoah摒弃了在G1中耗费大量内存和计算资源去维原创 2020-10-26 23:50:00 · 197 阅读 · 0 评论 -
【JVM系列】Region 内存布局回收器 G1
G1收集器特点可以面向堆内存任何部分来组成回收集(Collection Set,一般简称CSet)进行回收,衡量标准不再是它属于哪个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大,这就是G1收集器的Mixed GC模式。能够建立起“停顿时间模型”(Pause Prediction Model)的收集器,停顿时间模型的意思是能够支持指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过N毫秒这样的目标,以后会完全取代 CMS(CMS 在 JDK 9 已经过时)。可预测的停顿时原创 2020-10-26 23:49:34 · 1291 阅读 · 0 评论 -
【JVM系列】经典垃圾回收器
垃圾回收器分类Partial GC:并不收集整个GC堆的模式Young GC:只收集young gen的GC,有 Serial GC 、ParNew GC、Parallel Scavenge GC。Old GC:只收集old gen的GC。只有 CMS GC 是针对老年代的。Mixed GC:收集整个young gen以及部分old gen的GC,即所有分 Region 的收集器,包括 G1、Shenandoah、ZGC。Full GC:收集整个堆,包括young gen、old g原创 2020-10-26 23:49:19 · 252 阅读 · 0 评论 -
【JVM系列】HotSpot回收算法细节
HotSpot算法细节发起内存回收安全点安全点如何选取数量:其选定的既不能太少以至于让收集器等待时间过长,也不能太过频繁以至于过分增大运行时的内存负荷。位置:安全点位置的选取基本上是以“是否具有让程序长时间执行的特征”为标准进行选定的,因为每条指令执行的时间都非常短暂,程序不太可能因为指令流长度太长这样的原因而长时间执行。“长时间执行”的最明显特征就是指令序列的复用,例如方法调用、循环跳转、异常跳转等都属于指令序列复用,所以只有具有这些功能的指令才会产生安全点。实现方案抢先式中原创 2020-10-26 23:49:00 · 149 阅读 · 0 评论 -
【JVM系列】垃圾回收判定与算法
垃圾回收原因与算法介绍在 JVM 中,程序计数器、虚拟机栈、本地方法栈 3 个区域随线程而生,随线程而灭,而栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的(尽管在运行期会由即时编译器进行一些优化,但在基于概念模型的讨论里,大体上可以认为是编译期可知的)。因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需要过多考虑如何回收的问题,当方法结束或者线程结束时,内存自然就跟随着回收了。而 Java 堆和方法区这两个区域则原创 2020-10-26 23:48:41 · 1221 阅读 · 2 评论 -
【JVM系列】对象详解
对象创建过程1、当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程,2、在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。内存分配划分方式指针碰撞:假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在原创 2020-10-26 23:48:25 · 117 阅读 · 0 评论 -
【JVM系列】运行时数据区域详解
运行时数据区域程序计数器在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。此内存区域是唯一一个在《Java虚拟机规范》中没有原创 2020-10-26 23:48:07 · 180 阅读 · 0 评论