一个类创建实例的时候,需要经过多个步骤,比如我们调用new的时候经过了哪些流程,本文就来详细分析下

专业术语

逃逸分析算法

逃逸分析其实就是分析java对象的动态作用域,

  1. 如果一个对象被定义之后,被外部对象引用,则称之为方法逃逸
  2. 如果被其它线程所引用,则称之为线程逃逸

如果经过以上分析,一个对象没有逃逸出方法的话(仅仅在方法内部引用),那么就可能被优化成栈上分配。

TLAB(Thread Local Allocation Buffer)线程本地分配缓存

TLAB就是线程私有的堆空间,哪怕这个堆空间特别小(实际上时Eden区划分出来的),但只要有,每个线程分配对象到堆空间的时候会优先分配到线程自己所属的那一块堆空间中。

内存分配整体流程

1. 类加载

  1. 检查该指令参数是否能够在常量池中定位到这个类的符到引用
  2. 检查这个符号引用所代表的类是否已加载、解析、初始化
  3. 如果没有则执行类加载过程

2. 为对象分配内存

  1. 内存分配根据java堆内存是否绝对规整,分为:指针碰撞&空闲列表

    1. 指针碰撞法:
      假设堆中内存完整,已分配的内存和空闲内存分别在不同的一侧,这时通过一个指针为分界点,需要分配内存时将指针往空闲的一端移动与对象大小相等的距离,这样就完成了内存分配。
    2. 空闲列表法:
      如果堆中内存不完整,已分配内存和空闲内存相互交错,JVM通过维护一个空闲列表记录可用内存块信息。当需要分配内存时,在列表中找到一个足够大的内存块分配给对象实例,并更新列表上的记录。
  2. 解决线程安全问题
    1. 当有多个线程都需要分配内存空间时,使用CAS(Compare And Swap)+ 失败重试机制
    2. 依据逃逸分析算法分配到线程或者堆上

3. 内存空间初始化零值

保证了对象的实例字段在使用时可不赋值就直接使用(对应值0,比如int、boolean)

4. 对对象必要的设置

设置对象是哪个类的实例,并存放在对象的对象头中

内存分配详细流程


其中TLAB是在满足逃逸分析算法后做JVM做的优化

内存分配位置尝试过程


图中可以看到,优先在栈上分配->TLAB->老年代->Eden区

扩展

栈上分配和TLAB区别?

栈上分配:对象生命周期随着方法的调用开始而开始,结束而结束,不需要进行垃圾回收减轻了GC的负担

TLAB: 线程私有的堆内存,可以很好的避免了共享堆中多个线程操作堆内存分配对象空间时产生的同步问题(虽然有CAS+失败重试),从而提高堆上对象分配的效率。

总结

通过以上分析,弄懂了关于对象内存分配的详细过程,通过对过程的分析也了解了一些深层次的知识,比如指针碰撞、空闲列表、栈上分配、TLAB等。也希望可以给阅读本文的小伙伴带来一些帮助吧

JVM对象内存分配详细过程(栈上分配->TLAB->老年代->Eden区)相关推荐

  1. JVM 的栈上分配、TLAB、PLAB 有啥区别?

    我们在学习 G1 回收器的时候,一般我们都会接触到 TLAB 和 PLAB 这两个术语.它们都是为了提高内存分配效率而存在的,但它们和栈上分配有什么区别呢?今天,就让树哥带着大家盘一盘. 栈上分配 稍 ...

  2. 关于栈上分配和TLAB的理解

    引言 我们知道,一般在java程序中,new的对象是分配在堆空间中的,但是实际的情况是,大部分的new对象会进入堆空间中,而并非是全部的对象,还有另外两个地方可以存储new的对象,我们称之为栈上分配以 ...

  3. 3.内存分配、逃逸分析与栈上分配、直接内存和运行时常量池、基本类型的包装类和常量池、TLAB、可达性分析算法(学习笔记)

    3.JVM内存分配 3.1.内存分配概述 3.2.内存分配–Eden区域 3.3.内存分配–大对象直接进老年代 3.3.1.背景 3.3.2.解析 3.4.内存分配–长期存活的对象进去老年代 3.5. ...

  4. JVM逃逸分析(同步省略、标量替换、栈上分配)

    在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译是把.class转换成机器指令的过程. ...

  5. 对象可以在栈上分配空间吗?_Java面试题之:Java中所有的对象都分配在堆中吗?...

    JVM中的内存划分暂不讨论,单说堆(Heap),堆中一般存放的是new出来的对象.但是,随着JIT(即时编译)编译器的发展与逃逸分析(Escape Analysis)技术逐渐成熟,栈上分配.标量替换优 ...

  6. 只能在堆或只能在栈上分配内存的类

    只能在堆上分配内存的类 方法:将析构函数设置为私有 原因:C++ 是静态绑定语言,编译器管理栈上对象的生命周期,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性.若析构函数不可访问,则不能在 ...

  7. java创建对象时分配内存方式,是堆上分配还是栈上分配?

    创建对象的内存是分配在堆上还是栈上面?大部分童鞋的回答是这样的:"肯定分配在堆内存的嘛,栈内存是属于子线程和基本数据类型专用的内存空间,怎么会分配到栈上面呢?",这个回答嘛,也对, ...

  8. java tlab_java虚拟机中容易和JVM栈上分配混淆的TLAB上分配

    今天介绍一个容易跟JVM栈上分配混淆的 TLAB 上分配. 1. TLAB 上分配 Java 程序会极其频繁的创建对象并为对象分配内存空间,一般情况下对象是分配在堆上的,堆又是全局共享的,所以会存在这 ...

  9. GC分类、TLAB、逃逸分析、栈上分配、同步消除、标量替换

    GC分类 JVM的调优的一个环节,也就是垃圾收集,我们需要尽量的避免垃圾回收,因为在垃圾回收的过程中,容易出现STW(Stop the World)的问题,而 Major GC 和 Full GC出现 ...

最新文章

  1. hdfs web_ui深入讲解、服务启动日志分析、NN SNN关系
  2. 区块链正本清源 – 从计算机科学评看区块链的起源和发展
  3. strncasecmp的使用
  4. 倒计时2天,WebRTCon 2018有哪些有趣有料分享与活动?
  5. python 用元类 type 实现对数据库的ORM 映射
  6. 我TM快疯了,在博客园开博短短2个月,经历博客园数次故障。。。
  7. 更改数据库表中有数据的字段类型NUMERIC(18,2)为NUMERIC(18,6)
  8. 创业冲突的五种解决方法是_当创始合伙人发生冲突时,最好的解决方法4和5
  9. mac设置多个屏幕显示的问题
  10. 【阿里云视频点播加密视频播放报错】:网络错误加载数据失败(fragLoadError)或者403
  11. 【算法精解】计数排序
  12. 逆向工程的使用(逆向工程的压缩包下载分享)
  13. Python:正则表达式re.compile()
  14. input 搜索localStorage存储历史记录 删除历史记录
  15. Namesilo域名解析详细图文教程!
  16. html 地区筛选插件,帝国CMS7.2实现地区三级联动并且前台可地区筛选的插件教程...
  17. 宝剑配英雄,玫瑰赠伊人!(祝全天下静姝妇女节快乐!)
  18. Java11实现X509TrustManager报错SSLHandshakeException分析及解决办法
  19. 大一寒假集训(11)(12)---map,set
  20. spf打包解包_2020最新CentOS(linux下)安装7-Zip(7za压缩软件)以及解压命令,只打包不压缩,加密的方法...

热门文章

  1. arraychangekeycase php,浅谈php数组array_change_key_case() 函数和array_chunk()函数
  2. mysql数据库1对n_MySQL数据库InnnoDB引擎事务说明
  3. h5 fieldset
  4. 《微信小程序开发入门精要》——第2章,第2.8节带边距的水平等间隔排列
  5. 数据挖掘学习06 - 《数据挖掘导论》导读
  6. Android开发之APN网络切换
  7. 通过特性动态获取属性及值
  8. (二)线程--通过委托异步调用方法
  9. P1119 灾后重建(floyd进阶)
  10. bootstrap+masonry.js写瀑布流