写在前面的话:译者本身能力有限,不能逐字逐句地翻译。本人翻译的目标是为了能给大家说得简单明了,所以会采取意译的方法。如果有措辞不正确或不好的地方,讲大家不吝赐教,谢谢!
OOPs 与 Compressed OOPs
每一个Java对象在堆中被表示为一个普通对象指针(Ordinary Object Pointer,OOP)。每个OOP是一个指向Java堆内空间的一个受管理(控制)的指针。指向的空间是Java进程内的虚拟地址表示的一块连续的空间。
一般情况下,OOP的大小与宿主机的指针一样,也就是说在LP64数据模型系统中,OOP的大小是64位的。在一个ILP32数据模型系统中,堆的最大空间要小于4G。这有点小,对于很多应用来说不够用。
OOP指针指向的Java对象在堆中是以8字节地址边界对齐的。Compressed OOPs(压缩过的指针——好土的名字吧,请原谅笔者的翻译,水平有限呀)在Java虚拟机的堆中,很多时候(而不是所有情况都是),用32位的对象位移(object offset)来表示64位的字节位移(byte offset)[笔者认为,这句话可以认为:用32位的对象指针来替代64位对象指针]。因为Compressed OOP中的offset(笔者认为翻译成“位移”反而更让人搞不懂)是object offset,而不是byte offset。32位的object offset可以寻址的范围是4,000,000,000*objects*,也就是32GB的堆内空间。[在这里作者说得很让人发晕,不过笔者认为他就说了一件事儿:以前普通对象指针是按字节计算对象在内存中位置的,而现在Compressed OOPs则是按8字节为单位计算的。这也是为什么32位字节的指针本来只能寻址4GB的空间,现在就达到32GB了。实现这个技术的基础就在于段落第一句,因为Java对象在64位机器中是以8字节地址边界对齐的。] 为了能够正确找到对象的位置,Compressed OOPs的值需要乘以8再加上Java堆的基址才可以。使用compressed OOPs技术的对象的大小和在ILP32模式下的对象大小一般大。
Compressed OOP在Java v6u23及以后的版本中默认是打开的。在Java7中,在64位JVM中若启动java进程时”-Xmx”没有指定值或者其值小于32GB时,Compressed OOP技术是默认打开的。JDK6中6u23之前的版本需要在启动Java进程中添加“-XX:+UserCompressedOops”选项才能够使用这个特性。具体见这个链接:(http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html)
先简单地说下SampleClass
在这篇文章中,我们将用一个样本类——SampleClass,正如其名一样是个样例——为例来探索下其对象访问、其属性地layout(部局)等等。这个类很简单,其包含3个基本类型变量,并且继承SampleBaseClass类以说明继承反映在内存layout上是什么样子的。类的定义如下(这些类的代码也可以在github上找到):
public final class SampleClass extends SampleBaseClass {
private final static byte b = 100;
private int i = 5;
private long l = 10;
public SampleClass() {
}
public SampleClass(int i, long l) {
this.i = i;
this.l = l;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public long getL() {
return l;
}
public void setL(long l) {
this.l = l;
}
public static byte getB() {
return b;
}
}
public class SampleBaseClass {
protected short s = 20;
}
To Be Continued…