栈分配、逃逸分析与TLAB -JVM( 四 )


1、如果是对象(对象在超过一半大小的时候) , 直接在区域分配(老年代的连续区域) 。
2、根据状况在当前分配下标的内分配
再详细描述解析:
TLAB本身占用eEden区空间 , 在开启TLAB的情况下 , 虚拟机会为每个Java线程分配一块TLAB空间 。参数-XX:+开启TLAB , 默认是开启的 。TLAB空间的内存非常小 , 缺省情况下仅占有整个Eden空间的1% , 当然可以通过选项-XX:nt设置TLAB空间所占用Eden空间的百分比大小 。
由于TLAB空间一般不会很大 , 因此大对象无法在TLAB上进行分配 , 总是会直接分配在堆上 。TLAB空间由于比较小 , 因此很容易装满 。比如 , 一个100K的空间 , 已经使用了80KB , 当需要再分配一个30KB的对象时 , 肯定就无能为力了 。这时虚拟机会有两种选择 , 
第一 , 废弃当前TLAB , 这样就会浪费20KB空间;
第二 , 将这30KB的对象直接分配在堆上 , 保留当前的TLAB , 这样可以希望将来有小于20KB的对象分配请求可以直接使用这块空间 。实际上虚拟机内部会维护一个叫作【最大浪费空间】的值 , 当请求对象大于时 , 会选择在堆中分配 , 若小于该值 , 则会废弃当前TLAB , 新建TLAB来分配对象 。
这个阈值可以使用ion来调整 , 它表示TLAB中允许产生这种浪费的比例 。默认值为64 , 即表示使用约为1/64的TLAB空间作为 。默认情况下 , TLAB和都会在运行时不断调整的 , 使系统的运行状态达到最优 。如果想要禁用自动调整TLAB的大小 , 可以使用-XX:-禁用 , 并使用-XX:手工指定一个TLAB的大小 。
-XX:+可以跟踪TLAB的使用情况 。一般不建议手工修改TLAB相关参数 , 推荐使用虚拟机默认行为
对象内存分配的两种方法
为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来 。
指针碰撞(、等带过程的收集器)
假设Java堆中内存是绝对规整的 , 所有用过的内存都放在一边 , 空闲的内存放在另一边 , 中间放着一个指针作为分界点的指示器 , 那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离 , 这种分配方式称为“指针碰撞”(Bump the ) 。
空闲列表(CMS这种基于Mark-Sweep算法的收集器)
如果Java堆中的内存并不是规整的 , 已使用的内存和空闲的内存相互交错 , 那就没有办法简单地进行指针碰撞了 , 虚拟机就必须维护一个列表 , 记录上哪些内存块是可用的 , 在分配的时候从列表中找到一块足够大的空间划分给对象实例 , 并更新列表上的记录 , 这种分配方式称为“空闲列表”(Free List) 。
TLAB解决的问题
TLAB 要解决的问题很明显 , 尽量避免从堆上直接分配内存从而避免频繁的锁争用 。
详细描述
看到一篇问题 , 对TLAB解析的非常详细:
csdn地址:
具体看这个 。。。
【栈分配、逃逸分析与TLAB -JVM】 原创不易 , 如若本文能够帮助到您的同学 支持我:关注我+点赞+收藏??+留言格言:己所不欲勿施于人 扬帆起航、游历人生、永不言弃!