一、对象创建过程
1).loading:加载,将对象的class文件加载到内存
2).linking(verification、preparation、resolution)
verification:校验calss文件的格式是否符合虚拟的规范
preparation:将静态变量赋默认值
resolution:将类、方法、属性等符号引用解析为直接引用
3).initializing:将静态变量设为初始值,同时执行静态语句块
4).申请对象内存
5).成员变量赋默认值
6).调用构造方法<init>
1)成员变量赋初始值
2)执行构造方法语句
二、对象在内存中的布局
1).普通对象
1)对象头:markwork 8字节
2)ClassPointer指针: -XX:+UseCompressedClassPointers为4字节,不开启为8字节
3)实例数据
1)引用类型: -XX:+UseCompressedOops为4字节,不开启为8字节
Oops Ordinary Object Pointers
4)Padding对齐,8的倍数
2).数组对象
1)对象头:markwork 8字节
2)Classpointer指针
3)数组长度:4字节
4)数据数据
5)对齐 8的倍数
三、打印对象大小
1.写一个代理类,单独一个工程,主要是通过Instrumentation 的getObjectSize方法,来计算对象大小
public class ObjectSizeAgent {
private static Instrumentation instr;
public static void premain(String args, Instrumentation inst) {
instr = inst;
}
public static Long getSizeOf(Object object) {
if (instr == null) {
throw new IllegalStateException("Instrumentation is null");
}
return instr.getObjectSize(object);
}
}
2.代理类下载地址
https://github.com/dengchao3119/springcloud.git
3.打成jar包,引入到其他项目中
略
4.写一个JVM_012_ObjectSize类
把打成jar包的代理类引入的项目中,调用getSizeOf()方法
public class JVM_012_ObjectSize {
public static void main(String[] args) {
System.out.println(ObjectSizeAgent.getSizeOf(new Object()));
System.out.println(ObjectSizeAgent.getSizeOf(new int[]{}));
System.out.println(ObjectSizeAgent.getSizeOf(new P()));
}
/**
* -XX:+UseCompressedClassPointers 压缩指针
* -XX:+UseCompressedOops 压缩普通对象
* Oops = ordinary object pointers(普通对象指针)
*/
private static class P{
//8 markwork
//4 ClassPorinter
int id; //4
String name; //4
int age; //4
byte b1; //1
byte b2; //1
long c; //8
}
}
5.启动JVM_012_ObjectSize
-javaagent:D:\mycode\objectSize\target\objectSize-1.0-SNAPSHOT.jar
-javaagent后面加的是代理类jar包的位置,也可在后面加上下面两行代码,试试看打印对象的大小是否有变化
小编也有自己微信公众号:“JAVA菜鸟程序猿”,喜欢的可以关注下哦!