jvm 对象内存分配方式总结

      通常来说关于jvm对于对象的内存分配,只要到堆内分配一般就over了,但是在很多人的博客或者帖子中又说了一些其他的分配,比如栈内分配等等,搞的自己有点眼晕,索性就将jvm内存分配的方式统统查了一遍,然后总体上给缕一下。一来是方便自己,权当读书笔记,二来希望有人能一起讨论下。

      jvm在内存区域中专门划分出一块区域来,用于存储对象的相关数据,这块区域就叫做堆。堆内的对象数据是各个线程所共享的,所以当再堆内创建新的对象时,就要进行锁操作。而众所周知锁操作是比较耗费性能的,因此针对每个线程,jvm给它在堆上分配了一块“自留地”——TLAB。TLAB全称是Thread Local Allocation Buffer,处于堆内存的年轻区,也就是Eden这个区域里。每个线程在创建新的对象时,会首先尝试在自己的TLAB里进行分配,如果成功就返回,失败了再到共享的Eden区里去申请空间。在自己的TLAB区域创建对象失败一般有两个原因:一个是对象太大,第二个是自己的TLAB区剩余空间不够。

      这里就涉及到TLAB区域大小的问题了。通常默认的TLAB区域大小是Eden区域的1%,当然也可以手工进行调整,对应的JVM参数是-XX:TLABWasteTargetPercent。

      jvm在进行了上面的优化之后,发现创建对象还有可以优化的空间。空间在哪里?在于对象的生存周期。大部分所创建的对象都无法逃脱一次GC的,其中很多对象更是在一个线程、乃至一个方法调用结束后就over了。针对那些只在一次方法调用内生存的对象,jvm通过server方式的优化对其分配策略进行了改进。首先server方式的优化是可以进行复杂的逃逸分析,而后jvm根据逃逸分析的结果,将未逃逸的对象,直接在栈内分配内存空间。什么?栈内??没错!!这个分配方式就是栈内分配,当线程结束时,栈空间被收回,对象也就直接被回收了。由于栈的操作非常快,所以这种对于对象的操作也更加快速。那么栈内分配时对象数据放在哪里?这块我还没看到相关资料,我分析栈帧有三个区域,局部变量区、操作数区和剩余区域,所以对象数据应该是放在剩余的区域里,当然这块是猜测。

     以上就是两种额外的jvm内存分配方式。总结起来就是:在server端优化下,如果对象未逃逸,则直接在栈内分配;逃逸之后先尝试在TLAB中分配,失败后再在堆内分配,还失败的话,那么就GC吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值