JVM内存分配-逃逸分析、碰撞指针和TLAB详解(2)
2023-04-29 来源:飞速影视
第一个问题:已用区域会随着垃圾收集,出现大量的碎片,造成内存不连续。解决的思路是建立一个FreeList,把释放的区域加入到FreeList中,下次分配对象的时候,优先从 FreeList 中寻找合适的内存大小进行分配,之后再在主内存中撞针分配。
第二个问题:如何解决并发。通过CAS更新,失败了就重试。
3.TLAB
上面我们分析了如果没有发生逃逸,对象直接在栈上分配,没有并发问题。否则在堆中分配,多线程下有并发问题,方式时通过加锁、指针碰撞。加锁肯定性能不高。那么指针碰撞,在多线程下频繁的创建对象,CAS频繁的重试更新,性能也不高。
现在一般采用TLAB。通过TLAB(Thread Local Allocation Buffer),是在Hotspot1.6引入的新技术。在线程启动时,在堆的Eden区域申请一块指定大小的内存,线程私有,如果线程内需要创建对象,则在此区域内创建,避免并发,提升性能。包含start、top(归属线程最后一次申请的尾位置)、end。如下图所示:
TLAB由于是线程私有,所以就避免了并发,性能很高。
3.1 TLAB分配方式
首先都会检查是否启用了 TLAB,如果启用了,则会尝试 TLAB 分配;如果当前线程的 TLAB 大小足够,那么从线程当前的 TLAB 中分配;如果不够,但是当前 TLAB 剩余空间小于最大浪费空间限制(这是一个动态的值,我们后面会详细分析),则从堆上(一般是 Eden 区) 重新申请一个新的 TLAB 进行分配。否则,直接在 TLAB 外进行分配。TLAB 外的分配策略,不同的 GC 算法不同。例如G1:
如果是 Humongous 对象(对象在超过 Region 一半大小的时候),直接在 Humongous 区域分配(老年代的连续区域)。
根据 Mutator 状况在当前分配下标的 Region 内分配。
本站仅为学习交流之用,所有视频和图片均来自互联网收集而来,版权归原创者所有,本网站只提供web页面服务,并不提供资源存储,也不参与录制、上传
若本站收录的节目无意侵犯了贵司版权,请发邮件(我们会在3个工作日内删除侵权内容,谢谢。)
www.fs94.org-飞速影视 粤ICP备74369512号