目录
- 概述
- 对象里的三个区
- 对象头
- 验证
- 代码
- 控制台输出
- 分析
- 验证2
- 代码
- 控制台输出
- 实例数据
- 对其填充
- 访问对象
- 结束
概述
jvm
对象内存布局详解。
相关文章在此总结如下:
文章 | 地址 |
---|---|
jvm基本知识 | 地址 |
jvm类加载系统 | 地址 |
双亲委派模型与打破双亲委派 | 地址 |
运行时数据区 | 地址 |
运行时数据区-字符串常量池、程序计数器、直接内存 | 地址 |
jvm中对象创建流程与内存分配 | 地址 |
对象里的三个区
对象里有啥?
对象头
对象头:8字节,如果是数组12字节(记录数组长度,占4字节)
-
标记字段:存储对象
运行时
自身数据- 默认:对象Hashcode、GC分代年龄、锁状态
- 存储数据结构并不是固定的
-
类型指针:对象指向类元数据的指针
- 开启指针压缩占4字节、不开启8字节 (jdk1.6之后默认是开启的)
-
数组长度:如果是数组,则记录数组长度,占4个字节
-
对其填充:保证数组(针对的是数组)的大小永远是8字节的整数倍
32位Markword是可变的数据结构,对象头总大小固定8字节
Markword 占4个字节,共32位。
64位Markword是可变的数据结构,对象头总大小固定12字节
验证
打印空对象的内存而已信息
代码
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
执行代码
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 |
代码
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对象内存布局就说得明明白白了,如有疑问,欢迎评论区留言。