不安全的代码: 教你“随心所欲”地在内存中操作Java的类和对象(5)

5 篇文章 0 订阅
2 篇文章 0 订阅

[原文地址] https://zeroturnaround.com/rebellabs/dangerous-code-how-to-be-unsafe-with-java-classes-objects-in-memory/5/

域布局(Field layouts)与对齐(alignments)
Java与C/C++不同的是,它没有sizeOf操作符用来计算基本数据类型或对象在内存中占用了多少空间。当然这个操作符对于IO 操作、内存管理等等都有很大的用处。事实上,Java中有这样一个操作符是不合理的,因为基本数据类型的长度已经在语言规范中规定好了,而且Java中也不存在用于内存拷贝或指针操作的指针。

有两种方式定义一个类(其内属性)一共花费了多少内存空间。一种叫“浅大小(shallow size)”,另一种叫“深大小(deep size)”。浅大小指的是一个对象自己各个域所占空间大小的总和。假如对象中有另外一个对象的引用,则另一个对象的大小不会被计算在内。而深大小的计算方式则会将另一个对象的大小也计算在内。

在Sun Java虚拟机规范中规定,每个对象(除了数组类型)有一个2个字长的头部,一个字长的flag,和一个字长的指向对象的类的引用。当一个新对象通过"new Object()"被创建的时候,在队(heap)中就有8个字节空间被占用,用于2个字长的头部。

当一个类继承Object类时,空间占用情况将变得有点复杂,同时也变得有趣。在分配8字节之后,类中的属性将在heap中对齐。值得注意的是,它们并不是按其在类定义的顺序对齐的。

基本数据类型将以以下的顺序对齐:
  • double类型和long类型
  • int类型和float类型
  • short类型和char类型
  • boolean类型和byte类型
最后,其它类的对象引用类型将被对齐。JVM中对象引用大小是8字节大小。( http://blog.csdn.net/jiafu1115/article/details/7103022

举个例子:

class BooleanClass {
    byte a;
}

这个类的对象在内存中将占16字节,其中有7字节是空白填充(为了对齐)。
Header : 8 bytes
value of byte : 1 byte
padding : 7 bytes

再说OOP
一些有关OOP的基本内容在”OOPs和Compressed OOPs“部分已经讲过了。我们假设你已经知道JVM中OOP的相关术语了。我们进一步看一下OOPs。
一个OOP包含两个机器字(32位JVM中一个字是4字节,64字节JVM中是8字节)长度的域——”Mark“和”Klass“。这两个域之后是对象中的成员。值得一提的是,一个数组对象会有一个额外的字长头部在这些成员之前,就是数组的长度。”Mark“域在垃圾回收时会用(在mark-and-sweep的mark阶段会用),”Klass“则用于指向类的元信息的指针。无论是基本数据类型还是引用类型都在OOP的header部分之后(对象的引用当然也是OOP)。( http://www.infoq.com/articles/Introduction-to-HotSpot

未完待续。。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值