来看一道面试题:所有的new 对象都是分配在堆上的吗?如果不是,是什么情况。

在没看到这道题目的时候,我对所有对象都分配在堆上的想法是没有一丝怀疑的,但是事实是不一定的。

逃逸分析

逃逸分析的定义

逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。

Java在Java SE 6u23以及以后的版本中支持并默认开启了逃逸分析的选项。Java的 HotSpot JIT编译器,能够在方法重载或者动态加载代码的时候对代码进行逃逸分析,同时Java对象在堆上分配和内置线程的特点使得逃逸分析成Java的重要功能。

逃逸分析是如何决定一个对象是否分配在堆

先来看下面这段程序

public class test {public static void main(String[] args){String str = new String("Test");System.out.println(str);}
}

花两分钟想想,如果你是jvm的设计师,你会把这个str分配在堆上吗?

jvm中的堆上的对象可以线程共享的,那么我们把str放在堆上,谁来共享呢?

很明显没有人会再使用它,它在自己的线程栈结束的时候,就已经没有意义了。

再来看下面这段程序:

public class test {public static String getString(){String str = new String("Test");return str;}public static void main(String[] args){String MyStr = getString();System.out.println(MyStr);}
}

在调用getString方法的时候,在该栈帧上,如果我们把str放在栈中,那么调用该方法体将得不到该对象。因为在getString结束的时候,就会把str对象释放,那么在main方法体中,MyStr将会指向null。

于是在这个情况下,str对象是会被放在堆上去共享的。我想看到这,大家已经明白那些对象是可以放在栈上,哪些是必须放在堆上的了。

若一个方法体内的对象不被其他方法或者线程得到,我们可以把对象直接存放在栈上,当JVM能证明一个对象不会逃逸到方法或者线程外,则可能为这个变量进行一些高效的优化。

把对象放在栈上有什么意义

我们知道在堆上的对象是被多个线程共享的,共享就要考虑多线程的安全问题,那么就需要锁的消耗。而且把对象放在栈上,会随着栈的出栈一起释放。减轻GC的压力。

TLAB

JVM在内存新生代Eden Space中开辟了一小块线程私有的区域,称作TLAB(Thread-local allocation buffer)。默认设定为占用Eden Space的1%。在Java程序中很多对象都是小对象且用过即丢,它们不存在线程共享也适合被快速GC,所以对于小对象通常JVM会优先分配在TLAB上,并且TLAB上的分配由于是线程私有所以没有锁开销。因此在实践中分配多个小对象的效率通常比分配一个大对象的效率要高。

但对象还是分配在堆上的,只不过是堆上的一块区域而已。

JVM 之 逃逸分析和TLAB相关推荐

  1. 小师妹学JVM之:逃逸分析和TLAB

    文章目录 简介 逃逸分析和栈上分配 TLAB简介 TLAB详解 设置TLAB空间的大小 TLAB中大对象的分配 TLAB空间中的浪费 总结 简介 逃逸分析我们在JDK14中JVM的性能优化一文中已经讲 ...

  2. JVM 栈分配、逃逸分析与TLAB

    最近在学习JVM,在看到这块地方,做一个简化的日志记录,部分内容抄录. 一般认为new出来的对象都是被分配在堆上,但是这个结论不是那么的绝对,通过对Java对象分配的过程分析,可以知道有两个地方会导致 ...

  3. tlab java_Java中的逃逸分析和TLAB以及Java对象分配

    我们在学习使用Java的过程中,一般认为new出来的对象都是被分配在堆上,但是这个结论不是那么的绝对,通过对Java对象分配的过程分析,可以知道有两个地方会导致Java中new出来的对象并一定分别在所 ...

  4. JVM原理 | 逃逸分析

    逃逸分析 1. 何为"逃逸"(Escape)? 当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他方法或者线程所引用,这种现象称作指针(或者引用)的 ...

  5. JVM【带着问题去学习 01】什么是JVM+内存结构+堆内存+堆内存参数(逃逸分析)

    1.是什么 (1) 基本概念:可运行 Java 代码的非真实计算机 ,包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回器,堆和一个存储方法域.它运行在操作系统之上,与硬件没有直接的交互. (2) ...

  6. JVM内存模型、逃逸分析以及发生GC的时机

    文章目录 1. 整体内存模型图 ①:堆 ②:栈与栈帧 ③:方法区 ④:程序计数器 ⑤:本地方法栈 2. JVM参数设置 GC日志打印参数设置 3. JVM内部的对象创建流程(new 对象流程) 4. ...

  7. JVM 逃逸分析 (史上最全)

    对于JVM"逃逸分析" 特性,也是近年来大厂面试.高薪面试的常见面试题. 和逃逸分析有关的常见面试题: Java中的对象一定是在堆上分配的吗? 注:本文以 PDF 持续更新,最新尼 ...

  8. JVM虚拟机中优化技术之逃逸分析

    目录 编译器优化技术之语言相关的优化技术 简介 前置问题 对象是否都被分配到了堆内存中? 为什么会发生逃逸? 什么是逃逸分析? 逃逸分析原理 什么是方法逃逸? 举例说明: 什么是线程逃逸? 举例说明: ...

  9. 逃逸分析和标量替换技术,你明白了吗

    文章目录 逃逸分析 怎么做逃逸分析后的优化? 什么是线程分配缓冲TLAB? 什么是标量替换? 实战 开始逃逸分析(默认开启的) 关闭逃逸分析-XX:-DoEscapeAnalysis 逃逸分析 逃逸分 ...

最新文章

  1. 【图灵】iOS技能书单——入门+进阶+精通
  2. 年末裁员事件背后的启示录(2)
  3. 安卓进阶系列-08异步加载AsynsTask使用
  4. Tomcat安装及Eclipse配置教程
  5. String 使用不当可能导致内存泄露
  6. 快来一起玩转LiteOS组件:RHas
  7. 学习 openssl 证书命令
  8. gazebo打不开world
  9. 设计模式-第五篇之命令模式
  10. 记住不要把Bitmap往List等集合放
  11. project不显示里程碑标志_如何在project中创建里程碑?怎么设置project的里程碑?...
  12. 验证整数和小数的正则表达式
  13. 暮雨小巷,殇了身影,冷了沙洲
  14. filebox管理php,filebox.php
  15. 安装配置Axis2,为Eclipse安装配置Axis2插件教程
  16. 在后台处理请求返回的json字符串
  17. Ubuntu 查看Nvidia显卡驱动信息
  18. “重感知·轻地图”重新定义自动驾驶
  19. ubuntu 制作本地源 离线安装
  20. CGB2103-day01

热门文章

  1. 李宏毅机器学习2022.07.15--误差
  2. Arthas的watch命令
  3. 【HTML期末作业】个人游戏主页--html作业
  4. 第25讲 时序电路定时与异步交互
  5. 最纯粹的直播技术实战01-FFmpeg的编译与运行
  6. 微信小程序 canvas描绘文字图片 生成图片并保存到本地
  7. flutter 实现Android端百度地图定位
  8. 配置双系统开机选择系统的倒计时
  9. Rman还原种子数据库练习
  10. rockchip 平台ksz8863rll调试