有理想的“程序猿”应该知道基于“逃逸分析的栈上分配优化”

什么是栈上分配?

栈上分配是Java虚拟机提供的一种优化技术。指的是那些线程私有的、不可被其它线程访问的对象,将他们分配在栈上,而不是堆上。这样的对象就能随着栈的销毁而销毁,不需要垃圾收集,从而提高性能。

如何进行栈上分配?

栈上分配技术基础是逃逸分析,逃逸分析的作用是判断作用域是否可能逃逸出函数体。

有理想的“程序猿”应该知道基于“逃逸分析的栈上分配优化”

上面代码中包含两个函数,test1中包含成员变量user,该成员变量可能被其它任何线程访问,所以属于逃逸对象。test2中的user以局部变量形式存在,并且没有被返回或者任何形式的公开,因此属于非逃逸对象,这样的对象虚拟机会很有可能将其分配在栈上。

如何证明进行了栈上分配?

  • 上面代码加入测试环节,分别运行test1、test2函数1亿次,这样累计创建的User实例所需内存将超过1G。当我们设置堆内存小于该值,如果没有进行栈上分配,必定会频繁进行GC。
有理想的“程序猿”应该知道基于“逃逸分析的栈上分配优化”

  • 设置JVM参数如下:-server -Xmx10m -Xms10m -XX:+PrintGC -XX:+DoEscapeAnalysis -XX:-UseTLAB -XX:+EliminateAllocations
有理想的“程序猿”应该知道基于“逃逸分析的栈上分配优化”

-server(Server模式才能进行逃逸分析)

-Xmx10m(堆最大空间10m)

-Xms10m(堆初始空间10m)

-XX:+PrintGC(打印GC日志)

-XX:+DoEscapeAnalysis(开启逃逸分析)

-XX:-UseTLAB(关闭TLAB)

-XX:+EliminateAllocations(开启标量替换,允许将对象打散分配在栈上。比如User对象有两个属性name、age,那么将这两个属性当作两个独立的局部变量分配在栈上)

  • 运行test1函数结果如下
有理想的“程序猿”应该知道基于“逃逸分析的栈上分配优化”

  • 运行test2函数结果如下
有理想的“程序猿”应该知道基于“逃逸分析的栈上分配优化”

  • 从结果可看到,test1函数需要频繁GC,test2函数由于进行了栈上分配,只进行了3次GC
有理想的“程序猿”应该知道基于“逃逸分析的栈上分配优化”


分享到:


相關文章: