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日

相关文章

  • 关于spring data jpa 模糊查询like的坑点

    好的。首先让我们讨论一下”关于Spring Data JPA模糊查询Like的坑点”的具体情况。 什么是Spring Data JPA模糊查询Like的坑点? 如果我们想使用Spring Data JPA执行模糊查询(例如使用LIKE操作符),我们需要注意一些事项。这些主要涉及到通配符的使用和查询条件的拼接。 通配符的使用 在使用LIKE操作符时,我们需要使…

    Java 2023年5月20日
    00
  • 如何使用Reactor完成类似Flink的操作

    使用Reactor完成类似Flink的操作可以分为以下几个步骤: 创建Flux或Mono:首先需要创建Flux或Mono,Flux表示可以产生多个数据流,Mono表示只能产生一个数据流; 转换Flux或Mono:可以使用map()、flatMap()、filter()等函数对Flux或Mono进行转换,获得想要的结果; 订阅Flux或Mono:最后需要订阅F…

    Java 2023年5月20日
    00
  • Mybatis如何通过接口实现sql执行原理解析

    Mybatis是一款使用Java对象与数据库之间的映射配置来处理原始SQL的轻量级ORM框架。它可以通过接口实现 SQL 执行原理,实现原理如下: 在Mybatis中,每个mapper接口都对应了一个mapper xml文件。在mapper xml文件中涵盖了众多的SQL语句。 当应用程序访问mapper接口中的方法时,Mybatis会根据方法名去查询map…

    Java 2023年5月20日
    00
  • 最新springboot中必须要了解的自动装配原理

    Spring Boot是一个基于Spring框架的快速开发框架,它通过自动装配来简化了Spring应用程序的配置。在最新的Spring Boot中,自动装配原理是必须要了解的。以下是最新Spring Boot中必须要了解的自动装配原理的完整攻略: 自动装配原理概述 自动装配是Spring Boot的核心特性之一,它通过自动扫描和自动配置来简化Spring应用…

    Java 2023年5月15日
    00
  • Java中关于子类覆盖父类的抛出异常问题

    Java中的异常处理机制是一个很重要的特性,可以帮助开发者更好的处理程序运行过程中可能出现的异常情况,使程序更加健壮和稳定。在子类覆盖父类的方法时,如果子类方法抛出的异常类型与父类方法不同,就会产生编译错误。本文将详细介绍Java中关于子类覆盖父类的抛出异常问题,并提供两个示例说明。 1. 子类覆盖父类抛出异常类型必须兼容 子类覆盖父类的方法时,抛出的异常类…

    Java 2023年5月27日
    00
  • MVC异常处理详解

    下面是关于“MVC异常处理详解”的完整攻略,包含两个示例说明。 MVC异常处理详解 在MVC(Model-View-Controller)架构中,异常处理是一个非常重要的问题。在应用程序中,可能会发生各种各样的异常,如空指针异常、数据库异常、网络异常等等。如果不进行适当的异常处理,这些异常可能会导致应用程序崩溃或者无法正常工作。本文将详细介绍如何在MVC架构…

    Java 2023年5月17日
    00
  • java中List、Array、Map、Set等集合相互转换

    下面为你讲解Java中List、Array、Map、Set等集合相互转换的完整攻略。 一、List与Array之间相互转换 1. 将List转换为数组 使用 List 的 toArray() 方法可以将 List 转换为数组。示例代码如下: List<String> list = new ArrayList<>(); list.add…

    Java 2023年5月27日
    00
  • jsp中调用java代码小结

    下面我会给出一个完整的“jsp中调用java代码”的攻略,分为以下几个步骤: 一、创建Java类及方法在Java中创建一个类,并在其中定义一个或多个方法,以便供JSP调用。类及方法应当按照Java语法规范编写,并尽量遵循业内最佳实践的要求。 二、打包Java类为jar包将Java类打包成jar包,然后将jar包放置到WEB-INF/lib目录下。这样JSP页…

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