JVM-内存逃逸分析

内存逃逸

方法逃逸

  • 概念:一个方法内部创建的对象被外部方法引用(比如将对象作为返回值传递到其它方法中),我们称之为方法逃逸。

线程逃逸

  • 概念:一个线程内部创建的对象被外部线程引用(比如将对象作为返回值传递到其它线程中),我们称之为线程逃逸。

内存逃逸分析:

概念:

  • 通过动态分析对象的作用域,分析某些对象是否存在方法逃逸或线程逃逸,为其它优化手段(如栈上分配、同步消除和标量替换等)提供依据。

作用:

  • 若jvm开启了逃逸分析,JIT会对代码进行如下优化:

栈上分配对象:

  • 若某个对象不存在方法逃逸,那么这个对象就可以直接分配在栈中,之后该对象会随着栈帧出栈(方法执行结束后)而销毁,减轻了gc的压力。

同步消除:

  • 锁消除:若某个对象不存在线程逃逸,那么这个对象的读写就不会存在竞争,所以访问该对象的同步锁就可以被清除掉了。
  • 锁粗化:JVM 针对那些反复在一段代码中对同一对象加锁的情况,将同步锁放在最外层包住这里面的多次同步锁,同时取消内部的同步锁。

标量替换:

  • 标量:基础数据类型(int,char,long等)的变量 和 Reference类型变量(SoftReference等) 不能进行分解,这些不能分解的变量称为标量。
  • 聚合量:若一个对象可以继续分解,那么就称这个对象为聚合量。
  • 若逃逸分析证明一个对象不会逃逸出方法,不会被外部访问,并且这个对象是可以被分解的,那程序在真正执行的时候可能不创建这个对象,而是直接创建这个对象分解后的标量来代替。这样就无需在对对象分配空间了,只在栈上为分解出的变量分配内存即可。

缺点:

  • 逃逸分析是比较耗时的,所以性能未必提升很多,因为其耗时性,采用的算法都是不那么准确但是时间压力相对较小的算法来完成的,这就可能导致效果不稳定。

参数

逃逸分析参数:

  • -XX:+DoEscapeAnalysis
    • 开启逃逸分析,从jdk7开始默认开启。
  • -XX:-DoEscapeAnalysis
    • 关闭逃逸分析
  • -XX:+PrintEscapeAnalysis 
    • 开启逃逸分析后,可通过此参数查看分析结果。

锁消除:

  • -XX:+EliminateLocks
    • 开启锁消除,依赖-XX:+DoEscapeAnalysis参数,jdk8默认开启。
  • -XX:-EliminateLocks 
    • 关闭锁消除

标量替换:

  • -XX:+EliminateAllocations
    • 开启标量替换,依赖-XX:+DoEscapeAnalysis参数,jdk8默认开启。
  • -XX:+PrintEliminateAllocations 
    • 开启标量替换后,查看标量替换情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值