当前位置:网站首页>jvm之逃逸分析
jvm之逃逸分析
2022-07-30 05:45:00 【zpv2jdfc】
逃逸分析是指分析一个变量的作用域,看这个变量会不会逃逸到方法外,如果不会的话,则可以对这个变量进行一些优化。《深入理解java虚拟机》中是这样说的:
逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,他可能被外部方法所引用,例如作为调用参数传递到其他的方法中,称为方法逃逸。甚至还有可能被外部线程访问到,譬如复制非类变量或可以在其他线程中访问的实例变量,称为线程逃逸。
如果能证明一个对象不会逃逸到方法或线程之外,也就是别的方法或线程无法通过任何途径访问到这个对象,则可能为这个变量进行一些高效的优化。
这里的优化有:栈上分配、同步消除、标量替换。
由于我看的是第二版的书,当时还是jdk1.7,书上说1.7上的hotspot没有实现栈上分配,我好奇现在常用的1.8有没有实现,所以做了个小实验:
public static void main(String[] args) {
Main m =new Main();
long startTime=System.currentTimeMillis();
if(true){
while (true) {
m.fun();
}
}
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);
}
void fun(){
Object o = new Object();
}
上边的代码就是不断循环fun函数,由于fun函数中的变量 o 没有逃逸出方法,如果jdk1.8实现了栈上分配的话,堆空间的内存占用就不会一直增加,自然也不需要gc。实际结果如下图:
可以看出,程序内存占用是在不断上升的,而且也触发了GC,说明jdk1.8也没有实现栈上分配。
那么,标量替换能给效率带来多大的提升呢?
public static void main(String[] args) {
Main m =new Main();
long startTime=System.currentTimeMillis();
for(int i=0;i<1000000;i++) {
m.fun();
}
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);
}
void fun(){
Person p = new Person();
}
class Person{
int a;
int b;
int c;
int d;
}
这段代码反复执行fun函数100万次,我们首先开启逃逸分析和标量替换,结果如下:
5
一共运行了5毫秒。
然后关闭标量替换,结果如下:
[GC (Allocation Failure) [PSYoungGen: 8192K->840K(9216K)] 8192K->848K(19456K), 0.0009078 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 9032K->840K(9216K)] 9040K->848K(19456K), 0.0006650 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 9032K->824K(9216K)] 9040K->832K(19456K), 0.0006836 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 9016K->760K(9216K)] 9024K->768K(19456K), 0.0005237 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
10
程序执行了4次minorGC,这也导致执行时间延长了一倍。
总结:jdk1.8目前也没有实现栈上分配对象;标量替换能节省大量的内存空间。这给我们提了个醒,我们在写代码时,如果不是必要,尽量让变量不逃逸出方法。
边栏推荐
猜你喜欢

昆仑通态屏幕制作(连载2)---基础篇(设定与显示,串口发送)

边境的悍匪—Kaggle—泰坦尼克号生还预测详细教程

【正点原子】sys.c、sys.h位带操作的简单应用

十六、Kotlin进阶学习:协程详细学习。

Nodejs PM2 monitoring and alarm email (2)

边境的悍匪—机器学习实战:第十一章 训练深度神经网络

Flink-stream/batch/OLAP integrated to get Flink engine

DeepLearing4j深度学习之Yolo Tiny实现目标检测

MySQL data types and footprint

Rsync realizes folder or data synchronization between Win systems
随机推荐
Trust anchor for certification path not found.异常解决方法。
HSPF 模型应用
配置MMdetection环境并训练
Use kotlin to extend plugins/dependencies to simplify code (after the latest version 4.0, this plugin has been deprecated, so please choose to learn, mainly to understand.)
建造者模式(Swift 实现)
Knowledge distillation method of target detection
Pytorch(三):可视化工具(Tensorboard、Visdom)
MySQL index optimization and failure scenarios
QT连载1:readyRead()函数,数据分包不完整解决办法
联影医疗一面
Xcode 绑定按钮点击事件
CNN经典模型发展进程
QT串口动态实时显示大量数据波形曲线(五)========“最终完美解决版”
Rsync实现Win系统间的文件夹或数据同步
QT每周技巧(1)~~~~~~~~~运行图标
求职准备知识点
Shardingsphere depots table and configuration example
influxDB运维记录
生产力工具分享——简洁而不简单
边境的悍匪—机器学习实战:第九章 无监督学习任务