首页 > 其他分享 >逃逸分析(Escape Analysis)详解

逃逸分析(Escape Analysis)详解

时间:2022-09-19 18:22:53浏览次数:69  
标签:分析 逃逸 point 对象 Analysis XX 详解 线程 Escape

概念说明

    逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。逃逸分析的基本行为就是分析对象动态作用域。

 

逃逸类型

  方法逃逸(对象逃出当前方法)

      当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中。

  线程逃逸((对象逃出当前线程)

      这个对象甚至可能被其它线程访问到,例如赋值给类变量或可以在其它线程中访问的实例变量。

 

使用逃逸分析

  编译器可以对代码做如下优化:

    1. 同步省略或锁消除(Synchronization Elimination)。如果一个对象被发现只能从一个线程被访问到,那么对于这个对象的操作可以不考虑同步。
    2. 将堆分配转化为栈分配(Stack Allocation)。如果一个对象在子程序中被分配,要使指向该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配。
    3. 分离对象或标量替换(Scalar Replacement)。有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分(或全部)可以不存储在内存,而是存储在CPU寄存器中。

  jdk6才开始引入该技术,jdk7开始默认开启逃逸分析。在Java代码运行时,可以通过JVM参数指 定是否开启逃逸分析:

‐XX:+DoEscapeAnalysis //表示开启逃逸分析 (jdk1.8默认开启)
‐XX:‐DoEscapeAnalysis //表示关闭逃逸分析。
‐XX:+EliminateAllocations //开启标量替换(默认打开)
‐XX:+EliminateLocks //开启锁消除(jdk1.8默认开启)

 

  验证理论:

    验证代码展示

/**
 * 进行两种测试
 * 关闭逃逸分析,同时调大堆空间,避免堆内GC的发生,如果有GC信息将会被打印出来
 * VM运行参数:-Xmx4G -Xms4G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 *
 * 开启逃逸分析  jdk8默认开启
 * VM运行参数:-Xmx4G -Xms4G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 *
 * 执行main方法后
 * jps 查看进程
 * jmap -histo 进程ID
 *
 */
@Slf4j
public class EscapeTest {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 500000; i++) {
            alloc();
        }
        long end = System.currentTimeMillis();
        log.info("执行时间:" + (end - start) + " ms");
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }


    /**
     * JIT编译时会对代码进行逃逸分析
     * 并不是所有对象存放在堆区,有的一部分存在线程栈空间
     * Ponit没有逃逸
     */
    private static String alloc() {
        Point point = new Point();
        return point.toString();
    }

    /**
     *同步省略(锁消除)  JIT编译阶段优化,JIT经过逃逸分析之后发现无线程安全问题,就会做锁消除
     */
    public void append(String str1, String str2) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(str1).append(str2);
    }

    /**
     * 标量替换
     *
     */
    private static void test2() {
        Point point = new Point(1,2);
        System.out.println("point.x="+point.getX()+"; point.y="+point.getY());

//        int x=1;
//        int y=2;
//        System.out.println("point.x="+x+"; point.y="+y);
    }


}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Point{
    private int x;
    private int y;
}

 

标签:分析,逃逸,point,对象,Analysis,XX,详解,线程,Escape
From: https://www.cnblogs.com/chafry/p/16708477.html

相关文章

  • ps详解
    psman1ps支持的命令格式unix格式:-h-e,短格式bsd格式:a,x,u格式,不加-的格式gnu长格式:--help,长格式[root@iZ2~]#psPIDTTYTIMECMD4234pts/000......
  • 传输层详解-TCP建立断开连接过程、TCP和UDP封装报文格式和应用、TCP中的四种计时器)
    一、传输层的概念网络层提供点到点的连接,传输层提供端到端的连接。在网络通讯的过程中,依靠网络层达到发现对端的目的,在发现对端之后,我们需要精准的找到想要访问的进程/服......
  • TCP/IP协议详解
      TCP/IP不是一个协议,而是一个协议族的统称。里面包括IP协议、IMCP协议、TCP协议。TCP/IP协议模型,包含了一系列构成互联网基础的网络协议,是Internet的核心协议。基于......
  • 哈夫曼编码HuffmanCoding原理详解
    哈夫曼编码(\(Huffman\)\(Coding\))原理详解一、哈夫曼编码简介哈夫曼编码,又称为霍夫曼编码(\(Huffman\)\(Coding\))是一种可变长编码(\(VLC\),\(variable\)\(length\)......
  • SSH隧道:端口转发功能详解
    SSH系列文章:SSH基础:SSH和SSH服务SSH转发代理:ssh-agent用法详解SSH隧道:端口转发功能详解1.1ssh安全隧道(一):本地端口转发如下图,假如host3和host1、host2都同互相通信,但......
  • 详解升讯威在线客服系统前端多国语言实现技术:原生支持葡文、印尼文、土耳其文、俄文
    我在业余时间开发维护了一款免费开源的升讯威在线客服系统,也收获了许多用户。对我来说,只要能获得用户的认可,就是我最大的动力。越来越多的用户向我提出需求,希望为访客端......
  • 第四章 Redis-6.0版本配置文件详解
    一、Units单位#如果要配置跟内存大小相关的参数是可以这样配置,只支持bytes,不支持bit,这些单位都是大小写不敏感的:#1k=>1000bytes#1kb=>1024bytes#1m=>10......
  • 零拷贝详解
    1.什么是零拷贝零拷贝字面上的意思包括两个,“零”和“拷贝”:“拷贝”:就是指数据从一个存储区域转移到另一个存储区域。“零”:表示次数为0,它表示拷贝数据的次数为0。......
  • Java 异步编程 (5 种异步实现方式详解)
    ​ 同步操作如果遇到一个耗时的方法,需要阻塞等待,那么我们有没有办法解决呢?让它异步执行,下面我会详解异步及实现@mikechen目录什么是异步?一、线程异步二、Future......
  • 5G UE接入消息详解
    问题:UE重新注册需要5-6分钟FER:5G学习笔记之UE接入消息详解5G;NG-RAN;NGApplicationProtocol(NGAP)(3GPPTS38.413version15.0.0Release15......