java运行期优化
1.虚拟机发现某个方法或代码块运行的特别频繁,会把它认为是“热点代码”,为了提升执行效率,把热点代码编译成平台相关的机器码
JIT编译器
2.即时编译器:
1.解释器和编译器
需要迅速启动和执行的时候,解释器先发挥作用。时间久了,为了执行效率,编译器发挥作用
HotSpot虚拟机2个即时编译器 Client Compiler和Server Compiler(C1编译器,C2编译器)
虚拟机默认采用解释器与其中一个编译器配合。(取决于虚拟机的运行模式) 混合模式
可用参数-client -server强制指定虚拟机运行在Client模式还是Server模式
可用-Xint强制用解释模式。
-Xcomp强制用编译模式:有限用编译模式,在编译无法进行时还要用解释器
为了在启动响应速度和运行效率间平衡,采用分层编译:(Client Compiler:获取编译速度 和Server Compiler 获取编译质量 同时工作)
第0层:解释执行,解释器不开启性能监控
第1层:C1编译,字节码便以为本地代码,进行简单可靠的优化
第2层:C2编译,进行一些耗时较长的优化,甚至不可靠的激进优化
2.编译对象与触发条件:编译发生在方法执行过程中,也叫栈上替换
多次调用的方法
多次执行的循环体
判断是不是热点代码:
热点探测:
基于采样的热点探测:若发现某方法经常出现在栈顶,就是热点方法
基于计数器的热点探测:为每个方法建立计数器,统计执行次数。超过阈值就是热点代码,更精确严谨
基于计数器的热点探测:
方法调用计数器:Client模式1500次,Server模式10000次 可通过-XX:CompileThreshold人工设定,编译完成后,方法的调用入口地址就被系统自动改写成新的地址
不是方法调用的绝对次数,是一个相对的执行频率。一段时间内方法被调用的次数
超过一定时间限度(半衰周期),调用次数任然不足 计数器就减半:热度衰减 -XX:-UseCounterDecay关闭热度衰减
-XX:CounterHalfLifeTime:设置半衰周期
回边计数器(字节码中遇到控制流向后跳转的指令就叫回边):统计一个方法中循环体代码执行的次数
-XX:OnStackReplacePercentage间接设置回边计数器阈值 没有热度衰减
3.编译过程:后台编译
对于Client Compiler来说是一个简单快速的三段式编译器
第一阶段:一个平台独立的前端将字节码构成一种高级中间代码
第二阶段:一个平台相关的后端从HIR中产生低级中间代码
第三阶段:平台相关的后端使用线性扫描算法
Server Compiler:代码质量有所提高,减少本地代码执行时间。抵消编译时间开销
4.查看分析即时编译结果:
-XX:+PrintCompilation 要求虚拟机在即时编译时将被编译的本地代码方法名打出来
-XX:+PrintInlining 要求虚拟机输出方法内联信息
3.编译器优化:
方法内联:去除方法的调用成本(建立栈帧等),为其他优化建立良好基础(便于在更大范围进行后续优化)
冗余访问消除:y=a.value z=b.value --->z=y
复写传播
无用代码消除
公共子表达式消除:
表达式E倍计算过,且E中变量值未变,就没必要再计算E,直接用前面计算过的表达式结果代替E
数组便捷检查消除:
只要在编译器根据数据流分析确定数组的长度,判断下标有没有越界
方法内联:
目标方法代码复制到发起调用的方法中,避免真实的方法调用
静态方法,私有方法,实例构造器,父类方法直接内联
若遇到虚方法:想CHA查询次方法在当前程序下是否有多个版本选择
逃逸分析:
分析对象动态作用域:若能证明一个对象不会逃逸到方法或线程之外,别的方法 线程无法通过任何途径访问这个对象
1.栈上分配:对象在栈上分配内存:占用的空间就随着栈帧出栈而销毁
2.同步消除:不会逃逸到其他方法,线程,就不会有竞争。
3.标量替换:原始数据类型,不能再进一步分解。
对象称为聚合量:将访问对象的成员变量恢复为原始类型来访问就叫标量替换
判断一个对象是否逃逸,是一个相对耗时的过程,即时Server Compiler,也默认不开启
-XX:+DoEscapeAnalysis手动开启
模拟java程序oom
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
使用Netty模拟发生OOM
我们模拟这么一个场景,客户端和服务端都使用Netty进行通信,客户端无限循环地向服务端发送数据,过了一会客户端就会出现OOM
Netty OOM 客户端 服务端 数据 -
Netty模拟OOM-Metaspace
在模拟OOM之前, 先简单说下Netty服务端向客户端发送数据的时候, 涉及两个存储数据的地方, 如下图所示业务线程在向客户端发送数据的时候, 是不能直接把数据发送到网络的, 只有IO线程才可以把数据发送到网络, 因此业务线程只能把数据封装成一个任务放到与IO线程关联的一个Queue中, 之后IO线程会从Queue中取出任务, 执行写操作, 将数据写到网络. 因此这个Queue就是存储数据的第一个地方.在之前的文章中,介绍过 使用Netty模拟发生OOM , 那里说的OOM是指java.lang.Ou
Netty OOM Metaspace java netty -
Android 模拟OOM Android 模拟位置
虚拟位置大师,在地图上虚拟GPS位置。 它让你在地图上模拟任意的位置,并分享地图照片给好朋友,从而伪造出在另一个地方的假象。 虚拟位置大师是一款模仿虚拟及修改GPS将手机的地理位置伪装到你想定位的全世界各个地方。
android 模拟 input android手机模拟定位软件 地理位置 微信 辅助工具