`
chriszeng87
  • 浏览: 738626 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java内存对象的逃逸分析

    博客分类:
  • Java
阅读更多

    逃逸分析英文作Escape Analysis。在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。
    当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。
    在Java中比如下面的方法:
......
static V global_v;
public void a_method(){
   V v=b_method();
   c_method();
}
public V b_method(){
   V v=new V();
   return v;
}
public void c_method(){
   global_v=new V();
}
    其中b_method方法内部生成的V对象的引用被返回给a_method方法内的变量v,c_method方法内生成的V对象被赋给了全局变量global_v。这两种场景都发生了指针(引用)逃逸。
    逃逸分析研究对于Java编译器有什么好处?我们知道Java对象总是在堆中分配的,因此Java对象的创建和回收对系统的开销是很大的。Java语言被批评的一个地方,也是认为Java性能慢的一个原因就是Java不支持运行时栈分配对象,缺少像C#里面的值对象或者C++里面的struct结构。
    前面一篇文章《Java并发编程-常量对象(七)》就曾讨论过这个问题,这是Swing内存和性能消耗的瓶颈。近几年业界曾进行过激烈讨论,Java 6中是否应该加入栈分配对象。其中有人主张可以通过JIT进行逃逸分析的方式来解决目前的问题,不用在语言级别进行支持,虚拟机支持栈分配机制,由JIT对代码进行内联优化和逃逸分析。
    那么JIT怎么通过逃逸分析进行代码优化呢?分析下面的过程代码:
public void my_method(){
    V v=new V();
    //use v
    ......
    v=null;
}
    在这个方法中创建的局部对象被赋给了v,但是没有返回,没有赋给全局变量等等操作,因此这个对象是没有逃逸的,是可以在运行时栈进行分配和销毁的对象。没有发生逃逸的对象由于生命周期都在一个方法体内,因此它们是可以在运行时栈上分配并销毁。
    这样在JIT编译Java伪代码时,如果能分析出这种代码,那么非逃逸对象其创建和回收就可以在栈上进行,从而能大大提高Java的运行性能。
    另外为什么要在逃逸分析之前进行内联分析呢?这是因为往往有些对象在被调用过程中创建并返回给调用过程,调用过程使用完该对象就销毁了。这种情况下如果将这些方法进行内联,它们就由两个方法体变成一个方法体了,这种原来通过返回传递的对象就变成了方法内的局部对象,就变成了非逃逸对象了,这样这些对象就可以在同一栈上进行分配了。
    据说Java 6的虚拟机已经支持对象的栈分配和逃逸分析机制了,但目前并没有启动。具可靠的消息,Java 7中将启动这一功能。这对Swing来说又是一次大规模提升速度的机会。
    除能将堆分配对象变成栈分配对象,逃逸分析还有其他两个优化应用。一是同步消除。我们知道线程同步的代价是相当高的,同步的后果是降低并发性和性能。逃逸分析可以判断出某个对象是否始终只被一个线程访问,如果只被一个线程访问,那么对该对象的同步操作就可以转化成没有同步保护的操作,这样就能大大提高并发程度和性能。
    二是矢量替代。逃逸分析方法如果发现对象的内存存储结构不需要连续进行的话,就可以将对象的部分甚至全部都保存在CPU寄存器内,这样能大大提高访问速度。
    Java 7将完全支持了栈式分配对象,JIT将支持逃逸分析优化,另外Java 7还将缺省支持OpenGL的加速功能,光这三种平台性能的提升就会给Swing带来又一次性能的革命。

分享到:
评论

相关推荐

    深入了解java中的逃逸分析

    Java 中的逃逸分析是一种优化技术,通过分析对象的作用域和生命周期,来决定是否对对象进行栈上分配、标量替换、锁消除等优化。下面将深入了解 Java 中的逃逸分析,包括逃逸分析的原理、逃逸分析的优化、逃逸分析的...

    一种基于逃逸分析的对象生命期分析方法.pdf

    1. 提出一种新的基于逃逸分析的对象生命周期分析方法,该方法通过结合连接图和属性传播算法,能准确识别对象是否逃逸并分析对象的生命周期。 2. 设计了一个基于连接图的增量式过程间属性传播算法,该算法可以帮助在...

    面试中遇到的java逃逸分析问题

    Java逃逸分析是一种关键的虚拟机优化技术,它主要用于分析新创建对象的使用范围,以决定是否可以在栈上分配内存,从而提升程序性能。在Java Hotspot虚拟机中,逃逸分析可以从对象创建到使用的整个过程中,判断对象...

    深入Java核心_Java内存分配原理精讲

    使用栈上分配(逃逸分析)来提升效率;理解和避免内存泄漏;理解垃圾回收机制,如可达性分析算法和标记清除、复制、标记-整理、分代收集等策略,以减少垃圾回收带来的系统停顿。 此外,Java内存模型(JMM)也非常...

    深入JVM系列-逃逸分析、同步省略、栈上分配、标量替换1

    逃逸分析(Escape Analysis)是Java虚拟机中的一个重要优化技术,它通过对程序进行跨函数全局的数据流分析,判断一个新创建的对象是否会被外部方法或者外部线程访问。如果分析结果显示对象不会逃逸出当前作用域,JVM...

    简述Java编程语言中的逃逸分析

    通过逃逸分析,Java Hotspot 编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。 2. 逃逸分析的作用 逃逸分析可以减少 Java 程序中的同步负载和内存堆分配压力,提高程序的性能和...

    java中jvm逃逸问题分析

    JVM 逃逸分析(Escape Analysis)是一种可以有效减少 Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,Java Hotspot 编译器能够分析出一个新的对象的引用的使用范围,从而决定是否...

    java内存动态编译执行

    方法内联可以减少调用开销,逃逸分析用于判断对象是否需要在堆上分配,标量替换则是将对象拆解成其字段并直接在栈上处理,减少内存访问。 5. **元空间(Metaspace)**: 在Java 8及之后版本,原先的永久代...

    深入java内存模型

    6. **编译器优化与内存模型**:探讨JIT(Just-In-Time)编译器的工作原理,以及它如何影响内存模型,包括逃逸分析、标量替换等优化技术。 7. **内存屏障与 volatile**:讲解内存屏障在多线程通信中的作用,以及...

    java面向对象之JVM创建及分配策略方法详解.docx

    - **内存分配**:对象主要在堆内存中分配空间,对于逃逸分析技术的应用,部分对象可能在栈上分配。 - **初始化成员变量**:为对象的成员变量赋予默认值(如0或null)。 - **设置对象头部信息**:包括指向类型信息...

    java内存分配 .pdf

    虽然Java虚拟机规范指出所有的对象实例都应该在堆上分配,但随着JIT编译器技术和逃逸分析技术的进步,部分对象可以在栈上分配或者进行标量替换优化。Java堆可以进一步细分为新生代和老年代,其中新生代又包含Eden...

    编译时对象回收中的Java库分析研究.pdf

    本文提出了一种改进Java库方法调用分析策略,该策略使用指向逃逸图来描述库方法对堆中对象的影响,并将堆变化模式应用于Java程序的对象生命周期分析中。实验结果表明,该策略可以提高编译时对象回收的精确性,并且...

    Java中对象都是分配在堆上吗?你错了!

    通过逃逸分析,Java Hotspot 编译器能够分析出一个新的对象的引用的使用范围,从而决定是否要将这个对象分配到堆上。在 Java SE 6u23 及其以后的版本中支持并默认开启了逃逸分析的选项。 逃逸分析的定义是指分析...

    笔记,1、虚拟机的前世今生和java内存区域1

    对象分配一般发生在堆上,但通过逃逸分析和标量替换技术,某些对象可能直接在栈上分配,以减少垃圾回收的压力。 总之,理解JVM的内存区域和管理机制对于优化Java应用程序性能至关重要。开发者应熟悉这些概念,以便...

    Java中的逃逸问题心得

    逃逸分析是一种用于分析对象生命周期和引用范围的技术,由Java Hotspot JIT编译器执行。这项技术在Java SE 6u23及后续版本中被默认启用,目的是减轻程序中的同步负担和减少堆内存分配。 逃逸分析的主要目标是确定一...

    Java Object原理图

    8. 性能优化:JVM提供了诸如逃逸分析、标量替换等技术来进一步优化对象的创建和使用,减少不必要的内存开销,提升运行效率。 9. 内存模型:Java内存模型(Java Memory Model, JMM)定义了线程如何共享和访问内存,...

    java程序中的内存分配问题javalearnsa资料分享

    如果对象很小,且能被快速构造和销毁,可能会使用栈分配(逃逸分析)。 - 对象的实例字段数据在堆中分配,引用类型的数据(如对象的引用)也会在堆中分配。 - 如果两个线程同时创建同类型的对象,它们会在各自的...

    Java基础:减少对象的创建提高java性能

    6. 利用编译器优化:现代的Java编译器(如JIT)会进行一些运行时优化,如逃逸分析,识别出某些对象不会逃逸出当前作用域,从而避免不必要的对象创建。 总的来说,减少对象创建是Java性能优化的重要策略,但这需要在...

Global site tag (gtag.js) - Google Analytics