爱分享的淘金达人
http://www.jhzjz.cn/
展开
-
java逃逸分析
今天我将会介绍 Java 虚拟机中即时编译器的逃逸分析,以及基于逃逸分析的优化。在 Java 虚拟机的即时编译语境下,逃逸分析将判断新建的对象是否会逃逸。即时编译器判断对象逃逸的依据有两个:一是看对象是否被存入堆中,二是看对象是否作为方法调用的调用者或者参数。即时编译器会根据逃逸分析的结果进行优化,如锁消除以及标量替换。后者指的是将原本连续分配的对象拆散为一个个单独的字段,分布在栈上或者寄存器中。...原创 2022-07-10 21:03:14 · 161 阅读 · 0 评论 -
即时编译器的中间表达形式
今天我将给大家介绍即时编译器的内部构造。即时编译器将所输入的 Java 字节码转换成 SSA IR,以便更好地进行优化。具体来说,C2 和 Graal 采用的是一种名为 Sea-of-Nodes 的 IR,其特点用 IR 节点来代表程序中的值,并且将源程序中基于变量的计算转换为基于值的计算。此外,我还介绍了 C2 和 Graal 的 IR 的可视化工具 IGV,以及基于 IR 的优化 GVN。...原创 2022-07-09 14:22:08 · 132 阅读 · 0 评论 -
即时编译(下)
今天我们来继续讲解 Java 虚拟机中的即时编译。上篇提到,分层编译中的 0 层、2 层和 3 层都会进行 profiling,收集能够反映程序执行状态的数据。其中,最为基础的便是方法的调用次数以及循环回边的执行次数。它们被用于触发即时编译。...原创 2022-06-22 22:07:15 · 100 阅读 · 0 评论 -
即时编译(上)
今天我们便来详细剖析一下 Java 虚拟机中的即时编译。在专栏的第一篇中,我曾经简单地介绍过即时编译。这是一项用来提升应用程序运行效率的技术。通常而言,代码会先被 Java 虚拟机解释执行,之后反复执行的热点代码则会被即时编译成为机器码,直接运行在底层硬件之上。HotSpot 虚拟机包含多个即时编译器 C1、C2 和 Graal。...原创 2022-06-20 18:38:00 · 223 阅读 · 0 评论 -
Java语法糖与Java编译器
今天我将会介绍了 Java 编译器对几个语法糖的处理。基本类型和其包装类型之间的自动转换,也就是自动装箱、自动拆箱,是通过加入[Wrapper].valueOf(如 Integer.valueOf)以及[Wrapper].[primitive]Value(如 Integer.intValue)方法调用来实现的。Java 程序中的泛型信息会被擦除。具体来说,Java 编译器将选取该泛型所能指代的所有类中层次最高的那个,作为替换泛型的具体类。...原创 2022-06-14 11:13:16 · 108 阅读 · 0 评论 -
Java字节码
今天我主要介绍了各种类型的 Java 字节码。java 方法的栈桢分为操作数栈和局部变量区。通常来说,程序需要将变量从局部变量区加载至操作数栈中,进行一番运算之后再存储回局部变量区中。Java 字节码可以划分为很多种类型,如加载常量指令,操作数栈专用指令,局部变量区访问指令,Java 相关指令,方法调用指令,数组相关指令,控制流指令,以及计算相关指令。...原创 2022-06-13 17:25:44 · 142 阅读 · 0 评论 -
Java虚拟机是怎么实现synchronized的?
今天我介绍了 Java 虚拟机中 synchronized 关键字的实现,按照代价由高至低可分为重量级锁、轻量级锁和偏向锁三种。重量级锁会阻塞、唤醒请求加锁的线程。它针对的是多个线程同时竞争同一把锁的情况。Java 虚拟机采取了自适应自旋,来避免线程在面对非常小的 synchronized 代码块时,仍会被阻塞、唤醒的情况。轻量级锁采用 CAS 操作,将锁对象的标记字段替换为一个指针,指向当前线程栈上的一块空间,存储着锁对象原本的标记字段。它针对的是多个线程在不同时间段申请同一把锁的情况。...原创 2022-06-12 08:29:02 · 125 阅读 · 0 评论 -
垃圾回收(下)
今天我将介绍一些 Java 虚拟机中垃圾回收具体实现的一些通用知识。Java 虚拟机将堆分为新生代和老年代,并且对不同代采用不同的垃圾回收算法。其中,新生代分为 Eden 区和两个大小一致的 Survivor 区,并且其中一个 Survivor 区是空的。在只针对新生代的 Minor GC 中,Eden 区和非空 Survivor 区的存活对象会被复制到空的 Survivor 区中,当 Survivor 区中的存活对象复制次数超过一定数值时,它将被晋升至老年代。...原创 2022-06-10 18:20:22 · 98 阅读 · 0 评论 -
垃圾回收(上)
Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象。它从一系列 GC Roots 出发,边标记边探索所有被引用的对象。为了防止在标记过程中堆栈的状态发生改变,Java 虚拟机采取安全点机制来实现 Stop-the-world 操作,暂停其他非垃圾回收线程。回收死亡对象的内存共有三种方式,分别为:会造成内存碎片的清除、性能开销较大的压缩、以及堆使用效率较低的复制。...原创 2022-06-09 11:50:00 · 81 阅读 · 0 评论 -
Java对象的内存布局
今天我介绍了 Java 虚拟机构造对象的方式,所构造对象的大小,以及对象的内存布局。常见的 new 语句会被编译为 new 指令,以及对构造器的调用。每个类的构造器皆会直接或者间接调用父类的构造器,并且在同一个实例中初始化相应的字段。Java 虚拟机引入了压缩指针的概念,将原本的 64 位指针压缩成 32 位。压缩指针要求 Java 虚拟机堆中对象的起始地址要对齐至 8 的倍数。Java 虚拟机还会对每个类的字段进行重排列,使得字段也能够内存对齐。...原创 2022-06-09 11:27:52 · 93 阅读 · 0 评论 -
JVM是怎么实现invokedynamic的?(下)
上节讲到,为了让所有的动物都能参加赛马,Java 7 引入了 invokedynamic 机制,允许调用任意类的“赛跑”方法。不过,我们并没有讲解 invokedynamic,而是深入地探讨了它所依赖的方法句柄。今天,我便来正式地介绍 invokedynamic 指令,讲讲它是如何生成调用点,并且允许应用程序自己决定链接至哪一个方法中的。...原创 2022-06-08 11:23:18 · 124 阅读 · 0 评论 -
JVM是怎么实现invokedynamic的?(上)
今天我介绍了 invokedynamic 底层机制的基石:方法句柄。方法句柄是一个强类型的、能够被直接执行的引用。它仅关心所指向方法的参数类型以及返回类型,而不关心方法所在的类以及方法名。方法句柄的权限检查发生在创建过程中,相较于反射调用节省了调用时反复权限检查的开销。方法句柄可以通过 invokeExact 以及 invoke 来调用。其中,invokeExact 要求传入的参数和所指向方法的描述符严格匹配。方法句柄还支持增删改参数的操作,这些操作是通过生成另一个充当适配器的方法句柄来实现的。...原创 2022-06-08 09:58:09 · 88 阅读 · 0 评论 -
JVM是如何实现反射的?
在默认情况下,方法的反射调用为委派实现,委派给本地实现来进行方法调用。在调用超过 15 次之后,委派实现便会将委派对象切换至动态实现。这个动态实现的字节码是自动生成的,它将直接使用 invoke 指令来调用目标方法。方法的反射调用会带来不少性能开销,原因主要有三个:变长参数方法导致的 Object 数组,基本类型的自动装箱、拆箱,还有最重要的方法内联。...原创 2022-06-07 14:52:58 · 378 阅读 · 0 评论 -
JVM是如何执行方法调用的?(下)
本篇主要介绍了虚方法调用在 Java 虚拟机中的实现方式。虚方法调用包括 invokevirtual 指令和 invokeinterface 指令。如果这两种指令所声明的目标方法被标记为 final,那么 Java 虚拟机会采用静态绑定。否则,Java 虚拟机将采用动态绑定,在运行过程中根据调用者的动态类型,来决定具体的目标方法。Java 虚拟机的动态绑定是通过方法表这一数据结构来实现的。方法表中每一个重写方法的索引值,与父类方法表中被重写的方法的索引值一致。......原创 2022-06-06 11:51:35 · 72 阅读 · 0 评论 -
JVM是如何执行方法调用的?(上)
在 Java 中,方法存在重载以及重写的概念,重载指的是方法名相同而参数类型不相同的方法之间的关系,重写指的是方法名相同并且参数类型也相同的方法之间的关系。Java 虚拟机识别方法的方式略有不同,除了方法名和参数类型之外,它还会考虑返回类型。在 Java 虚拟机中,静态绑定指的是在解析时便能够直接识别目标方法的情况,而动态绑定则指的是需要在运行过程中根据调用者的动态类型来识别目标方法的情况。由于 Java 编译器已经区分了重载的方法,因此可以认为 Java 虚拟机中不存在重载。...原创 2022-06-06 10:59:33 · 97 阅读 · 0 评论 -
JVM是如何处理异常的?
众所周知,异常处理的两大组成要素是抛出异常和捕获异常。这两大要素共同实现程序控制流的非正常转移。抛出异常可分为显式和隐式两种。显式抛异常的主体是应用程序,它指的是在程序中使用“throw”关键字,手动将异常实例抛出。隐式抛异常的主体则是 Java 虚拟机,它指的是 Java 虚拟机在执行过程中,碰到无法继续执行的异常状态,自动抛出异常。捕获异常则涉及了如下三种代码块,try代码块、catch代码块、finally代码块。...原创 2022-06-05 20:42:31 · 355 阅读 · 0 评论 -
Java虚拟机是如何加载Java类的?
听我的意大利同事说,他们那边有个习俗,就是父亲要帮儿子盖栋房子。这事要放在以前还挺简单,亲朋好友搭把手,盖个小砖房就可以住人了。现在呢,整个过程要耗费好久的时间。首先你要请建筑师出个方案,然后去市政部门报备、验证,通过后才可以开始盖房子。盖好房子还要装修,之后才能住人。盖房子这个事,和 Java 虚拟机中的类加载还是挺像。从 class 文件到内存中的类,按先后顺序需要经过加载、链接以及初始化三大步骤。其中,链接过程中同样需要验证;而内存中的类没有经过初始化,同样不能使用。...原创 2022-06-05 20:04:13 · 149 阅读 · 0 评论 -
Java代码是怎么运行的?
我们学院的一位教授之前去美国开会,入境的时候海关官员就问他:既然你会计算机,那你说说你用的都是什么语言吧?教授随口就答了个 Java。海关一看是懂行的,也就放行了,边敲章还边说他们上学那会学的是 C+。我还特意去查了下,真有叫 C+ 的语言,但是这里海关官员应该指的是 C++。事后教授告诉我们,他当时差点就问海关,是否知道 Java 和 C++ 在运行方式上的区别。但是又担心海关官员拿他的问题来考别人,也就没问出口。那么,下次你去美国,不幸地被海关官员问这个问题,你懂得如何回答吗?作为一名 Ja原创 2020-06-25 11:43:44 · 225 阅读 · 1 评论 -
开篇词--为什么我们要学习Java虚拟机?
前不久我参加了一个国外程序员的讲座,讲座的副标题很有趣,叫做:“我如何学会停止恐惧,并且爱上 Java 虚拟机”。这句话来自一部黑色幽默电影《奇爱博士》,电影描述了冷战时期剑拔弩张的氛围。程序员之间的语言之争又未尝不是如此。写系统语言的鄙视托管语言低下的执行效率;写托管语言的则取笑系统语言需要手动管理内存;写动态语言的不屑于静态语言那冗余的类型系统;写静态语言的则嘲讽动态语言里面各种光怪陆离的运行时错误。Java 作为应用最广的语言,自然吸引了不少的攻击,而身为 Java 程序员的你,或许在口水原创 2020-06-23 10:20:04 · 202 阅读 · 1 评论
分享