您的位置:首页 > 理论基础 > 计算机网络

http://www.dewen.net.cn/q/6120/如何获取Java对象的大小

2016-03-10 16:13 459 查看
http://www.dewen.net.cn/q/6120/如何获取Java对象的大小

kenvi
1 票
kenvi 2078
在C或者C++里经常会通过sizeof来计算一个对象所占空间的大小,但是对于java对象,如何获得其大小呢?

评论 (1) • 举报 (0) • 分享 • 链接 • 2012-09-26 
1 http://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html?page=2 – Darcy 2012-09-27
添加评论...

brayden认证专家
0 票
brayden6562
用Unsafe, 主要代码引自: http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
@Test
public void testea() throws Exception{
System.out.println(sizeOf1(new Object()));
System.out.println(sizeOf1(new TestTesteTestB()));
}

private long sizeOf(Object o) throws Exception {
Unsafe u = getUnsafe();
HashSet<Field> fields = new HashSet<Field>();
Class c = o.getClass();
while (c != Object.class) {
for (Field f : c.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) == 0) {
fields.add(f);
}
}
c = c.getSuperclass();
}
long maxSize = 0;
for (Field f : fields) {
long offset = u.objectFieldOffset(f);
System.out.println("sdfsd"+offset);
if (offset > maxSize) {
maxSize = offset;
}
}
return ((maxSize / 8) + 1) * 8;
}

private Unsafe getUnsafe() throws Exception {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
return (Unsafe) theUnsafe.get(null);
}

我的运行结果:
8
32

看了一些资料, 这里说一下我的理解:
1). Java对象实例大小都是8的倍数;
2). 开头为 4字节java对象头, 4字节为 类对象(Klass) 的引用; 然后是对象 实例成员(field);
3). 对象 实例成员的存储, java不一定按照类定义的顺序, 为了优化存储空间, 会做重排;
4). 为了对齐, 可能会做padding.

这样, 上面的sizeof中, 先拿到偏移对大的那个field, 再做padding((maxSize / 8) + 1) * 8;); 从而拿到对象的大小. Object对象为8个字节, 这已经是最小的了(因为其没有额外的field定义).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: