7.jvm对象内存布局

目录

概述

jvm对象内存布局详解。

相关文章在此总结如下:

文章 地址
jvm基本知识 地址
jvm类加载系统 地址
双亲委派模型与打破双亲委派 地址
运行时数据区 地址
运行时数据区-字符串常量池、程序计数器、直接内存 地址
jvm中对象创建流程与内存分配 地址

对象里的三个区

对象里有啥?

对象头

对象头:8字节,如果是数组12字节(记录数组长度,占4字节)

  • 标记字段:存储对象运行时自身数据

    • 默认:对象Hashcode、GC分代年龄、锁状态
    • 存储数据结构并不是固定的
  • 类型指针:对象指向类元数据的指针

    • 开启指针压缩占4字节、不开启8字节 (jdk1.6之后默认是开启的)
  • 数组长度:如果是数组,则记录数组长度,占4个字节

  • 对其填充:保证数组(针对的是数组)的大小永远是8字节的整数倍

    复制代码
                        32位Markword是可变的数据结构,对象头总大小固定8字节

Markword 占4个字节,共32位。

复制代码
					64位Markword是可变的数据结构,对象头总大小固定12字节

验证

打印空对象的内存而已信息

代码
xml 复制代码
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

执行代码

java 复制代码
package com.fun.info;

import org.openjdk.jol.info.ClassLayout;

public class ObjLock {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println("new Object:"+ ClassLayout.parseInstance(o).toPrintable());
    }
}
控制台输出
分析
  • 首先对象头是包含 Markword类型指针 这两部分信息
  • 开启指针压缩的情况下,存放 Class 指针的空间大小是4字节,Markword是8字节,对象头为12个字节
  • 新建 Object 对象,会在内存占用16个字节,其中 Header 占12个(Markword 占8个 + ClassPoint 占 4个),没有实例数据,补充对齐 4 个字节

验证2

基本数据类型和包装类的内存占用情况

数据类型 内存占用 (byte)
boolean 1
byte 1
short 1
char 2
int 4
float 4
long 8
double 8
Boolean 4
Byte 4
Short 4
Character 4
Integer 4
Float 4
Long 4
Double 4
代码
java 复制代码
package com.fun.info;

import org.openjdk.jol.info.ClassLayout;

public class ObjLock2 {
    public static void main(String[] args) {
        Student o = new Student();
        System.out.println("new Object:"+ ClassLayout.parseInstance(o).toPrintable());
        o.setAge(10);
        o.setFlag(true);
        o.setName("abc");
        System.out.println("赋值 new Object:"+ ClassLayout.parseInstance(o).toPrintable());

    }

    static class Student{
        private boolean flag;
        private int age;
        private String name;

        public boolean isFlag() {
            return flag;
        }

        public void setFlag(boolean flag) {
            this.flag = flag;
        }
        
        public void setAge(int age) {
            this.age = age;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
控制台输出


总结: 对象从创建,对象的大小就已确定了。

实例数据

对象内部的成员变量

对其填充

8字节对象,保证对象大小是8字节的整数倍。

访问对象

如何访问对象?


两种方式如上两图:

  • 1.句柄
  • 2.直接指针

结束

至此,jvm对象内存布局就说得明明白白了,如有疑问,欢迎评论区留言。

相关推荐
1.01^10004 小时前
[5-01-01].第04节:初识字节码文件 - 字节码文件作用
jvm
找不到、了7 小时前
JVM核心知识整理《1》
jvm
L.EscaRC9 小时前
面向 Spring Boot 的 JVM 深度解析
jvm·spring boot·后端
学到头秃的suhian1 天前
JVM-类加载机制
java·jvm
NEFU AB-IN1 天前
Prompt Gen Desktop 管理和迭代你的 Prompt!
java·jvm·prompt
唐古乌梁海2 天前
【Java】JVM 内存区域划分
java·开发语言·jvm
众俗2 天前
JVM整理
jvm
echoyu.2 天前
java源代码、字节码、jvm、jit、aot的关系
java·开发语言·jvm·八股
代码栈上的思考2 天前
JVM中内存管理的策略
java·jvm
thginWalker2 天前
深入浅出 Java 虚拟机之进阶部分
jvm