几分钟了解下java虚拟机--04
方法内联
方法内联能够触发更多的优化。通常而言,内联越多,生成代码的执行效率越高。然而,对于即时编译器来说,内联越多,编译时间也就越长,而程序达到峰值性能的时刻也将被推迟。
内联意味着有编译,编译后的机器码要存到 Codecache 中,而 Codecache 内存是有固定大小的由 Java 虚拟机参数 -XX:ReservedCodeCacheSize 控制),如果 Codecache 满了,则会带来性能问题
虚方法的内联
通过判断虚方法的目标是否唯一
- 唯一, 完全去虚化
直接内联
- 不唯一, 条件去虚化
向代码中增添类型比较,内联不同类型目标的虚方法
将虚方法调用转换为一个个的类型测试以及对应该类型的直接调用
HotSpot虚拟机的intrinsic
intrinsic 与方法内联
- 独立的桩程序
- 解释执行器(Interpreter):解释执行器在执行代码时,如果遇到对原方法的调用,可以直接跳转到对应的桩程序执行,而不是执行原方法的字节码。这样可以减少方法调用的开销,并可能使用更高效的实现
- 即时编译器(JIT Compiler):即时编译器在将字节码编译为机器码时,会将代表对原方法调用的中间表示(IR)节点替换为对桩程序的调用。这种替换发生在编译过程中,使得生成的机器码直接调用桩程序,而不是原方法
- 特殊的编译器 IR 节点
- 即时编译器(JIT Compiler):即时编译器会将对原方法的调用的 IR 节点,替换成特殊的 IR 节点,并参与接下来的优化过程。最终,即时编译器的后端将根据这些特殊的 IR 节点,生成指定的 CPU 指令
逃逸分析
一种确定指针动态范围的静态分析,它可以分析在程序的哪些地方可以访问到指针
- 对象是否被存入堆中(静态字段或者堆中对象的实例字段)
- 对象是否被传入未知代码中。
判断对象是否会被外部方法引用或线程共享
基于逃逸分析的优化
- 栈上分配:如果对象不会逃逸到方法外部,可以直接在栈上分配内存,而不是在堆上分配,从而减少垃圾回收的压力。由于JVM大多基于对象分布在堆上而进行的优化, 故引入了标量替换
- 标量替换:将对象拆分为基本类型(标量),直接在栈上分配这些基本类型,避免对象的创建。
class Foo {
int a = 0;
}
static int bar(int x) { static int bar (int x){
Foo foo = new Foo(); int a = x;
foo.a = x; return a;
return foo.a; }
}
同步消除:如果对象不被多个线程共享消除不必要的同步操作
synchronized (new Object()) {}以提高性能
部分逃逸分析
Graal中存在此优化(C2中无)
public static void bar(boolean cond) {
Object foo = new Object();
if (cond) {
foo.hashCode();
}
}
// 优化后代码类似:
public static void bar(boolean cond) {
if (cond) {
Object foo = new Object();
foo.hashCode();
}
}
部分逃逸分析通过考虑程序的控制流,能够在对象仅在部分路径中逃逸时进行优化,将对象的创建推迟到必要的分支中执行
XMM寄存器
由于普通寄存器只有32b 8字节,影响对数组向量的优化 故引入了XMM寄存器

c[i:i+3] = b[i:i+3]+c[i:i+3]

注解处理器
package java.lang;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
测试框架JMH(待完善)
generated-sources
具体来说,它们之间的继承关系是MyBenchmark_jmhType -> B3 -> B2 -> B1 -> MyBenchmark(这里A -> B代表 A 继承 B)。其中,B2 存放着 JMH 用来控制基准测试的各项字段。
为了避免这些控制字段对MyBenchmark类中的字段造成 false sharing 的影响,JMH 生成了 B1 和 B3,分别存放了 256 个 Boolean 字段,从而避免 B2 中的字段与MyBenchmark类、MyBenchmark_jmhType类中的字段(或内存里下一个对象中的字段)会出现在同一缓存行中。
注解@
@Fork允许开发人员指定所要 Fork 出的 Java 虚拟机的数目。@BenchmarkMode允许指定性能数据的格式。@Warmup和@Measurement允许配置预热迭代或者测试迭代的数目,每个迭代的时间以及每个操作包含多少次对测试方法的调用。@State允许配置测试程序的状态。测试前对程序状态的初始化以及测试后对程序状态的恢复或者校验可分别通过@Setup和@TearDown来实现。
JNI的运行机制(非重要)
native 方法的链接
- 让 Java 虚拟机自动查找符合默认命名规范的 C 函数
// foo.c
#include <stdio.h>
#include "org_example_Foo.h"
JNIEXPORT void JNICALL Java_org_example_Foo_bar__Ljava_lang_String_2Ljava_lang_Object_2
(JNIEnv *env, jobject thisObject, jstring str, jobject obj) {
printf("Hello, World\n");
return;
}
- C 代码中主动链接
JNI的 API

几分钟了解下java虚拟机--04的更多相关文章
- 带着新人看java虚拟机04(多线程篇)
我记得最开始接触多进程,多线程这一块的时候我不是怎么理解,为什么要有多线程啊?多线程到底是个什么鬼啊?我一个程序好好的就可以运行为什么要用到多线程啊?反正我是十分费解,即使过了很长时间我还是不是很懂, ...
- 每日一问:你了解 Java 虚拟机结构么?
对于从事 C/C++ 程序员开发的小伙伴来说,在内存管理领域非常头疼,因为他们总是需要对每一个 new 操作去写配对的 delete/free 代码.而对于我们 Android 乃至 Java 程序员 ...
- java虚拟机理解探索1
以下内容源于个人对<深入java虚拟机>的理解总结 基本概念: java虚拟机可以指一种抽象规范,也可以指一种具体实现,亦可以指一个java虚拟机实例. 虚拟机生命周期: 一个java虚拟 ...
- 深入java虚拟机学习 -- 内存管理机制
前面说过了类的加载机制,里面讲到了类的初始化中时用到了一部分内存管理的知识,这里让我们来看下Java虚拟机是如何管理内存的. 先让我们来看张图 有些文章中对线程隔离区还称之为线程独占区,其实是一个意思 ...
- 谈谈java虚拟机
本文可作为北京圣思元深入java虚拟机的课堂笔记. 先看一个令人dan teng的面试题 public class Singleton { public static Singleton s=new ...
- JVM基础系列第2讲:Java 虚拟机的历史
说起 Java 虚拟机,许多人就会将其与 HotSpot 虚拟机等同看待.但实际上 Java 虚拟机除了 HotSpot 之外,还有 Sun Classic VM.Exact VM.BEA JRock ...
- day 05JVM和深入理解java虚拟机
-----------------Java 虚拟机发展史 PS: Sun公司有 HotSpot, BEA公司有JRockit,IBM有 J9 这三个是高性能VM 在Oracle收购Sun和BEA这两 ...
- java虚拟机的内存机制
我们都知道,java程序的跨平台性离不开java虚拟机,虚拟机隔绝了底层操作系统,使得java程序可以直接运行在虚拟机之上.所以,对java的学习,离不开对java虚拟机的学习与了解.下面简单整理下j ...
- 深入理解Java虚拟机—内存管理机制
前面说过了类的加载机制,里面讲到了类的初始化中时用到了一部分内存管理的知识,这里让我们来看下Java虚拟机是如何管理内存的. 先让我们来看张图 有些文章中对线程隔离区还称之为线程独占区,其实是一个意思 ...
- 深入理解java虚拟机学习笔记(一)JVM内存模型
上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...
随机推荐
- 解决Linux下文本文件中文乱码问题
上一篇我们提到了OS和DB的一些中文乱码问题解决,本篇我们继续介绍下在OS上的文本文件中文乱码问题. 操作系统是Linux(OEL 8.10),所有文件是打了一个压缩包上传的,上传解压后发现其中的文本 ...
- 通过百度地图 API V2.0 版本,进行地图坐标系转换
注意 先阅读参考链接 瞭月 的文章,再阅读本文. 其中,请求参数中 model 的含义: amap/tencent - 即:GCJ02 火星坐标系,由中国国家测绘局制订的地理信息系统的坐标系统. 由 ...
- Git 查看修改历史
# 查看某个文件的 commit 历史日志 1. git log filename # 查看每次提交的diff 2. git log -p filename # git show abe69804bb ...
- 一文速通Python并行计算:06 Python多线程编程-基于队列进行通信
一文速通 Python 并行计算:06 Python 多线程编程-基于队列进行通信 摘要: 队列是一种线性数据结构,支持先进先出(FIFO)操作,常用于解耦生产者和消费者.慢速生产-快速消费场景中,队 ...
- Ruby+Appium+testunit实现app自动化demo
1.安装对应库 gem install test-unit gem install appium_lib 2.编写代码 代码如下: require 'appium_lib' require 'test ...
- Spring 的 resolveBeforeInstantiation 方法作用详解
一.定义 resolveBeforeInstantiation 是 Spring 框架中 AbstractAutowireCapableBeanFactory 类的核心方法之一,它在 Bean 的实例 ...
- 关于while循环与for循环
首先看for循环 def test(): print('1') print('2') for i in range(3): test() 执行后的结果,按照下图所示,for循环就是把指定的函数重复执行 ...
- fiddler抓包常用辅助工具
一.过滤器 1.hosts: 只展示内网或外网的hosts,internet(外网),Intranet(内网) 展示下面的hosts/隐藏下面的hosts/:选择后填写需要设置的hosts(地址前面的 ...
- Windows上,10分钟构建一个本地知识库
这篇文章是我约新书<RAG应用实战>的一个样章,基于阿里云代码构建的一个本地RAG服务. 本地模型看代码注释,需要替换几行代码. 阅读本章时,已默认安装你的个人电脑上安装了Python 3 ...
- Typora——锚点
意思就是只能跳到标题(单击时可能需要按Ctrl),即# 开头的字段,格式很简单,例如对于一个二级标题,单击(按住Ctrl)"我想跳转",可以跳到"跳 到 这 里" ...