Java 的逃逸分析

1. 定义

逃逸分析(Escape Analysis)是 JVM 的一种优化技术,用于分析对象的作用域,从而决定对象的分配方式或优化手段。

主要目的是判断一个对象是否会逃离当前方法或线程的作用域。


2. 逃逸分析的类型

2.1 方法逃逸

  • 如果对象被方法外的代码引用,则该对象发生方法逃逸。

  • 示例:

    public class EscapeExample {
    private Object obj;
    public void methodEscape() {
    obj = new Object(); // 对象逃逸到当前方法外
    }
    }

2.2 线程逃逸

  • 如果对象被当前线程以外的代码引用,则该对象发生线程逃逸。

  • 示例:

    public void threadEscape() {
    new Thread(() -> {
    System.out.println(new Object()); // 对象逃逸到其他线程
    }).start();
    }

3. 逃逸分析的优化方式

3.1 栈上分配

  • 如果一个对象没有发生逃逸,则可以将该对象分配在栈上而不是堆上。

  • 优点:

    • 减少堆内存分配,降低垃圾回收(GC)的压力。
  • 示例:

    public void stackAllocation() {
    Object obj = new Object(); // 不逃逸,分配在栈上
    System.out.println(obj);
    }

3.2 标量替换

  • 如果对象没有逃逸,JVM 可以将对象拆解为基本数据类型或成员变量,避免创建完整的对象。
  • 示例:
public void scalarReplacement() {
Point point = new Point(1, 2); // 不需要创建完整的 Point 对象
int x = point.x; // JVM 可以只分配 x 和 y
int y = point.y;
}

3.3 同步消除

  • 如果某个对象没有线程逃逸,则 JVM 可以优化掉其上的同步块。
  • 示例:
public void synchronizationElimination() {
Object lock = new Object(); // 没有线程逃逸
synchronized (lock) {
System.out.println("No thread escape!");
}
}

4. 逃逸分析的局限性

  • 复杂代码场景:对于复杂的代码路径,逃逸分析可能无法精确判断对象的作用域。
  • JVM 实现依赖:逃逸分析是特定 JVM(如 HotSpot)中的优化特性,不同 JVM 的实现可能有所不同。
  • 对性能的影响:逃逸分析虽然能优化性能,但其计算本身也需要消耗资源。

5. 如何启用逃逸分析

在 HotSpot JVM 中,可以通过以下 JVM 参数启用逃逸分析(默认开启):

-XX:+DoEscapeAnalysis
  • 禁用逃逸分析:
-XX:-DoEscapeAnalysis
  • 查看逃逸分析优化的效果(如标量替换和同步消除):
-XX:+PrintGCDetails -XX:+PrintCompilation

6. 逃逸分析的示例

以下是一个演示逃逸分析优化的代码示例:

public class EscapeAnalysisTest {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1_000_000_000; i++) {
allocate();
}
long end = System.currentTimeMillis();
System.out.println("Execution Time: " + (end - start) + " ms");
} private static void allocate() {
Point point = new Point(1, 2); // 对象未逃逸,可分配在栈上
}
} class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}

7. 总结

  • 逃逸分析 是一种静态分析技术,用于判断对象是否逃离当前方法或线程的作用域。
  • 主要优化:
    • 栈上分配:减少堆分配和 GC 压力。
    • 标量替换:避免创建完整对象。
    • 同步消除:优化掉不必要的同步块。
  • 启用方式:通过 -XX:+DoEscapeAnalysis 启用。
  • 注意事项:逃逸分析的效果依赖于 JVM 的实现,可能对复杂代码场景表现有限。

你了解 Java 的逃逸分析吗?的更多相关文章

  1. 深入理解Java中的逃逸分析

    在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译是把.class转换成机器指令的过程. ...

  2. Java之JVM逃逸分析

    引言: 逃逸分析(Escape Analysis)是众多JVM技术中的一个使用不多的技术点,本文将通过一个实例来分析其使用场景. 概念 逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配 ...

  3. java中的逃逸分析

    逃逸分析 public static StringBuffer craeteStringBuffer(String s1, String s2) { StringBuffer sb = new Str ...

  4. 面试问我 Java 逃逸分析,瞬间被秒杀了。。

    记得几年前有一次栈长去面试,问到了这么一个问题: Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在考什么知识点,难道对象不是在堆中分配 ...

  5. Java逃逸分析

    Java逃逸分析 记录下看到的别人的博客内容,以后深入了解再详细写篇,加深下基础概念和印象! 一般来说,Java对象的创建,通常是在堆空间中分配内存,但是如果大量的临时对象也在堆空间创建的话,会导致性 ...

  6. [转]Java 逃逸分析

    作者:栈长  公众号:Java技术栈 记得几年前有一次栈长去面试,问到了这么一个问题:Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在 ...

  7. 面试官:Java中对象都存放在堆中吗?你知道逃逸分析?

    面试官:Java虚拟机的内存分为哪几个区域? 我(微笑着):程序计数器.虚拟机栈.本地方法栈.堆.方法区 面试官:对象一般存放在哪个区域? 我:堆. 面试官:对象都存放在堆中吗? 我:是的. 面试官: ...

  8. java虚拟机的逃逸分析

    逃逸分析作为其他优化手段提供依据的分析技术,其基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他方法中,称为方法逃逸.甚至还有可能被外部线程 ...

  9. JVM中启用逃逸分析

    -XX:+DoEscapeAnalysis 逃逸分析优化JVM原理我们知道java对象是在堆里分配的,在调用栈中,只保存了对象的指针.当对象不再使用后,需要依靠GC来遍历引用树并回收内存,如果对象数量 ...

  10. JVM笔记-逃逸分析

    参考: http://www.iteye.com/topic/473355http://blog.sina.com.cn/s/blog_4b6047bc01000avq.html 什么是逃逸分析(Es ...

随机推荐

  1. oracle19.3打补丁

    补丁 36582781 - 数据库发布更新 19.24.0.0.240716 本文档在发布时准确无误.有关数据库版本更新 19.24.0.0.240716 的任何更改和其他信息,请参阅 My Orac ...

  2. AI赋能软件测试:未来已来,你准备好了吗?

    ps:文末有福利领取哦 引言 在数字化转型的浪潮中,软件测试作为保障产品质量的关键环节,正面临着前所未有的挑战. 传统的测试方法已难以满足快速迭代和复杂场景的需求,而人工智能(AI)的引入,则为软件测 ...

  3. Centos7部署DVWA靶场

    Centos7部署DVWA靶场 ​ DVWA 款开源的渗透测试漏洞练习平台,其中内含xs SQL注入. 文件上传.文件包含. CSRF和暴力破解等各个难度的测试环境. 安装httpd及其相关的组件 y ...

  4. Spark异常总结

    1.Spark读写同一张表报错问题Cannot overwrite a path that is also being read from 问题描述:Spark SQL在执行ORC和Parquet格式 ...

  5. MacOS配置Homebrew

    Homebrew笔记 1. 介绍 官网:https://brew.sh/ 对于习惯了使用命令来完成一切的程序员来说,安装软件这种小事,自然是能够用命令解决,就不用图形界面选择.但是在 Linux 中, ...

  6. pagehelper分页查询的一个坑,明明下一页没有数据了却还是返回了数据

    pagehelper分页查询的一个坑,明明下一页没有数据了却还是返回了数据 解决:关闭这该死的合理化,如下配置: pagehelper:# helperDialect: mysql reasonabl ...

  7. 【Unity】投影矩阵和线性深度推导

    [Unity]投影矩阵和线性深度推导 网络上有很多投影矩阵的推导,也有很多声称是基于 Unity 的,但和我的实测都不一致(现在看来是因为这些文章并不全面),此外有一些 Unity 本身的函数我也搞不 ...

  8. wordpress无法显示gitee图床的图片

    wordpress无法显示gitee图床的图片 Question:如题 Solution:是防盗链的问题,gitee官网给出了防盗链的方法,而github貌似没有. Reference:你已经是个成熟 ...

  9. angular项目中修改nz-zorro组件库字体大小

    有时候我们开发时使用到的组件库,可能样式不是符合我们的需求,我试着从谷歌调试工具获取组件的类,给他设置样式,如下我设置tabset的样式 .ant-tabs-nav .ant-tabs-tab { f ...

  10. linux服务器开启BBR

    BBR TCP拥塞控制算法,是 Google 为优化网络传输性能而研发的网络优化协议,尤其是在高延迟.高丢包的网络环境下可以显著提升网络传输效率,改善用户体验.开启 BBR 的主要好处: 提高带宽利用 ...