精神小伙儿探秘JVM(二)

上回说到,JVM是个啥,里面的内存模型是怎样的。这次我们来研究HotSpot虚拟机。

HotSpot虚拟机

啥?这又是个啥?不是Java虚拟机么?咋又整出个HotSpot来?我读书少,别骗我。。。淡定,我也是小白。HotSpot VM,其实Java程序员都知道,它是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。所以,这玩意就是JVM中的一种。

对象的内存布局

分为三块区域

  • 对象头(Header)
  • 实例数据(Instance Data)
  • 对齐填充(Padding)

对象头:记录了对象在运行过程中所需要的一些数据:哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳。对象头还可能包含指针,来确定这个对象属于哪个类的。如果对象是一个数组,对象头还包含数组长度。

实例数据:其实就是成员变量。包含了自己的还有父类的成员变量。

对齐填充:确保对象的总长度为8的倍数。HotSpot VM 的自动内存管理系统要求对象的大小必须是 8 字节的整数倍。而对象头部分正好是 8 字节的倍数(1 倍或 2 倍),因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。当然,对齐填充并不是必然存在,也没有特别的含义,它仅仅起着占位符的作用。

对象的创建过程

类加载检查

虚拟机加载的只是.class文件,别的也不认。当读取.class文件中发现有new时,首先去常量池中检查常量池中有没有这个类的符号引用,完了检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,必须先执行类的加载过程。

为新生对象分配内存

类加载完了,需要创建哪些对象,他们的类型,也就都知道了,这样对象的大小就能定下来了。接下来,就是给对象分配内存。方式有二:

1.指针碰撞

非常酷炫的名字。这个主要针对Java堆中内存绝对规整的情况。我们的Java堆是一块大大的内存,可以想象成是个冰箱,每创建一个对象,相当于放一个新的东西进去,就需要在里面开辟一块地方。如果我们比较勤快,每个新放进去的吃的,都能够和旧的紧密相连,排排坐吃果果,这样我们的冰箱就非常规整。Java管这个叫内存绝对规整。这需要内存分配的时候,特别采用“复制算法”或“标记整理算法”(具体想理解可以查查)。这么分配的好处,就是不会有碎片内存,那么Java在已分配的空间和未分配空间中间,设置了一个指针,我们叫它分界点指示器。每次新new对象的时候,挪动这个指针,挪动距离等于对象的大小,这样就能完成新对象的内存分配。这,就叫指针碰撞。

2.空闲列表

有规整的方法,也有懒人版的内存管理算法。毕竟,我们家里的冰箱可不是整整齐齐的,起码我家的不是。。。好吧,Java如果采用的是标记-清除算法,来管理内存,那么就会有碎片产生。至于为啥大家自己百度下哈。这样,已分配内存和未分配内存不是界限分明的,而是犬牙交错,你中有我,我中有你,彼此交织在一起。那就得弄个表,我们叫它“空闲列表”,把哪块没用的用这表记着,需要new对象了,别急,我给你找个地方,能塞下你的。这种分配内存的方式就叫“空闲列表“。

初始化

分配完地方了,就得初始化对象了。总共分两步:1.给成员变量赋值 2.设置对象头信息 3.调用对象的构造方法

这样,一个对象就诞生了。

对象的访问方式

鲁迅说过:存在即合理。。。咳咳,可能不是鲁迅。这句话反过来,必须有价值的东西才能存在。对象也不例外,对象的价值就是能被使用,被访问。对象虽然诞生在堆里,但这人厚道,为了方便外界访问,在栈里同时留了个指针,我们通过这个指针就能访问到这个对象。这个指针存的是个地址,这个地址是啥,决定了对象有两种不同的访问形式。

第一种,存放对象的句柄地址。堆中有一块地方,叫“句柄池”,里头放了对象的实例信息和类型信息。句柄池里存放每个对象的句柄,每个句柄有自己的地址。对象指针存放句柄地址,通过访问句柄地址,找到对象地址,就能访问这个对象了。

第二种,就存放实际对象的地址。通过它就可以直接访问到对象了。但这种方式,没有句柄保存类信息,类信息需要其他策略进行保存。

以上两种方式,我们的HotSpot为了追求效率,选择了第二种。故也采用其他策略来保存对象的类信息。

了解了JVM和其中的代表人员HotSpot,Java虚拟机大概认识了。那么下面就进入下一主题,也是虚拟机不得不说的事儿:垃圾回收。有诗为证:

JVM虚拟机,垃圾回收真传奇;自动回收挺牛币,不知原理全玩儿去!

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林小BA

请作者增肥

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值