[译]在运行时内存中的Java对象是怎么样的
(文章翻译自What do Java objects look like in memory during run-time?)
我们知道函数在内存中是作为一个活动记录栈来实现的。而且我们知道Java的方法在JVM栈中是作为一个帧栈来实现的并且在堆中被分配内存。
Java对象在堆中是什么样子的呢?一旦一个对象被放置到内存中,它就是一个序列的字节。
然后我们怎么知道到哪里去寻找一个指定的域呢?这是在编译器中有一个维护着每一个域的偏移量的内部表。
下面就是一个放置在内存的对象Base
B的例子,这个类中没有任何方法,而且方法的存储是下一个部分要讲的问题。
如果我们有另外的一个类Derived
(D)继承了类Base
。这个内存布局就像下面一样:
子对象和父对象拥有相同的内存布局,除非它需要更多的空间去存储新增加的域。指向D对象的B类型的指针A可以看到在开始出的对象B。因此,通过B的引用作用在D对象上的操作会是安全的而且没有必要检查B动态的指向什么。
下面就是相同的逻辑,方法可以被放置到对象的开始处。
但是,这种方法不是效率高的。如果一个类有很多的方法,然后每一个对象肯定会有O(M)的指针集。另外,每一个对象还需要为O(M)指针分配空间。这样就是是创建对象变得慢,而且对象更大。
优化的方式是针对一个特定的类实现的成员函数创建一个虚拟的数组指针表。为每一个类创建一个单独的虚拟表的实例而且让每个对象的指针存储指向这个虚拟表的指针。
上面就是优化的方式。