Java虚拟机中对象的创建、存储、访问定位。

Java中,对象的创建与销毁无时无刻不在进行之中,但是在虚拟机中,对象的创建是再怎么样的?(除开数组,因为数组直接在堆上分配;除开Class对象,详情见我的blog,Java中的Class对象。)

JVM中对象的创建过程

当JVM遇到一个new的指令时,首先回去常量池中定位到一个类的符号引用。,并且检查类的符号引用代表的类是否已经被加载、链接、初始化过。如果没有,则先进行相应的类加载过程。

      当类加载检查通过后,JVM开始为对象分配内存。大小在类加载完后已经确定。此时,如何分配内存在这里可以探讨一下。

方法一:指针碰撞,java堆中的内存绝对规整,使用的放在一边,空闲的放在一边。他们之间放一个指针做指示器,分配时内存向未使用过的内存偏移。
方式二:空闲列表,已使用和空闲内存交叉,JVM维护一张表,记录那些内存已经使用。在分配时,从列表中找出一块足够大的空间,并跟新记录。

为什么会存在这两种方式,这是和垃圾回收采用的算法相关的。详情请参阅我的博文----Java的垃圾回收机制。

如果你看完觉得分配没问题了,就大错特错了。考虑一下多线程的问题:

当你正在在为对象A分配一块内存时,指针还未修改;此时为对象B也分配到了这块内存怎么办?为了解决此问题,由于多线程造成的问题。虚拟机采用CAS失败重试的方法进行保证更新的原子性:另一种方式,每个线程在java堆中都预先分配一小块内存,哪个线程需要分配内存,就在哪个线程所被分配的内存重分配。当此内存使用完,进行同步锁定。


JVM中对象的内存布局

         对象在内存的存储布局可以分为3块区域:对象头实例数据对齐填充

         对象头包括两部分信息:1>.对象运行时自身的数据,比如HashCode、GC分带年龄等。  2.>类型指针。指向它类元数据的指针。

         实例数据:程序代码中所定义的各种类型字段的内容。

         对齐填充:占位符的作用。因为VM要求对象其实地址必须是8字节的整数倍。


JVM中对象的访问定位

     Java程序需要通过栈上reference数据来操作对上的具体对象。目前主流的访问方式有句柄和直接指针。

     直接指针:reference中存放的是对象地址。直接可以访问。

     句柄(类型两级指针):Java堆中划分一块内存作为句柄池,reference存放的是对象的句柄地址,而句柄对象中存放了对象实录数据与数据类型个自己的地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值