对象的内存布局

使用JavaAgent测试Object的大小

观察虚拟机配置

java -XX:+PrintCommandLineFlags -version

对象创建过程

  • class loading
  • class linking(verification, preparation, resolution)
  • class initializing
  • 申请对象内存
  • 成员变量赋默认值
  • 调用构造方法<init>

成员变量顺序赋初始值,执行构造方法语句

普通对象

对象头:markword  8
ClassPointer指针:-XX:+UseCompressedClassPointers 为4字节 不开启为8字节
实例数据

  • 引用类型:-XX:+UseCompressedOops 为4字节 不开启为8字节
  • Oops Ordinary Object Pointers

Padding对齐,8的倍数

数组对象(比普通对象多了一个数组长度)

对象头:markword 8
ClassPointer指针同上
数组长度:4字节
数组数据
对齐 8的倍数

实验

新建项目ObjectSize (1.8)
创建文件ObjectSizeAgent

package com.test.jvm.agent;
import java.lang.instrument.Instrumentation;
   
public class ObjectSizeAgent {
    private static Instrumentation inst;
   
    public static void premain(String agentArgs, Instrumentation _inst) {
        inst = _inst;
    }
    public static long sizeOf(Object o) {
        return inst.getObjectSize(o);
    }
}

src目录下创建META-INF/MANIFEST.MF

Manifest-Version: 1.0
Created-By: test.com
Premain-Class: com.test.jvm.agent.ObjectSizeAgent

注意Premain-Class这行必须是新的一行(回车 + 换行),确认idea不能有任何错误提示
打包jar文件
在需要使用该Agent Jar的项目中引入该Jar包,project structure - project settings - library 添加该jar包
运行时需要该Agent Jar的类,加入参数:

 -javaagent:C:workijprojectsObjectSizeoutartifactsObjectSize_jarObjectSize.jar

如何使用该类

package com.test.jvm.c3_jmm;
import com.test.jvm.agent.ObjectSizeAgent;
      
public class T03_SizeOfAnObject {
    public static void main(String[] args) {
        System.out.println(ObjectSizeAgent.sizeOf(new Object()));
        System.out.println(ObjectSizeAgent.sizeOf(new int[] {}));
        System.out.println(ObjectSizeAgent.sizeOf(new P()));
    }
      
    private static class P {
                        //8 _markword
                        //4 _oop指针
        int id;         //4
        String name;    //4
        int age;        //4
      
        byte b1;        //1
        byte b2;        //1
      
        Object o;       //4
        byte b3;        //1      
    }
}

markword64位

hashcode部分

没有重写的hashcode,31位hashcode,称之为identityHashCode

为什么GC年龄默认为15,最大为15

Hotspot开启内存压缩的规则(64位机)

  • 4G以下,直接砍掉高32位
  • 4G - 32G,默认开启内存压缩 ClassPointers Oops
  • 32G,压缩无效,使用64位

内存并不是越大越好

IdentityHashCode的问题

当一个对象计算过identityHashCode之后,不能进入偏向锁状态

https://cloud.tencent.com/developer/article/1480590

https://cloud.tencent.com/developer/article/1484167

https://cloud.tencent.com/developer/article/1485795

https://cloud.tencent.com/developer/article/1482500

对象定位

https://blog.csdn.net/clover_lily/article/details/80095580

  1. 句柄池
  2. 直接指针
论读书
睁开眼,书在面前
闭上眼,书在心里
原文地址:https://www.cnblogs.com/YC-L/p/14411930.html