使用java的java.lang.instrument.Instrumentation来测试各个不同类型占用的内存空间。中间有些波折,最后使用最直接将所有类都放到同一个目录下,不使用IDE生成的目录结构,完成了相关的测试。
1. 编译Tools类
javac SizeOfObject.java
2. 编辑META-INF(文件内部内容)
Premain-Class: SizeOfObject
3. 将SizeOfObject和META-INF一起打到jar包中
jar cvfm java-agent-sizeof.jar META-INF/MANIFEST.MF .
4. 编译测试类
javac Main.java
5. 运行测试类
java -javaagent:java-agent-sizeof.jar Main
以下是一些执行例子可以帮助理解对象的组成 简单案例
/** 对象头(8) + 类指针(4) + padding(4) = 16 */
static class Empty{
}
/** 对象头(8) + 类指针(4) + a(4) = 16 */
static class A {
int a;
}
/** 对象头(8) + 类指针(4) + a(4) + b(4) + padding(4) = 24 */
static class B {
int a;
int b;
}
/** 对象头(8) + 类指针(4) + a(4) + b(4) + c(4) = 24 */
static class C {
int a;
int b;
int c;
}
/** 对象头(8) + 类指针(4) + a(4) + b(4) + c(4) + d(4) + padding(4) = 32 */
static class D {
int a;
int b;
int c;
int d;
}
上述例子执行截图
复杂案例
static class ObjectMultiA {
String str; // 4
int i1; // 4
byte b1; // 1
byte b2; // 1
int i2; // 4
Object obj; //4
byte b3; // 1
}
内存占用:对象的多个属性,虚拟机中会先按照以下顺序进行排序: 从长到短排列,引用排最后: long/double –> int/float –> short/char –> byte/boolean –> Reference。
按照以上原则,可以算出该对象的内存占用为: 8(_mark) + 4(oop指针) + 4(i1) + + 4(i2) + 1(b1) + 1(b2) + 1(b3) + 1(padding) + 4(str) + 4(obj) = 32
执行前截图:
执行后截图
代码GitHub地址: