Java对象存储内存布局详解

yizhihongxing

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日

相关文章

  • IDEA中创建maven项目引入相关依赖无法下载jar问题及解决方案

    下面是详细讲解“IDEA中创建maven项目引入相关依赖无法下载jar问题及解决方案”的完整攻略。 问题描述 在使用IntelliJ IDEA创建Maven项目时,通过编辑POM.XML文件引入相关依赖,但是发现IDEA无法下载所需的JAR包,导致项目无法编译运行。 可能原因 上述依赖库不存在。 依赖库被墙了。 IDEA配置问题。 解决方案 方案一:更改本地…

    Java 2023年5月19日
    00
  • Java实现批量导出导入数据及附件文件zip包

    下面我来详细讲解一下“Java实现批量导出导入数据及附件文件zip包”的完整攻略。 一、准备工作 1.引入相关依赖 我们需要引入以下依赖: <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</ar…

    Java 2023年5月19日
    00
  • 探讨Java中最常见的十道面试题(超经典)

    让我来为你详细讲解“探讨Java中最常见的十道面试题(超经典)”的完整攻略。 前言 在面试Java相关职位时,经常会被问到一些非常经典的问题。本文将列举出Java中最常见的十道面试题,并为每个问题提供完整的解答,希望能够帮助你在面试时取得更好的成绩。 面试题1:Java中的“值传递”和“引用传递”有何区别? 在Java中,所有的参数传递都是“值传递”,也就是…

    Java 2023年5月24日
    00
  • 图文详解Java线程和线程池

    图文详解Java线程和线程池 什么是线程 线程是操作系统能够进行运算调度的最小单位。一个进程可以包含多个线程,线程共享进程资源,但是是CPU分配资源的独立单位。 Java中的线程 Java中的线程是使用Thread类对象来创建。Java中的线程有以下几种状态:新建状态、可运行状态、阻塞状态和死亡状态。在Java中,实现多线程有两种方式,一是继承Thread类…

    Java 2023年5月18日
    00
  • Java单例的写法详解

    Java中的单例模式,指的是确保一个类只有一个实例,并提供访问该实例的全局访问点。这在某些情况下非常有用,例如当有一个全局资源,如线程池、数据库连接池等,需要在应用程序的整个生命周期内保持一致时。下面是Java单例模式的写法详解。 懒汉式单例模式 实现方式 懒汉式单例模式是指在需要使用实例的时候才去创建,而不是在类加载时就创建。懒汉式单例模式可以通过两种方式…

    Java 2023年5月23日
    00
  • java进行文件读写操作详解

    Java进行文件读写操作详解 概述 Java支持文件的读写操作,通过读写文件能够实现各种常见的功能,比如读取配置文件、写入日志等。文件读写的过程中我们需要使用到Java中的IO类库,主要包括InputStream、OutputStream、Reader和Writer等。其中InputStream和OutputStream主要用于读写字节数据,Reader和W…

    Java 2023年5月20日
    00
  • Tomcat中catalina.out 和 catalina.log的区别和用途详解

    题目:Tomcat中catalina.out 和 catalina.log的区别和用途详解 概述 在Tomcat的日志输出中,经常出现catalina.out和catalina.log两个常用的日志文件,本篇攻略主要介绍这两个日志文件的区别和用途。 区别 在Tomcat中,catalina.out和catalina.log两个日志文件的区别主要表现在以下几个…

    Java 2023年6月2日
    00
  • 十三、JSP动作

    JSP动作(Action)是JSP页面中特殊的标识,可以在JSP中调用Servlet或JavaBean,也可以完成JSP页面的控制流程、变量的传递、构建自定义标签库等功能。JSP动作在JSP中是由尖括号包裹的标识,其中尖括号后面是关键词,关键词和它们的值都是用特殊的语法结构来定义的。本文将实现JSP动作的完整攻略。 1、JSP动作的类型 JSP动作主要分为三…

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