详解jvm中的标量替换

 更新时间:2020年09月29日 14:36:56   作者:TomCoding  
这篇文章主要介绍了详解jvm中的标量替换,帮助大家更好的理解和使用Java虚拟机,感兴趣的朋友可以了解下

概述

通常在java中创建一个对象,大家都认为是在堆中创建。 在jdk6开始有逃逸分析,标量替换等技术,关于在堆中创建对象不再绝对。

关于标量替换,通过以下几点进行概述:

  1. 逃逸分析
  2. 标量替换是什么
  3. 测试标量替换

逃逸分析

逃逸分析是一种分析技术,分析对象的动态作用域,供其他优化措施提供依据。比如分析一个对象不会逃逸到方法之外或线程之外,其它优化措施(栈上分配,标量替换等)根据逃逸程度进行优化。

逃逸分析示例

public class EscapeAnalysis {
  public Person p;
  /**
   * 发生逃逸,对象被返回到方法作用域以外,被方法外部,线程外部都可以访问
   */
  public void escape(){
    p = new Person(26, "TomCoding escape");
  }

  /**
   * 不会逃逸,对象在方法内部
   */
  public String noEscape(){
    Person person = new Person(26, "TomCoding noEscape");
    return person.name;
  }
}

static class Person {
  public int age;
  public String name;
  
  ... // 省略构造方法
}

标量替换是什么

标量可以理解成一种不可分解的变量,如java内部的基本数据类型、引用类型等。 与之对应的聚合量是可以被拆解的,如对象。
当通过逃逸分析一个对象只会作用于方法内部,虚拟机可以通过使用标量替换来进行优化。
比如上述noEscape()方法中person对象只会在方法内部,通过标量替换技术得到如下伪码:

/**
 * 不会逃逸,对象在方法内部
 */
public String noEscape(){
  int age = 26;
  String name = "TomCoding noEscape";
  return name;
}

测试标量替换

接下来我们通过对noEscape()方法进行测试,主要测试两种场景:

  1. 不使用标量替换
  2. 使用标量替换

以下测试是在jdk8中运行(注jdk8默认是开启逃逸分析,标量替换技术的)

测试代码如下:

void testEliminateAllocationsWithNoEscape() {
  int n = 100000000;
  long start = System.currentTimeMillis();
  EscapeAnalysis escapeAnalysis = new EscapeAnalysis();
  for (int i = 0; i < n; i++) {
    // noEscape()不会发生逃逸
    escapeAnalysis.noEscape();
  }
  System.out.println("耗时:" + (System.currentTimeMillis() - start));
}
  • 不使用标量替换

将jvm参数设置如下:

-Xms5m 最小堆内存5M
-Xmx5m 最大堆内存5M
-XX:+PrintGC  打印gc日志
-XX:-EliminateAllocations 关闭标量替换优化

运行后在我本机的耗时:3006毫秒,gc发生2000多次。

  • 使用标量替换

将jvm参数设置如下:

-Xms5m 最小堆内存5M
-Xmx5m 最大堆内存5M
-XX:+PrintGC  打印gc日志
-XX:+EliminateAllocations 关闭标量替换优化

运行后在我本机的耗时:20毫秒,gc发生6次。

再来看看发生逃逸的对象使用标量替换效果

测试代码如下:

void testEliminateAllocationsWithEscape() {
  int n = 100000000;
  long start = System.currentTimeMillis();
  EscapeAnalysis escapeAnalysis = new EscapeAnalysis();
  for (int i = 0; i < n; i++) {
    // escape()发生逃逸
    escapeAnalysis.escape();
  }
  System.out.println("耗时:" + (System.currentTimeMillis() - start));
}

将jvm参数设置如下:

-Xms5m 最小堆内存5M
-Xmx5m 最大堆内存5M
-XX:+PrintGC  打印gc日志
-XX:+EliminateAllocations 关闭标量替换优化

运行后在我本机的耗时:3705毫秒,gc发生2000多次。

总结

  1. 可以看到通过逃逸分析与标量替换技术有效的减少了gc次数(减少了对象在堆中创建的数量)。
  2. 实际编码过程中避免对象逃逸情况是一种理想的情况。可以形成一种编码意识,尽量去减少对象逃逸。

思考

标量替换只是利用逃逸分析其中的一种优化措施, 还有其它优化措施吗?

以上就是详解jvm中的标量替换的详细内容,更多关于jvm 标量替换的资料请关注脚本之家其它相关文章!

相关文章

  • SpringBoot的服务注册与发现示例

    SpringBoot的服务注册与发现示例

    本篇文章主要介绍了SpringBoot的服务注册与发现示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Java对文件进行基本操作案例讲解

    Java对文件进行基本操作案例讲解

    这篇文章主要介绍了Java对文件进行基本操作案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是本文的详细内容,需要的朋友可以参考下
    2021-07-07
  • 滥用@PathVariable导致bug原因分析解决

    滥用@PathVariable导致bug原因分析解决

    这篇文章主要为大家介绍了滥用@PathVariable导致bug原因分析解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 解决java 分割字符串成数组时,小圆点不能直接进行分割的问题

    解决java 分割字符串成数组时,小圆点不能直接进行分割的问题

    这篇文章主要介绍了解决java 分割字符串成数组时,小圆点不能直接进行分割的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Java中超高频常见字符操作合集(建议收藏)

    Java中超高频常见字符操作合集(建议收藏)

    这篇文章主要为大家详细介绍了Java中超高频常见字符操作合集,文中的示例代码讲解详细,对我们学习java有一定的帮助,需要的小伙伴可以参考下
    2023-10-10
  • SpringBoot之@Aspect注解解读

    SpringBoot之@Aspect注解解读

    这篇文章主要介绍了SpringBoot之@Aspect注解解读,AOP是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,而@Aspect 就是把一个类定义为切面供容器读取,需要的朋友可以参考下
    2024-01-01
  • 一文秒懂IDEA中每天都在用的Project Structure知识

    一文秒懂IDEA中每天都在用的Project Structure知识

    这篇文章主要介绍了一文秒懂IDEA中每天都在用的Project Structure知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 完美解决IDEA Ctrl+Shift+f快捷键突然无效的问题

    完美解决IDEA Ctrl+Shift+f快捷键突然无效的问题

    这篇文章主要介绍了完美解决IDEA Ctrl+Shift+f快捷键突然无效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 理解Java中的静态绑定和动态绑定

    理解Java中的静态绑定和动态绑定

    这篇文章主要帮助大家理解Java中的静态绑定和动态绑定,在Java中存在两种绑定方式,一种为静态绑定,另一种就是动态绑定,亦称为后期绑定,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • SpringBoot中@ComponentScan注解过滤排除不加载某个类的3种方法

    SpringBoot中@ComponentScan注解过滤排除不加载某个类的3种方法

    这篇文章主要给大家介绍了关于SpringBoot中@ComponentScan注解过滤排除不加载某个类的3种方法,文中通过实例代码介绍的非常详细,对大家学习或者使用SpringBoot具有一定的参考学习价值,需要的朋友可以参考下
    2023-07-07

最新评论