Java对象的分配流程有了解过吗?

一、分配流程

  • 分配流程图:

并不是所有对象都分配在堆上,除了(绝⼤多数对象分配到堆上)以外,还有两个地⽅可以存放对象——TLAB

○ 如果开启栈上分配,JVM会先进行栈上分配

○ 如果没有开启栈上分配不符合条件,则会进行TLAB分配

○ 如果TLAB分配不成功且不满足进入老年代的条件,则会在eden区分配

○ 如果对象满足了直接进入老年代的条件,那就直接在老年代分配

二、栈上分配

栈上分配是JVM提供的一项优化技术

基本思想如下所示:

  • 对于那些线程私有的对象(即:不可能被其他线程访问的对象),可以将它们打散分配在栈上,而不是分配在堆上。

  • 分配在栈上的好处是可以在函数调用结束后自行销毁,而不需要垃圾回收器的介入,从而提高系统的性能。

  • 对于大量的零散小对象,栈上分配提供了一种很好的对象分配优化策略,栈上分配速度快,并且可以有效避免GC带来的负面影响,但是由于和堆空间相比,栈空间较小,因此对于大对象无法也不适合在栈上分配

栈上分配的技术基础,两者必须都开启:

  • 逃逸分析:逃逸分析的目的是判断对象的作用域是否有可能逃逸出函数体

  • 标量替换:允许将对象打散分配在栈上。比如:若一个对象拥有两个字段,会将这两个字段视作局部变量进行分配。

注:只能在server模式下才能启用逃逸分析;

  • 参数-XX:+DoEscapeAnalysis启用逃逸分析;

  • 参数-XX:+EliminateAllocations开启标量替换(默认打开)。

三、TLAB

  • TLAB的全称是Thread Local Allocation Buffer,即线程本地分配缓存区,这是一个线程专用的内存分配区域。

  • 由于对象一般会分配在堆上,而堆是全局共享的。因此在同一时间,可能会有多个线程在堆上申请空间。因此,每次对象分配都必须要进行同步(虚拟机采用CAS配上失败重试的方式保证更新操作的原子性),而在竞争激烈的场合分配的效率又会进一步下降。

  • JVM使用TLAB来避免多线程冲突,在给对象分配内存时,每个线程使用自己的TLAB,这样可以避免线程同步,提高了对象分配的效率。

  • TLAB本身占用Eden区空间,在开启TLAB的情况下,虚拟机会为每个Java线程分配一块TLAB空间

  • 参数**-XX:+UseTLAB**开启TLAB,默认是开启的。

  • TLAB空间的内存非常小,缺省情况下仅占有整个Eden空间的1% ,当然可以通过选项-XX:TLABWasteTargetPercent设置TLAB空间所占用Eden空间的百分比大小。

  • 由于TLAB空间一般不会很大,因此大对象无法在TLAB上进行分配,总是会直接分配在堆上。TLAB空间由于比较小,因此很容易装满。

四、逃逸分析

  • 对于线程私有的对象,可以分配在栈上,⽽不是分配在堆上。好处是⽅法执⾏完,对象⾃⾏销毁,不需要gc介⼊。可以提⾼性能。

  • ⽽栈上分配的⼀个技术基础(如果关闭逃逸分析关闭标量替换,那么⽆法将对象分配在栈上)就是逃逸分析。

  • 逃逸分析的⽬的是判断对象的作⽤域是否有可能逃逸出函数体。如下所示:

Student student; 
// 属于逃逸了
public void say1() {  
    student = new Student();
}
public void say2() {  
    Student student = new Student(); // 没有逃逸
}

【注意】

  • 对于say2()⽅法中的new Student(),jvm就有可能将Student分配在栈上,⽽不是堆上。

  • 对于⼤量的零散⼩对象,栈上分配提供了⼀种很好的对象分配优化策略。

  • 对于⼤对象,⽆法也不适合在栈上分配。

五、标量替换

  • 标量不可被进一步分解的量,——JAVA的基本数据类型就是标量(如:int,long等基本数据类型以及reference类型等)

  • 聚合量标量的对立就是可以被进一步分解的量。——JAVA中对象就是可以被进一步分解的聚合量。

  • 替换过程

条件1> 通过逃逸分析确定该对象不会被外部访问。
条件2> 对象可以被进一步分解,即聚合量。JVM不会创建该对象,而会将该对象成员变量 解若干个被这个方法使用的成员变量所代替。这些代替的成员变量在 栈帧寄存器上分配空间。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值