JVM(八):Java 对象模型

本文将学习对象是如何创建的,对象的内存布局,以及如何定位访问一个对象。

对象创建

当虚拟机碰到一个new指令时,首先检查指令参数能否在常量池中定位一个类的符号引用,并且检查该符号引用对应的类是否已经被加载,解析和初始化。当一切都确定完成后,JVM就会为其分配内存(需要分配的内存大小在现在就已经确定,在 下面 中详细讲述)。

对象的内存分配方式分为以下两种:

  1. 指针碰撞,这种分配方式建立在堆内已用空间和剩余空间是完整的,这样的话,在两者之间放置一个指针作为分界点的指示器即可,在分配空间时,只需要移到一下指针位置就好了。
  2. 空闲列表,如果 JVM 内的空间不是规整的,那么就只能采用此方案了。此时 JVM 会维护一个列表,记录了哪些内存块是可用的,在分配的时候划一个大小足够的区域给对象实例,并更新列表即可。

以上两种方式采取哪种,取决于 Java 堆是否工整,而堆是否工整又取决于垃圾回收算法是否具有整理功能。

对象模型

前面说到对象在创建时就已经确定了内存大小,那么 JVM 是怎么确定对象的大小呢?对象在内存中又是如何存储的呢?

在 JVM 中 Java 的对象模型分为以下3块,对象头实例数据对齐填充,下面就让我们来分别介绍一下。

对象头

对象头的数据包括两部分。一部分是用于存储自身运行时数据,这部分数据被官方称为“Mark World”。其中存储数据包括Hashcode、GC 分代年龄、锁状态标志、线程持有锁、偏向线程ID、偏向时间戳等等

对象头的另外一部分是 类型指针,即对象指向其类元数据的指针。通过这个指针,我们就可以知道该实例属于哪个类。

实例数据

实例数据就是对象真正存储的有效信息,也就是代码中定义的各种类型的字段内容,不论是父类的还是子类的,都需要记录下来。其存储顺序受到虚拟机分配策略和定义顺序影响。

对齐填充

对象填充不是必要数据。在模型中只是起到占位符的作用。因为 HotSpot 要求对象起始地址必须是8的整数倍,这样在实例数据达不到要求的时候,就需要通过对齐填充来补齐。

对象访问

对象访问的方式是通过引用来定位、访问。但 JVM 规范并没有强制要求该通过何种方式使用引用,因此具体实现还是要依赖与具体虚拟机类型。

不过目前的主流访问方式就是以下两种。

  1. 使用引用。其在 Java 堆中会独立创建一个句柄池,引用指向句柄,而句柄指向实例数据和类型数据。

使用这种方式来访问的优点是稳定,例如在 GC 后,实例数据需要移动,那么只需要修改句柄池中的内容即可,reference 指向的是稳定的位置,缺点是这种方式需要二次定位,速度较慢。

  1. 直接指针访问,引用直接堆中对象地址,堆中保存了实例数据和类型数据指针,指针直接指向另外存储的类型数据。

使用这种方式的优点是访问实例数据快,因为 reference 指向直接的对象,省去了一次内存定位开销。但缺点就是不够稳定,在对象移动后,reference 也需要修改值。

具体采用何种,不同的虚拟机有不同的实现,因为两者各有千秋,并没有强烈的优缺点,因此不同情况不同处理即可。

总结

在本文中介绍了对象的本质模型是什么,以及对象是如何创建和访问使用的,与上文的 JVM 内存模型结合来看,可以让我们了解内存泄露产生的原因,有助于高效地理解使用 Java 的自动内存管理机制。

文章在公众号“iceWang”第一手更新,有兴趣的朋友可以关注公众号,第一时间看到笔者分享的各项知识点。谢谢!笔芯!

本系列文章主要借鉴自《深入分析 Java Web 技术内幕》和《深入理解 Java 虚拟机-JVM 高级特性与最佳实践》。

JVM(八):Java 对象模型的更多相关文章

  1. 【JVM】JVM内存结构 VS Java内存模型 VS Java对象模型

    原文:JVM内存结构 VS Java内存模型 VS Java对象模型 Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清 ...

  2. 【转】JVM内存结构 VS Java内存模型 VS Java对象模型

    JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途. 其中有些区域随着虚拟机进程的启动而 ...

  3. java内存结构JVM——java内存模型JMM——java对象模型JOM

    JVM内存结构 Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途.其中有些区域随着虚拟机进程的启动而存在,而有些区 ...

  4. JVM内存结构 VS Java内存模型 VS Java对象模型

    前面几篇文章中, 系统的学习了下JVM内存结构.Java内存模型.Java对象模型, 但是发现自己还是对这三者的概念和区别比较模糊, 傻傻分不清楚.所以就有了这篇文章, 本文主要是对这三个技术点再做一 ...

  5. 区分 JVM 内存结构、 Java 内存模型 以及 Java 对象模型 三个概念

    本文由 简悦 SimpRead 转码, 原文地址 https://www.toutiao.com/i6732361325244056072/ 作者:Hollis 来源:公众号Hollis Java 作 ...

  6. Java内存模型、JVM内存结构和Java对象模型

    JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途.其中有些区域随着虚拟机进程的启动而存 ...

  7. JVM内存结构、Java内存模型和Java对象模型

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚.比如本文要讨论的JVM内存结构.Java内存模型和Java对象模型 ...

  8. [转帖]JVM内存结构 VS Java内存模型 VS Java对象模型

    JVM内存结构 VS Java内存模型 VS Java对象模型 https://www.hollischuang.com/archives/2509 Java作为一种面向对象的,跨平台语言,其对象.内 ...

  9. java对象模型

    java对象模型其实就是JVM中对象的内存布局.一个对象本身内在结构的描述信息以字节码的方式存储在方法区中(参见java内存区域),说白了就是class文件.那么如何获取到对象的class信息呢?虚拟 ...

随机推荐

  1. WPF控件TextBlock中文字自动换行

    原文:WPF控件TextBlock中文字自动换行 在很多的WPF项目中,往往为了追求界面的美观,需要控制控件中文字的换行显示,现对TextBlock控件换行的实现方式进行总结,希望大家多多拍砖!!! ...

  2. 让用户使用第三方账号(如亚马逊账号)接入AWS IoT系统

    我们想象这么一个IoT应用场景:厂商A使用AWS IoT来开发物联网解决方案,那么A把设备卖给用户的时候,需要使用户能够登入AWS IoT系统来控制其购买的A的设备,也就是说给用户分配适当的权限.下面 ...

  3. centos 6.5 搭建ftp 服务器(vsftpd的配置文件说明)

    0x00 如何快速的搭建简易的资源发布站 开启简易的python http服务器 1 2 cd /home/your_path python -m SimpleHTTPServer 8000 开启防火 ...

  4. Android零基础入门第11节:简单几步带你飞,运行Android Studio工程

    原文:Android零基础入门第11节:简单几步带你飞,运行Android Studio工程 之前讲过Eclipse环境下的Android虚拟设备的创建和使用,现在既然升级了Android Studi ...

  5. 【UWP开发】uwp应用安装失败

    原文:[UWP开发]uwp应用安装失败 编译出了uwp应用.appx之后双击打开,报错你需要为此应用包而安装的新证书,或者是带有受信任证书的新应用包.系统管理员或应用开发人员可以提供帮助.证书链在不受 ...

  6. Qt的模态对话框和非模态对话框 经常使用setAttribute (Qt::WA_DeleteOnClose)

    模态对话框就是指在子对话框弹出时,焦点被强行集中于该子对话框,子对话框不关闭,用户将无法操作其他的窗口.非模态相反,用户仍然可以操作其他的窗口,包括该子对话框的父对话框. 如果从线程角度来讲,模态对话 ...

  7. 虚拟机安装 ubuntu 后,更新源无效,以及无法联网安装软件的问题

    问题: 虚拟机安装 ubuntu 后,更新源无效,以及无法联网安装软件: 错误提示: Err http://security.ubuntu.com/ubuntu/ trusty-security/un ...

  8. WCF学习--我的第一个WCF例子

    Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口. 通信双方的沟通方式,由合约来订定.通信双方所 ...

  9. spring boot单元测试之RestTemplate(三)——api详解

    本篇内容来自翟永超的<Springcloud微服务实战>,转载请注明. 一.GET请求 在RestTemplate中,对GET请求可以通过如下两个方法进行调用实现. 第一种:getForE ...

  10. 打印第二列为oldboy的第一列内容(awk,grep,sed用法)

    [root@goldtest ~]# cat ip.log 10.0.0.1 oldboy 10.0.0.2 oldgirl 10.0.0.4 tingting 10.0.0.4 oldboy old ...