jvm-对象一定创建在堆上吗
结论:不一定,看对象经过了逃逸分析后发现该变量只是用到方法区时,则jvm会自动优化,在栈上创建该对象
逃逸分析
逃逸分析(escape analysis)简单来讲就是:java hotspot虚拟机可以分析新创建对象的使用范围,并决定是否在java堆上分配内存
标量替换
标量替换:jvm通过逃逸分析确定该对象不会被外部访问。那就通过将该对象标量替换分解在栈上分配内存,这样该对象所占用的内存空间就可以随栈帧出栈而销毁,就减轻了垃圾回收的压力
标量:不可被进一步分解的量,而java的基本数据类型就是标量
聚合量:在java中对象就是可以被进一步分解的聚合量
栈上分配
jvm对象分配在堆中,当对象没有被引用时,依靠gc进行回收内存,如果对象数量较多会给gc带来较大压力,也间接影响了应用的性能
为了减少临时对象在堆内分配的数量,jvm通过逃逸分析确定该对象不会被外部访问。那就通过将该对象标量替换分解在栈上分配内存,这样该对象所占用的内存空间就可以随栈帧出栈而销毁,就减轻了垃圾回收的压力
同步消除
同步消除是java虚拟机提供的一种优化技术
通过逃逸分析,可以确定一个对象是否会被其他线程进行访问,如果对象没有出现线程逃逸,那该对象的读写就不会存在资源竞争,不存在资源的竞争,则可以消除对该对象的同步锁。比如方法体内调用StringBuffer
逃逸分析结论:虽然经过逃逸分析可以做标量替换、栈上分配、和锁消除。但是逃逸分析自身也是需要进行一系列复杂的分析的,这其实协商一个相对耗时的过程
如果对象经过层层分析后发现,无法进行逃逸分析优化反而耗时了,因此慎用