透过OOP-Klass模型来看实例变量与类变量的存储

《透过OOP-Klass模型来看实例变量与类变量的存储》

 

前言

很久没有写过博客了,但今天在Iteye上看见有朋友提问静态变量是存储在方法区还是存储在哪里的一篇帖子,然后又搜索了其他的一些相关帖子,看后心里不免有些蛋疼,十有八九很多人从心里根本不清楚JVM是如何存储的,或者说,很多人根本就没有区分开什么是变量存储什么是值存储,这2个压根就不是同一个概念,导致很多人产生疑问,那么笔者今天这篇博客,要的效果就是深入到JVM底层来分析这个问题。当然由于本人能力有限,难免会有语义错误的地方,请大家指出。

 

正文

言归正传,再谈存储之前,首先做一个扫盲。从虚拟机内部表示形式来看,变量可以划分为实例变量和类变量(即静态变量)。实例变量与对象实例相关,也就是说,任何一个实例变量,在使用之前,首先要做的事情就是目标类型必须要实例化,然后才能够使用;而类变量与对象实例无关,但是却以类相关,也就是说,使用一个被static关键字标示的类变量是不用实例化对象的,直接可用。

 

当大家明白实例变量和类变量之前的区别后,我们再接从语法层面开始讨论引用类型的变量和原始类型的变量之间的区别。引用类型的变量所持有的值是什么?相信大家都应该知道,所谓引用指的就是一个指向目标对象实例的类似于“指针”的东西,而原始类型的变量所持有的值就是实际的原始值。

 

关于变量的概念已经介绍了一大堆后,接下来我们来再来看看变量值的存储。以粗粒度的方式来看待变量的存储尽管有些不妥,但为了让更多不理解JVM底层的人能够看懂,也是情有可原。Java的运行时数据区中,栈帧中的局部变量表用于存储方法体内的局部变量和方法参数,如果变量的类型是原始数据类型,则在局部变量表中存储实际的原始值,反之存储对象引用(reference),当然还会存储returnAddress类型。那么如果是成员变量,就存储在Java堆区中(内存布局中的实例数据中)。简单来说,与线程上下文相关的存储在Java栈中,反之存储在Java堆中,这个是常识。

图1 对象访问定位

之所以先说变量值的存储而没有先说变量的存储,笔者是可以安排的,因为这2个概念是非常多的开发人员容易弄混淆的。变量仅仅只是一个存储介质,所负责的任务很简单,就是牵引数据存储到正确的位置上,但它自己本身没有任何能力存储数据,这一点要明确。这里要引入一个概念,那就是JVM中对象的底层表示形式,OOP-Klass模型。对象内存布局中的内存头是由instanceOopDesc来表示(数组类型则用arrayOopDesc对象来进行表示),而对象头中的元数据指针所指向的当前对象的目标类型则是由Klass中的instanceKlass对象进行表示(数组则用arrayKlass对象进行表示)。OOPKlass其实是2个相互独立但是却又彼此相互关联的模块,这2个模块均包含在/openjdk/hotspot/src/share/vm/oops模块中,那么OOP-Klass模型与对象的内存布局之间又有什么关系呢?在JVM中对象头就是由OOP对象instanceOopDesc来表示(数组类型则用arrayOopDesc对象来进行表示),而对象头中的元数据指针所指向的当前对象的目标类型则是由Klass中的instanceKlass对象进行表示(数组则用arrayKlass对象进行表示),用于在JVM中表示一个Java类的对等体。当明确OOP-Klass模型的作用后,请大家思考一下JVM是如何通过栈帧中的对象引用访问到其内部的对象实例的呢?如图1所示,JVM可以通过对象引用准确定位到Java堆区中的instanceOopDesc对象,这样既可成功访问到对象的实例信息,当需要访问目标对象的具体类型时,JVM则会通过存储在instanceOopDesc中的元数据指针定位到存储在方法区中的instanceKlass对象上。

 

扯了一大堆,说白了,类变量既然不予对象实例相关,那么它则存储在方法区中的instanceKlass对象内,当然仅仅只是变量!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值