TLAB

TLAB是虚拟机在堆内存的eden划分出来的一块专用空间,是线程专属的。在虚拟机的TLAB功能启动的情况下,在线程初始化时,虚拟机会为每个线程分配一块TLAB空间(包含在 Eden 空间内),只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。

多线程同时分配内存时,使用 TLAB 可以避免一系列的非线程安全问题,同时还能提升内存分配的吞吐量,因此我们可以将这种内存分配方式称为快速分配策略

为什么要有 TLAB :

  • 堆区是线程共享的,任何线程都可以访问到堆区中的共享数据

  • 由于对象实例的创建在 JVM 中非常频繁,因此在并发环境下从堆区中划分内存空间是线程不安全的

  • 为避免多个线程操作同一地址,需要使用加锁等机制,进而影响分配速度

当然了,不是所有的对象实例都能够在 TLAB 中成功分配内存,但 JVM 确实是将 TLAB 作为内存分配的首选。

在程序中,可以通过 -XX:UseTLAB 设置是否开启 TLAB 空间。

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

一旦对象在 TLAB 空间分配内存失败时,JVM 就会尝试着通过使用加锁机制确保数据操作的原子性,从而直接在 Eden 空间中分配内存

逃逸分析技术

对象一定分配在堆中吗?

不一定的,JVM通过「逃逸分析」,那些逃不出方法的对象就会在栈上分配。

栈上分配的条件

  • 作用域不会逃逸出方法的对象

  • 小对象(一般几十个byte);大对象无法在栈上分配

  • 标量替换:若逃逸分析证明一个对象不会逃逸出方法,不会被外部访问,并且这个对象是可以被分解的,那程序在真正执行的时候可能不创建这个对象,而是直接创建这个对象分解后的标量来代替。这样就无需在对对象分配空间了,只在栈上为分解出的变量分配内存即可。

什么是逃逸分析

逃逸分析(Escape Analysis),是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。

通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围,从而决定是否要将这个对象分配到堆上。

  • 一个对象在方法中被定义后,对象如果只在方法内部使用,则认为没有发生逃逸;(没有发生逃逸的对象,会在栈上分配)

  • 当一个对象在方法中被定义后,它被外部方法所引用,则认为发生了逃逸。

如何快速的判断是否发生了逃逸分析?

  • 看new的对象实体是否有可能在方法外被调用。注意是看new 出来的实体,而不是那个引用变量。

通俗点讲,如果一个对象的指针被多个方法或者线程引用时,那么我们就称这个对象的指针发生了逃逸。

逃逸分析的好处

  • 栈上分配,可以降低垃圾收集器运行的频率。

  • 同步消除,如果发现某个对象只能从一个线程可访问,那么在这个对象上的操作不需要同步。

  • 标量替换,把对象分解成一个个基本类型,并且内存分配不再是分配在堆上,而是分配在栈上。这样的好处有

    • 减少内存使用,因为不用生成对象头。

    • 程序内存回收效率高,并且GC频率也会减少。

小结

关于逃逸分析的论文在1999年就已经发表了,但直到JDK 1.6才有实现,而且这项技术到如今也并不是十分成熟的。

其根本原因就是无法保证逃逸分析的性能消耗一定能高于他的消耗。虽然经过逃逸分析可以做标量替换、栈上分配、和锁消除。但是逃逸分析自身也是需要进行一系列复杂的分析的,这其实也是一个相对耗时的过程。

一个极端的例子,就是经过逃逸分析之后,发现没有一个对象是不逃逸的。那这个逃逸分析的过程就白白浪费掉了。

面试题专栏

Java面试题专栏已上线,欢迎访问。

  • 如果你不知道简历怎么写,简历项目不知道怎么包装;
  • 如果简历中有些内容你不知道该不该写上去;
  • 如果有些综合性问题你不知道怎么答;

那么可以私信我,我会尽我所能帮助你。

对象一定分配在堆中吗?聊聊TLAB和逃逸分析技术的更多相关文章

  1. 面试官:Java中对象都存放在堆中吗?你知道逃逸分析?

    面试官:Java虚拟机的内存分为哪几个区域? 我(微笑着):程序计数器.虚拟机栈.本地方法栈.堆.方法区 面试官:对象一般存放在哪个区域? 我:堆. 面试官:对象都存放在堆中吗? 我:是的. 面试官: ...

  2. (转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?

    转自:http://www.cnblogs.com/xiaoyao2011/archive/2011/09/09/2172427.html 在.NET程序运行过程中,什么是堆,什么是栈? 堆也就是托管 ...

  3. C/C++用new、delete分配回收堆中空间

    int *CreateList() 10 { 11 int a[5]; 12 int *a = new int[5]; 13 delete[] a; 14 15 int a(5); 16 int a ...

  4. 【性能优化】面试官:Java中的对象都是在堆上分配的吗?

    写在前面 从开始学习Java的时候,我们就接触了这样一种观点:Java中的对象是在堆上创建的,对象的引用是放在栈里的,那这个观点就真的是正确的吗?如果是正确的,那么,面试官为啥会问:"Jav ...

  5. new 的对象如何不分配在堆而分配在栈上(方法逃逸等)

    当能够明确对象不会发生逃逸时,就可以对这个对象做一个优化,不将其分配到堆上,而是直接分配到栈上,这样在方法结束时,这个对象就会随着方法的出栈而销毁,这样就可以减少垃圾回收的压力. 如方法逃逸. 逃逸分 ...

  6. 求你了,别再说Java对象都是在堆内存上分配空间的了!

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  7. 别再说Java对象都是在堆内存上分配空间的了!

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  8. JVM知识(一) 求你了,别再说Java对象都是在堆内存上分配空间的了!

    求你了,别再说Java对象都是在堆内存上分配空间的了! https://baijiahao.baidu.com/s?id=1661296872935371634&wfr=spider& ...

  9. Java内存分配之堆、栈和常量池

    Java内存分配主要包括以下几个区域: 1. 寄存器:我们在程序中无法控制 2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 3. 堆:存放用new产生的数据 4. 静 ...

  10. Java内存分配之堆、栈和常量池(转)

    摘录自http://www.cnblogs.com/SaraMoring/p/5687466.html Java内存分配主要包括以下几个区域: 1. 寄存器:我们在程序中无法控制 2. 栈:存放基本类 ...

随机推荐

  1. 8.Java Spring框架源码分析-IOC-调用BeanFactoryPostProcessor的postProcess方法

    目录 1. 要研究的代码 2. 处理BeanDefinitionRegistryPostProcessor类型的PostProcessor 2.1. 当前bean工厂是BeanDefinitionRe ...

  2. Vmware虚拟机中安装CentOS

    安装centos8显示设置基础软件仓出错_jacksky的技术博客_51CTO博客 下载Iso 镜像:https://www.centos.org/download/ 选择第一项,安装直接CentOS ...

  3. Spring Boot 3响应式编程

    1.Stream A.流操作: 背压模式,有则执行,没有则不管 B.操作有哪些? 中间操作: filter.map.distinct.limit.flatmap.sorted.peek.skip 终结 ...

  4. 前端开发系列129-进阶篇之Throttle And Debounce

    本文讨论前端开发中 函数防抖 和 函数节流,它们的应用.区别以及简单实现. 在前端开发中我们可能经常需要给(页面)标签绑定一些持续触发的事件,如 resize.scroll.input.mousemo ...

  5. .net core 过滤器中AuthorizationFilterContext如何获取访问的控制器名称和方法

    public class AuthenFilterAttribute : IAuthorizationFilter { //每个action执行之前都会进入这个方法 public void OnAut ...

  6. WSL初探

    1 简介 WSL( Windows Subsystem for Linux )是微软开发的兼容层,允许在 Windows 10 及更高版本上运行原生Linux二进制文件(如 Ubuntu . Debi ...

  7. Economic-Statistics-Investment-Analysis-: 美国上市公司的财务报表分析: 净利润率 + 市场销售增速 + 股东分红

    将经济政治和科学研究.微观和宏观.理论和实践 联合分析: 对每一类精深的统计研究分析 Systematical Method的研究透任何有兴趣的形成经验和个人能力 行业.组织.决策层.高管.个人 Qu ...

  8. POLIR-Society-Organization-Lawsuits: (2020)粤0303民初16184号判决书

    (2020)粤0303民初16184号判决书 深圳市罗湖区人民法院 送达公告页:https://guanwang.szlhfy.gov.cn/news/14209.cshtml 送达公告列表页(第16 ...

  9. SciTech-EECS-用MCU的 GPIO 或 OpAmp运放的Output 适配驱动 高电压 的 MOS管/IGBT/可控硅 甚至是 220V及以上的 阻性/感性/容性负载的

    TRIAC是"双向可控硅",SCR是"单向可控硅": 有半导体产商为直接驱动TRIAC与SCR而设计的配对光耦, 可以极大简化驱动电路设计.非常方便的用MCU信 ...

  10. 算法练习(19)-单源最短路径dijkstra算法

    如上图,先初始化1个图,每条边上的红色数字为路径权重:(Node,Edge的定义参见算法练习(17)-图的广度优先遍历/深度优先遍历) Graph init() { List<Node> ...