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对象内存布局就说得明明白白了,如有疑问,欢迎评论区留言。

相关推荐
abc小陈先生1 小时前
JVM类加载
jvm
小马爱打代码11 小时前
Minor GC与Full GC分别在什么时候发生?
jvm
alden_ygq15 小时前
当java进程内存使用超过jvm设置大小会发生什么?
java·开发语言·jvm
多敲代码防脱发18 小时前
导出导入Excel文件(详解-基于EasyExcel)
java·开发语言·jvm·数据库·mysql·excel
北漂老男孩1 天前
JVM对象头中的锁信息机制详解
jvm
黄雪超1 天前
JVM——方法内联之去虚化
java·开发语言·jvm
xinxiyinhe1 天前
内存泄漏与OOM崩溃根治方案:JVM与原生内存池差异化排查手册
java·开发语言·jvm
PgSheep1 天前
深入理解 JVM:StackOverFlow、OOM 与 GC overhead limit exceeded 的本质剖析及 Stack 与 Heap 的差异
jvm·面试
意倾城1 天前
JVM 如何优化 31 * x 为 (x << 5) - x?
java·jvm
LUCIAZZZ2 天前
JVM之内存管理(一)
java·jvm·spring·操作系统·springboot