Klass与Oop
前段时间,一直在看《Hotspot实战》,顺便编译了一份OpenJDK的源码,然后就在eclipse里面调试起来。
虽然我的入门语言是c/c++,但是被Java拉过来好几年了,现在再看源码,熟悉又陌生,好在慢慢找到了感觉。
这是分析Hotspot源码的第一篇,讲一下Klass和Oop这两种数据结构。
系统的介绍和讲解,可以查看https://yq.aliyun.com/articles/20279和http://www.jianshu.com/p/252e27863822这两篇文章。确实写的比较好,深入而且透彻。另外可以再看看《Hotspot实战》的第3章。
我这里主要看看Klass和Oop的内存布局。
当时看这张图的时候,有一个巨大的疑问,instanceKlass的数据结构与图不符,没有对象头(Mark和Klass这两个属性)。
真是百思不得其解。
于是,继续看源码。
1)对象头里的Klass这个属性,是一个klassOopDesc类型的指针,并不是一个指向Klass类的指针。why???
看了之前的第一篇文章,豁然开朗。在JDK8之前,方法区内的描述类型的元数据对象,也是由GC管理的。所有由GC统一管理的对象,都要继承自oopDesc,所以才会诞生klassOopDesc这个类型。从JDK8开始,类型元数据都移出了GC堆,所以Klass这个属性可以直接指向Klass类了。
2)klassOopDesc只有从父类继承过来的Mark和Klass这两个属性,并没有指向Klass类的指针,那oop是如何找到对应的Klass的呢???
klassOopDesc内部有一个方法:klass_part()
// returns the Klass part containing dispatching behavior
Klass* klass_part() const { return (Klass*)((address)this + sizeof(klassOopDesc)); }
这个方法果然返回一个指向Klass的指针,但是计算过程比较诡异,在当前klassOopDesc对象的首地址增加sizeof(klassOopDesc)这么多空间后的地址。也就是说,一个klassOopDesc对象数据和对应的Klass对象数据,是从上到下紧密的排列着,有了klassOopDesc的指针,就能顺藤摸瓜找到对应的Klass数据。
那当初构造的时候,是按这种模式在内存分配数据的吗???
之前的第二篇文章,讲的巨细。可以看到,在类加载的过程中,构造了一个空的Klass对象,然后调用了Klass类的as_klassOop方法返回klassOopDesc的指针。
// returns the enclosing klassOop
klassOop as_klassOop() const {
// see klassOop.hpp for layout.
return (klassOop) (((char*) this) - sizeof(klassOopDesc));
}
klassOop是klassOopDesc指针的一个别名。构造的时候,首地址减去sizeof(klassOopDesc)这么多空间后的地址。这时候,内存空间是分配出来了,具体的数据,在后续过程中填充。
最后说下看源码心得体会 :其实那张图上的数据排列结构是对的,但是具体的实现方式,如果不看源码肯定会很疑惑。另外,看到这么犀利的指针操作,对c/c++的好感真是倍增。
Klass与Oop的更多相关文章
- 深入解析Java反射-invoke方法
博客原文:http://www.sczyh30.com/posts/Java/java-reflection-2/ 上篇文章中回顾了一下Java反射相关的基础内容.这一节我们来深入研究Method类中 ...
- 深入理解java虚拟机---对象的结构(九)
注意: 我们可以看到的就是InstanceData的数据. 先转载一篇文章作为开头,因为讲的非常详细,我就简单加工下放到这里: 对象结构 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区 ...
- 深入理解多线程(二)—— Java的对象模型
上一篇文章中简单介绍过synchronized关键字的方式,其中,同步代码块使用monitorenter和monitorexit两个指令实现,同步方法使用ACC_SYNCHRONIZED标记符实现.后 ...
- Java对象结构及HotSpot对象模型
一.对象结构 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding).下图是普通对象实例与数组对象 ...
- 从Oop-Klass模型看透反射
<红楼梦>第十二回,贾瑞因痴迷王熙凤,被王熙凤折腾的眼看就快不行了.当然这里面是没有多少爱的,完全因王熙凤的美貌而起.就在这时来了一个跛足道人,带来了一面宝镜,说能治好贾瑞的病.当然这可不 ...
- HotSpot二分模型(1)
HotSpot采用了OOP-Klass模型来描述Java类和对象.OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象的具体类型. 那么为何要设计这样一 ...
- HotSpot源码分析之C++对象的内存布局
HotSpot采用了OOP-Klass模型来描述Java类和对象.OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象的具体类型.为了更好理解这个模型, ...
- 深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用
反射的概念 反射: Refelection,反射是Java的特征之一,允许运行中的Java程序获取自身信息,并可以操作类或者对象的内部属性 通过反射,可以在运行时获得程序或者程序中的每一个类型的成员活 ...
- jvm源码解读--17 Java的wait()、notify()学习
write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...
随机推荐
- Go从入门到精通(一)go语言初始
一.第一个go程序 package main import ( "fmt" ) func main(){ fmt.Println("hello world") ...
- java加密算法入门(一)-算法概念及单向加密
说起加密,我的第一印象就是电视剧各种密码本破解解密的场景,这两天在看加密相关的东西,做下笔记以便以后查看,也提供给大家个参考. 本文是java加密的第一篇,主要讲述下消息编码Base64以及简单的消息 ...
- JavaScript设计模式_05_发布订阅模式
发布-订阅模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都将得到通知.发布-订阅模式是使用比较广泛的一种模式,尤其是在异步编程中. /* * pre:发布-订阅 ...
- [0] Visual studio 2010 快捷键大全
[窗口快捷键]Ctrl+W,W: 浏览器窗口 Ctrl+W,S: 解决方案管理器 Ctrl+W,C: 类视图 Ctrl+W,E: 错误列表 Ctrl+W,O: 输出视图 trl+W,P: 属性窗口 C ...
- Vue2 全家桶仿 微信App 项目,支持多人在线聊天和机器人聊天
前言 这个项目是利用工作之余写的一个模仿微信app的单页面应用,整个项目包含27个页面,涉及实时群聊,机器人聊天,同学录,朋友圈等等,后续页面还是开发中.写这个项目主要目的是练习和熟悉vue和vuex ...
- python实现微信接口(itchat)
python实现微信接口(itchat) 安装 sudo pip install itchat 登录 itchat.auto_login() 这种方法将会通过微信扫描二维码登录,但是这种登录的方式确实 ...
- 【转载】Windows系统下删除ubuntu
原始日期:2013-11-02 15:51 以windows7为例: 用MbrFix.exe修复MBR 卸载Windows/Linux双系统中的Ubuntu1.如果你有Windows系统安装盘/启 ...
- js模版引擎开发实战以及对eval函数的改进
简介 前段时间,想着自己写一个简单的模版引擎,便于自己平时开发demo时使用,同时也算是之前学习的知识的一种总结吧! 首先我们先了解一下模版引擎的工作原理吧! 1. 模版引擎其实就是将指定标签的内容根 ...
- Linux下重启多个 tomcat 服务的脚本
由于修改tomcat的配置文件或手动操作数据库数据后,tomcat的缓存和redis的缓存很严重,需要经常重启tomcat来释放缓存,经常就是手动重启. # .查找tomcat的进程ID ps -ef ...
- java的三大特性,封装,继承,多态
封装 /** * 所谓封装,就是将对象具有的成员变量和成员函数包装和隐藏起来,让外界无法直接使用, * 被封装的成员只能通过某些特定的方式才能访问. * 实现封装有两个步骤: * 1.将不能暴露的 ...