JVM -- 基于逃逸分析的代码优化技术(详解)

JVM – 基于逃逸分析的代码优化技术(详解)


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

栈上分配

        JIT编译器在编译期间根据逃逸分析的结果,发现如果一个对象并没有逃逸出方法的话,就可能被优化成栈上分配。分配完成后,继续在调用栈内执行,最后线程结束,栈空间被回收,局部变量对象也被回收。这样就无须进行垃圾回收了。
常见的栈上分配的场景
        ✔在逃逸分析中,已经说明了。分别是给成员变量赋值、方法返回值、实例引用传递。

同步省略

        线程同步的代价是相当高的,同步的后果是降低并发性和性能。

        在动态编译同步块的时候,JIT编译器可以借助逃逸分析来判断同步块所使用的锁对象是否只能够被一个线程访问而没有被发布到其他线程。 如果没有,那么JIT编译器在编译这个同步块的时候就会取消对这部分代码的同步。这样就能大大提升并发性和性能。这个取消同步的过程就叫同步省略,也叫做锁消除。

        程序编译成的字节码中会含有同步的指令,但是符合优化要求的会在JIT编译阶段被优化掉。

分离对象或标量替换

        分离对象或分离对象或标量(Scalra) 是指一个无法再分解成更小的数据的数据。Java中的原始数据类型就是标量。

        相对的,那些还可以分解的数据叫做聚合量(Aggregate), Java中的对象就是聚合量,因为他可以分解成其他聚合量和标量。

        在JIT阶段,如果经过逃逸分析,发现一个对象不会被外界访问的话,那么经过JIT优化,就会把这个对象拆解成若干和其中包含的若干个成员变量来代替,这个过程就是标量替换


逃逸分析并不成熟

        逃逸分析技术的论文在1999年发表,但直到JDK 1.6才有实现,这项技术到如今也不是十分成熟。根本原因就是无法保证逃逸分析的性能消耗一定能高于他的消耗。虽然经过逃逸分析可以做标量替换、栈上分配、和锁消除。但是逃逸分析自身也是需要进行一系列复杂的分析的,这其实也是一个相对耗时的过程。
        虽然这项技术不是十分成熟,但是它也是即时编译器优化技术中一个十分重要的技术。

你可能感兴趣的:(JVM,JVM,逃逸分析,代码优化)