JVM学习笔记:逃逸分析的优化手段(猜想随笔)

简介: 逃逸分析:优化的内容只是针对那些未发生逃逸的对象,将对象通过标量替换的手段进行优化了,也就是说将未发生逃逸的对象拆分成了基础数据类型和方法,在栈帧使用栈帧即可管理。
有这样一个问题:对象是在堆中被分配的吗?我想说至少目前是这样的。

现在版本的JVM本身就已经默认开启逃逸分析来优化我们的代码,这种优化的思想有一种错觉是对象在栈上分配了,但其实并不是。实际上对象还是在堆中被分配的,优化的内容只是针对那些未发生逃逸的对象,将对象通过标量替换的手段进行优化了,也就是说将未发生逃逸的对象拆分成了基础数据类型方法,在栈帧使用栈帧即可管理,方法结束后栈帧出栈,“对象”被释放,减少了GC发生的次数,优化了代码。

为了巩固自己的印象,上文提到了这些名词,将在文中逐一介绍:

  1. 逃逸分析
  2. 什么叫未发生逃逸的对象
  3. 如何开启和关闭逃逸分析
  4. 标量替换是什么意思

示例代码

类名为StackAllocation。方法名:alloc,调用之后就new一个StackAllocation对象。main方法循环10000000次调用alloc方法,并且计算花费的时间。

public class StackAllocation {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        for (int i = 0;i < 10000000; i++){
            alloc();
        }

        long end = System.currentTimeMillis();
        System.out.println("花费的时间是:" + (end- start) + "毫秒");

        try {
            TimeUnit.SECONDS.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    public static void alloc(){
        StackAllocation stackAllocation  = new StackAllocation();
    }
}

运行该代码时,添加JVM指令:-XX:-DoEscapeAnalysis(该命令是关闭逃逸分析),执行结果如下:

花费的时间是:75毫秒

那么我们开启逃逸分析:

花费的时间是:4毫秒

逃逸分析

逃逸分析的作用是用来减少Java程序中同步负载和内存堆分配的压力,它的基本行为就是分析对象作用域

未发生逃逸的对象

举个例子:当一个对象在A方法中被定义后,如果该对象仅在A方法中使用,则表示该对象是未发生逃逸的;

public void alloc(){
    Cheng c = new Cheng(); // 该对象c只在alloc方法中使用,未发生逃逸
}

发生逃逸的对象

而以下三种行为是会发生逃逸的:

  1. 为类成员赋值,我们常说的getInstance动作
public class EscapeAnalysis{
    private Cheng c;
    
    public void getInstance{
        this.c == null ? new Cheng():this.c; // 对象作用域已经出了这个方法
    }
}
  1. return语句
public Cheng getCheng(){
    return new Cheng(); // 对象作用域已经出了这个方法
}
  1. 调用return语句或者getInstance拿到已经发生逃逸的对象
public void run(){
    Cheng c = getInstance();
    c.run();
}

如何开启和关闭逃逸分析

开启:-XX:+DoEscapeAnalysis(默认就是开启的)

关闭:-XX:-DoEscapeAnalysis

标量替换是什么意思

标量是指一个无法再分解的数据,基本数据类型满足这个特征。

而类是由成员变量以及方法构成的,所以一般类成员是可以进行拆分,拆分成标量。这个拆有个前提就是满足未逃逸

例子:

private static void alloc() {
    Point point = new Point(1,2);
}
class Point {
    private int x;
    private int y;
}

point满足未逃逸,它将会优化成标量

private static void alloc() {
    int x = 1;
    int y = 2;
}

这种方法+变量的形式,用栈结构即可。

总结

如何理解逃逸分析呢?

第一步:我们要知道JVM放置对象和数组的地方称为GC垃圾回收的主要区域,如果频繁的GC操作是会影响程序性能的,所以目的是要减缓GC操作,这才有了逃逸分析。

第二步:了解逃逸分析做了什么事,它的设想是能不能栈上分配对象,如果可以对象的回收不由GC控制,用完直接出栈即可,满足这个就需要该对象是满足未逃逸的,只有它是未逃逸的前提下,就可以将该对象进行标量替换成标准数据类型和方法,这样的结构用栈帧就足以表示,从而间接的实现了栈上分配,而这里分配并不是将对象在栈上分配了,而是通过标量替换的方式用另一种方式在栈上表示了对象。

第三步:程序变快了的原因,就是通过第二步的方式,在栈中用出栈的方式管理对象的回收问题。

最后:逃逸分析并不成熟。

目录
相关文章
|
2月前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
71 0
|
3月前
|
监控 算法 Java
jvm-48-java 变更导致压测应用性能下降,如何分析定位原因?
【11月更文挑战第17天】当JVM相关变更导致压测应用性能下降时,可通过检查变更内容(如JVM参数、Java版本、代码变更)、收集性能监控数据(使用JVM监控工具、应用性能监控工具、系统资源监控)、分析垃圾回收情况(GC日志分析、内存泄漏检查)、分析线程和锁(线程状态分析、锁竞争分析)及分析代码执行路径(使用代码性能分析工具、代码审查)等步骤来定位和解决问题。
|
2月前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
3月前
|
监控 算法 Java
Java虚拟机垃圾回收机制深度剖析与优化策略####
【10月更文挑战第21天】 本文旨在深入探讨Java虚拟机(JVM)中的垃圾回收机制,揭示其工作原理、常见算法及参数调优技巧。通过案例分析,展示如何根据应用特性调整GC策略,以提升Java应用的性能和稳定性,为开发者提供实战中的优化指南。 ####
58 5
|
3月前
|
监控 Java 开发者
Java虚拟机(JVM)深度优化指南####
本文深入探讨了Java虚拟机(JVM)的工作原理及其性能优化策略,旨在帮助开发者通过理解JVM的内部机制来提升Java应用的运行效率。不同于传统的技术教程,本文采用案例分析与实战技巧相结合的方式,为读者揭示JVM调优的艺术。 ####
86 8
|
3月前
|
存储 IDE Java
实战优化公司线上系统JVM:从基础到高级
【11月更文挑战第28天】Java虚拟机(JVM)是Java语言的核心组件,它使得Java程序能够实现“一次编写,到处运行”的跨平台特性。在现代应用程序中,JVM的性能和稳定性直接影响到系统的整体表现。本文将深入探讨JVM的基础知识、基本特点、定义、发展历史、主要概念、调试工具、内存管理、垃圾回收、性能调优等方面,并提供一个实际的问题demo,使用IntelliJ IDEA工具进行调试演示。
66 0
|
4月前
|
存储 算法 Java
深入理解Java虚拟机(JVM)及其优化策略
【10月更文挑战第10天】深入理解Java虚拟机(JVM)及其优化策略
66 1
|
3月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
632 1
|
2月前
|
存储 Java 程序员
【JVM】——JVM运行机制、类加载机制、内存划分
JVM运行机制,堆栈,程序计数器,元数据区,JVM加载机制,双亲委派模型
|
2月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。