java中的对象在内存中,究竟是怎样一种存在?

这篇随笔,我们就来一探究竟。可能不够深入,但是我们把理解到位,深入到我们需要的程度这样即可。

先来看下jvm的内存模型:

程序计数器

虚拟机栈和本地方法栈

方法区(运行时常量池)

这就是整个的jvm的内存模型的组成部分,那么对象是存储在Heap Area中的,也就是堆空间。

知道了存储的地方,那具体究竟是怎么存储的呢?我们继续。

注:全篇所说的jvm都是特指HotSpot JVM。

(刚在看OOP_CLASS)的过程中,详细看了一篇博客写的很清晰,把相关的内容写的很清晰。看了下介绍是个15年毕业的兄弟,现在已经是阿里的技术专家了,再次印证的那个道理,人必须有个勤字,一勤天下无难事,还有就是恒字,反省我自己的技术生涯,如果能做到这两个字也早起来了。痛定思痛继续努力。

之前其实翻过HotSpot的Klass部分的源码,但当时并没有深刻的理解,今天再来引用一下。

先看整个的结构:

Java对象分为两个部分在jvm中,一个是对象本身,一个是对象对应的类,在jvm的代码oopsHierarchy.hpp中可以看到,代表对象的是下边这些:

#ifndef CHECK_UNHANDLED_OOPS

typedefclass oopDesc*oop;

typedefclass instanceOopDesc*instanceOop;

typedefclass methodOopDesc*methodOop;

typedefclass constMethodOopDesc*constMethodOop;

typedefclass methodDataOopDesc*methodDataOop;

typedefclass arrayOopDesc*arrayOop;

typedefclass objArrayOopDesc*objArrayOop;

typedefclass typeArrayOopDesc*typeArrayOop;

typedefclass constantPoolOopDesc*constantPoolOop;

typedefclass constantPoolCacheOopDesc*constantPoolCacheOop;

typedefclass klassOopDesc*klassOop;

typedefclass markOopDesc*markOop;

typedefclass compiledICHolderOopDesc*compiledICHolderOop;#else

代表类的是下边这些:注释上也写了,klass的结构和oop的结构是分开的

//The klass hierarchy is separate from the oop hierarchy.

classKlass;classinstanceKlass;classinstanceMirrorKlass;classinstanceRefKlass;classmethodKlass;classconstMethodKlass;classmethodDataKlass;classklassKlass;classinstanceKlassKlass;classarrayKlassKlass;classobjArrayKlassKlass;classtypeArrayKlassKlass;classarrayKlass;classobjArrayKlass;classtypeArrayKlass;classconstantPoolKlass;classconstantPoolCacheKlass;classcompiledICHolderKlass;#endif //SHARE_VM_OOPS_OOPSHIERARCHY_HPP

为什么要分开,据说是为了避免像c++那样实现多态的时候需要每个对象维护一个虚方法表,而分开的。这样oopDesc里我们可以看到,对象的定义里,对象头除了MarkWord之外,就是类型指针,而类型指针其实就是方法区的instanceKlass。表示的就是类在jvm里的实例信息。

classoopDesc {

friendclassVMStructs;private:volatilemarkOop _mark; // 1 MarkWord

union _metadata { // 2 类型指针

wideKlassOop _klass;

narrowOop _compressed_klass;

} _metadata;// ...省略private://field addresses in oop

void* field_base(int offset) const;

jbyte* byte_field_addr(int offset) const;

jchar* char_field_addr(int offset) const;

jboolean* bool_field_addr(int offset) const;

jint* int_field_addr(int offset) const;

jshort* short_field_addr(int offset) const;

jlong* long_field_addr(int offset) const;

jfloat* float_field_addr(int offset) const;

jdouble* double_field_addr(int offset) const;

address* address_field_addr(int offset) const;

这个就是OopDesc.hpp的代码,而我们要的InstanceOop是这样的

#include "oops/oop.hpp"

//An instanceOop is an instance of a Java Class//Evaluating "new HashTable()" will create an instanceOop.

class instanceOopDesc : publicoopDesc {// 省略};#endif //SHARE_VM_OOPS_INSTANCEOOP_HPP

明显看到instanceOopDesc就是继承自oopDesc的。所以我们来分析下oopDesc的结构。

我们知道Java对象的组成部分是:对象头(Header)/ 实例数据(Instance Data)/ 对齐填充(Padding) 三个部分。而对象头又包括两部分:MarkWord 和 类型指针。

代码中明显可以看到对象头的部分,我们已经标注出来,而实例数据就在下边的各种field里。

看到了OopDesc表示的对象,我们再来看下Klass表示的类吧。

java 的“mwq”_java的对象模型 - osc_mwqvsfzo的个人空间 - OSCHINA - 中文开源技术交流社区...相关推荐

  1. java知识理论_JAVA理论知识 - OSC_rnoszD的个人空间 - OSCHINA - 中文开源技术交流社区...

    1. final关键字可以用来修饰什么?分别起什么作用? a) final可以修饰类,这样的类不能被继承. b) final可以修饰方法,这样的方法不能被重写. c) final可以修饰变量,这样的变 ...

  2. java课程总结_Java课程总结 - osc_uyb9f22c的个人空间 - OSCHINA - 中文开源技术交流社区...

    总结:已经学了一个学期的Java,虽然在课堂上面还是很认真的听讲,但在课后,基本上没有复习与巩固,导致感觉没有C语言学的好,最后的面试结果也不是很令人满意.在以后的学习中,要改变学习方式.做什么事都要 ...

  3. java组件介绍_Java组件介绍 - osc_wws45aot的个人空间 - OSCHINA - 中文开源技术交流社区...

    1.String string对象的不变性.被final关键字修饰. 使用charat方法替代startwith/endwith方法(提高性能) 使用buffer(方法同步,性能较差)和builder ...

  4. java 抽奖算法_Java抽奖概率算法 - hejunbinlan的个人空间 - OSCHINA - 中文开源技术交流社区...

    摘要: 序号 奖品名称 奖品编号 抽到的概率 1 再来一次 P1 0.2 2 本站VIP一年 P2 0.1 3 谢谢参与 P3 0.4 4 50金币 P4 0.3 5 Iphone 6 P5 0.0 ...

  5. java io 读取配置文件_java读取配置文件 - tomzhao2008的个人空间 - OSCHINA - 中文开源技术交流社区...

    对于要打包成jar文件来运行来说,用file是会有问题的,下面的程序可以解决这样的问题 1.ReadPropsUtil /** * */ package readproperties; import ...

  6. java动态变量名反射_Java动态性—反射 - Eclipse666的个人空间 - OSCHINA - 中文开源技术交流社区...

    1.什么是动态语言? 程序运行时,可以改变程序的结构或者变量类型:如Python,javaScript function(){ var s="var a=3;var b=4;" e ...

  7. java记录类加载的个数_java类加载过程 - audience_1的个人空间 - OSCHINA - 中文开源技术交流社区...

    java类加载过程: 在我们代码中,一般就一个new的方法,就能够创建一个java的对象类,但在java虚拟机中 1:首先,我们需要判断该类是否已经在方法区中的常量池中有一个类的符号的引用存在,如果该 ...

  8. java枚举变量带括号_java枚举类型 - 墨梅的个人空间 - OSCHINA - 中文开源技术交流社区...

    public class TestEnum { /*最普通的枚举*/ public enum ColorSelect { red, green, yellow, blue; } /* 枚举也可以象一般 ...

  9. 5.0 java集合框架中的接口collection属于_JAVA集合框架 - osc_cyo2dovg的个人空间 - OSCHINA - 中文开源技术交流社区...

    一.为什么要使用集合 单个数据,可以用变量保存: 多个数据,可以用数组保存: 但是对于存储多个数据且数量不确定的情况,使用集合: 二.集合和数组的区别 (1)数组: 1.只能保存同一种类型的数据: 2 ...

最新文章

  1. HTML5 的优点与缺点
  2. pku1050----To the Max(求矩阵的最大子段和)
  3. 会声会影X4 初学者速成 转
  4. iOS推送小结--swift语言
  5. 前端学习(239):渐进增强和优雅降级
  6. 第七章 假设检验(2)
  7. netcore quartz job用不了services_.NetCore开源集成框架
  8. html 无序列表编程一排_HTML 入门笔记
  9. php接收post写入文件,PHP中Post和Get获取数据写入文件中
  10. 真不好意思,关于小猪妹(妖精)的
  11. SQL Server商业智能–简介
  12. 380.常数时间插入、删除和获取随机元素
  13. 高德地图根据关键词坐标拾取小工具
  14. 基于FlexRay总线的汽车冗余线控转向系统的可靠性(FEMA)分析
  15. 最简单24点算法,可任意实现n数n点,一看就明!
  16. Spark如何求解中位数
  17. 服务器修改传奇道士神兽升级,1.76复古传奇道士玩家快速升级神兽的技巧
  18. 构建具有时间依存协变量的Elastic-net Cox模型
  19. 用spark实现单词统计
  20. js模板引擎Template.js使用详解及免费下载template.js

热门文章

  1. 使用Opencv进行轮廓检测,字符提取,简单的直方图字符识别!
  2. IOS之AutoLayout框架的使用
  3. python中输入17=x会引起错误_python新手常犯的17个错误
  4. C++11标准出现后,函数指针写法汇总
  5. Android开发之自定义控件的基本介绍(附源码)
  6. 一个java源文件允许_一个Java源文件中最多只能有一个class定义
  7. Android ble covana,I’m A Lie
  8. 美汽车销售商使用RFID汽车,加快销售速度
  9. centos7 安装rabbitMQ3.6.6
  10. 【VLC-Android】vlc-android简例