Java对象存储内存布局详解

Java对象存储内存布局详解

Java 是一门面向对象的编程语言,因此在 Java 程序中创建对象是很常见的。在 Java 虚拟机(JVM)中,对象在内存中是如何存储和布局的呢?接下来我们将详细介绍 Java 对象存储内存布局的实现。

Java对象存储

Java 对象有两种主要的存储区域:堆和栈。

  1. 堆:是 Java 程序中最常见的内存区域,用来存储所有的对象和数组。所有的线程共享 Java 堆。

  2. 栈:是线程私有的内存区域。它用来存储线程运行时的栈帧。每个栈帧(Stack Frame)存储一个方法(Method)的局部变量表、操作数栈和帧数据(Frame Data)。

Java对象内存布局

Java 对象在内存中的布局由三部分组成:对象头(Header)、实例数据(Instance data)和对齐填充(Padding)。

对象头(Header)

对象头是对象在内存中的开头部分,包含两个部分的数据:标记字(Mark Word)和类型指针(Klass Pointer)。

  1. 标记字(Mark Word):包含了对象的哈希码、锁状态、分代年龄等信息。大多数的 JVM 实现使用32位的标记字,但在一些具有大内存支持的 JVM 中,可以使用64位标记字。

  2. 类型指针(Klass Pointer):用于指向对象所属的类,也称为 Class Metadata Address。

实例数据(Instance data)

实例数据是指对象实际存储的数据部分,即程序员自定义的成员变量和方法。

对齐填充(Padding)

对齐填充(Padding)是指填充字节,用于占用一定的内存,以对齐下一个对象。Java 要求对象在内存中的起始地址必须是8的倍数,因此为了达到这个要求,JVM需要额外的填充一些字节。

示例说明

下面两个示例用于说明 Java 对象的内存布局。

示例一

public class Test {
    private int i;
    private Object obj;
}

对于这个示例,Test 类实例化后占用的内存空间如下:

对象头:markword(32位)+ klass pointer(32位)= 8字节
实例数据:int i(4字节)+ object obj(4字节)= 8字节
对齐填充:不需要填充
--------------------------------------
总共:8字节

示例二

public class Test {
    private int i;
    private Object obj;
    private byte b;
}

对于这个示例,Test 类实例化后占用的内存空间如下:

对象头:markword(32位)+ klass pointer(32位)= 8字节
实例数据:int i(4字节)+ object obj(4字节)+ byte b(1字节)= 9字节
对齐填充:填充3字节
--------------------------------------
总共:20字节

对于这两个示例,我们可以看到对象头和实例数据不难理解,重点是对齐填充的理解,这是因为按内存对齐要求,每个对象在内存中的数值地址都应该是8的倍数,如此可能会带来空间浪费。因此,jvm会通过对齐填充的方式,来补齐空间,保证每个对象的内存地址都能够是8的倍数,达到了对性能的优化效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java对象存储内存布局详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • MyBatis几种不同类型传参的方式总结

    Sure! MyBatis几种不同类型传参的方式总结 在MyBatis中,传参是非常重要的一部分。正确的传递参数对于正确的执行SQL语句非常关键。本文将介绍MyBatis的不同传参方式及其使用示例。 1. 基本参数类型 基本参数类型指的是Java中的简单数据类型,如int、String、float等,也包括其相应的包装类型。在Mapper文件中,可以直接使用…

    Java 2023年5月20日
    00
  • Java ClassCastException异常解决方案

    接下来我将为你详细讲解解决Java中的ClassCastException异常的完整攻略,让你能够更好地理解如何找到并解决这种异常。 什么是ClassCastException异常 在Java程序中,当试图将一个对象强制向下转型为其他类型,但发现这个对象的实际类型与转型类型不一致时,就会抛出ClassCastException异常。例如: // 定义一个父类…

    Java 2023年5月27日
    00
  • Myeclipse中hibernate自动创建表的方法

    下面是MyEclipse中Hibernate自动创建表的方法的完整攻略。 准备工作 在MyEclipse中安装Hibernate插件 在MyEclipse中创建Java工程 导入Hibernate相关的jar包 配置Hibernate的配置文件hibernate.cfg.xml 使用Hibernate自动创建表 在实体类中添加@Table、@Column等注…

    Java 2023年5月20日
    00
  • 深入理解Java注解类型(@Annotation)

    深入理解Java注解类型(@Annotation) 引言 Java注解(Annotation)是Java语言中非常常见的一种特殊的语法元素,它可以为Java程序的编写提供更加丰富、灵活的方式。在本篇文章中,我们将详细地了解Java注解的定义、分类、使用方法及其在实际开发中的应用。 定义 Java注解(Annotation)是Java语言中的一种特殊语法元素,…

    Java 2023年5月20日
    00
  • Maven插件docker-maven-plugin的使用

    下面是关于” Maven插件docker-maven-plugin的使用”的完整攻略,包含了插件的介绍、使用方式和示例。 Maven插件docker-maven-plugin简介 docker-maven-plugin是一款Maven插件,它可以让你使用 Maven 来构建、运行和管理 Docker 镜像。它基于 Docker Java API 和 Dock…

    Java 2023年5月19日
    00
  • JavaWeb中使用JavaMail实现发送邮件功能实例详解

    下面我将为你详细讲解“JavaWeb中使用JavaMail实现发送邮件功能实例详解”的完整攻略。 1. 前置技能 在使用JavaMail之前你需要具备以下知识: Java基础知识:Java语法、类、对象、方法、接口、异常、集合框架等 SMTP/POP3协议:SMTP是发送邮件的协议,POP3是接收邮件的协议,具体可以通过网络搜索或者参考相关文档进行了解 2.…

    Java 2023年6月15日
    00
  • 自己动手写的mybatis分页插件(极其简单好用)

    下面是自己动手写的mybatis分页插件的完整攻略。 1. 目标 我们的目标是自己手写mybatis分页插件,以便在查询大数据量时能够更加高效地进行分页操作。 2. 环境准备 本教程的示例环境如下: 操作系统:Windows 10 开发工具:IntelliJ IDEA JDK版本:1.8 mybatis版本:3.4.6 3. 新建项目 首先,我们需要新建一个…

    Java 2023年5月19日
    00
  • IDEA下创建SpringBoot+MyBatis+MySql项目实现动态登录与注册功能

    下面我将为您详细讲解“IDEA下创建SpringBoot+MyBatis+MySql项目实现动态登录与注册功能”的完整攻略。 环境准备 首先,我们需要在本地环境中安装好如下软件: JDK、IDEA、Maven、MySQL等开发环境 SpringBoot、MyBatis、MySql等相关依赖包 创建SpringBoot项目 步骤如下: 打开IDEA,选择 Cr…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部