前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HotSpot虚拟机对象如何被创建的?

HotSpot虚拟机对象如何被创建的?

作者头像
逍遥壮士
发布2021-03-04 14:35:46
8050
发布2021-03-04 14:35:46
举报
文章被收录于专栏:技术趋势技术趋势

类的生命周期(类的加载过程)

每个class文件加载到内存到卸载,都是经历过jvm的类的生命周期是加载、连接(验证、准备、解析)、初始化、使用、卸载;

简单介绍后续深入了解!!!

HotSpot虚拟机对象如何被创建的?

java程序中创建对象是通过new出来的,而虚拟机这会就会接收到一条new的指令后,先去检查这个指针是否能够在常量池中找着一个类的符号引用,或找着这个符号引用,则代表这个类经历了加载、解析和初始化过,如果没有那就要执行类的加载过程。当然加载检查全部通过后,虚拟机会为这个类分配内存,当这个类中的所有对象所需的内存大小被加载后就已确认。

内存是如何分配的?

当类加载完成后,这时已经完全确认内存后,分配内存有两种方式:指针碰撞(Bump The Pointer)和维护一张空闲列表(Free List);

指针碰撞(Bump The Pointer):

假设jvm内存是规整(连续意思)的。堆内存被一个指针一分为二。指针的左边是使用过的,内里存放着对象,右边则是空闲的,而指针的作用是当每次新创建对象向右边移动一个对象的size的距离,这种叫做指针碰撞。

个人理解:堆就像连续的一块耕地,左边种上大豆苗子(对象),右边还是空的,当有新的苗子运来的时候接着开始从右边靠近左边空的继续种上,直接种空。(不知道生动不~)

空闲列表(Free List):

假设jvm内存不是规整(连续意思)的,已被使用与空间的内存交错在一起,这时候就无法通过指针碰撞进行分配内存,那就必须维护一张空闲列表,这张表存放着所有空间的地址,当新创建一个对象的时候,需要多少的空间就从表里进行寻找到一位合适的空闲空间进行分配。(当然有大有小,如果大了剩余的是需要被虚拟机回收的,这块jvm对应一套自己的处理机制,这里不赘述,有兴趣可以更深入了解)。

个人理解:这个空闲列表就像有一整块地,有几十亩(内存),有些地房盖上了房子(已用),有些还是空的(未用)。那这时候空的地会被记录在案,当某一天,哪位有钱人家想块地进行盖房子时,就先从这个记录在案里面找一块,然后才进盖房子(创建对象)。

jvm具体选择是空闲列表,还是指针碰撞方式进行内存分配,是根据java堆是否规整来决定,而java堆是否规整又是由垃圾上集器是否带空间压缩整理来决定。(后续垃圾算法详细深入)。

Serial、ParNew等带压缩整理过程收集器采用:指针碰撞。

CMS基于标记清除算法采用:空间列表。

频繁内存分配怎么保证线程安全?

内存分配解决了,但是jvm在分配的时候频繁修改一个指针所指向的位置,在并发情况不是线程安全的,那jvm是通过同步处理和本地线程分配缓冲解决该问题。

同步处理:虚拟机是采用CAS配上失败重试的方式保证更新操作的原子性。

本地线程分配缓冲:每个线程在java堆中预先分配一小块内存,称为地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,这块内存分配时线程独占的,读取、使用、回收是线程共享,只有本地缓冲区用完了,分配新的缓存区时才需要同步锁定。

TLAB空间的内存非常小,缺省情况下仅占有整个Eden空间的1%,也可以通过选项-XX:TLABWasteTargetPercent设置TLAB空间所占用Eden空间的百分比大小。由于TLAB空间一般不会很大,因此大对象无法在TLAB上进行分配,总是会直接分配在堆上。TLAB空间由于比较小,因此很容易装满。比如,一个100K的空间,已经使用了80KB,当需要再分配一个30KB的对象时,肯定就无能为力了。这时虚拟机会有两种选择,第一,废弃当前TLAB,这样就会浪费20KB空间;第二,将这30KB的对象直接分配在堆上,保留当前的TLAB,这样可以希望将来有小于20KB的对象分配请求可以直接使用这块空间。

jvm设定TLAB通过:-XX:+/-UseTLAB

比如:使用本地缓存区

-XX:+UseTLAB

注意:

jvm默认采用本地线程分配缓冲来进行解决线程安全问题。

推荐使用虚拟机默认配置,不建议修改TLAB配置。

两种优缺点对比:

名称

同步处理

本地线程分配缓冲

性能

较低

高效

占用空间

不会

会根据运行情况计算而得或配置

最后

简单介绍关于对象被创建的相关流程和条件及内存是如何分配的,这块在面试中倒是经常遇到,希望本文对你有帮助,下文继续关于对象的内存是如何布局的。

参考文章:

https://www.zhihu.com/question/56538259

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 技术趋势 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档