在之前的文章中,简要说了一下kvm中的对象头,kvm中的对象头和jvm中的不完全相同.本文进行详细介绍.
在我们的VM中,内存中的每个堆分配结构前面都有一个对象头,它提供关于对象类型和大小的详细信息。头的长度是一个字(32位)。
如图:
这里有一定注意的是,在kvm中是没有对象句柄。因此,与许多其他JVM实现(openjdk)不同,所有内存引用都是直接的,而不是间接的。
对象头出于管理目的,其是包含重要管理信息的32位结构。如图所示:
length保存的是对象的长度,不包括对象头。例如,length=1表示对象的数据区域是4个字节。对象的最小物理大小为8字节(4字节头+4字节数据)。
类型字段保存对象的垃圾收集类型,指示垃圾收集器在垃圾收集时正确扫描对象的数据字段。垃圾收集类型(gct_*)定义如下:
typedef enum {
GCT_FREE = 0,
/* 没有指针指向该对象,可以在gc环节中忽略 */
GCT_NOPOINTERS,
/* java级别的对象,可能有多个指针指向该对象*/
GCT_INSTANCE,
GCT_ARRAY,
GCT_OBJECTARRAY,
/* 只在使用静态区域的情况下使用,默认是不使用的 */
GCT_METHODTABLE,
/* vm内部对象,可能有多个指针指向该对象 */
GCT_POINTERLIST,
GCT_EXECSTACK,
GCT_THREAD,
GCT_MONITOR,
/* 在registerCleanup中被使用*/
GCT_WEAKPOINTERLIST,
/* 对java.lang.ref.WeakReference的支持 */
GCT_WEAKREFERENCE
} GCT_ObjectType;
静态位除了在Palm上之外是未使用过的。在原始的kvm收集器中,该位用于表示在静态堆中分配了一个对象,即该对象是不可移动的
标记位用于在垃圾收集期间标记活动(非垃圾)对象。在正常程序执行期间,每个堆对象中的该位应该始终为0。
设置对象头
设置对象头是在mallocHeapObject方法中设置的.其中代码如下:
// 分配指定大小的内存空间
thisChunk = allocateFreeChunk(realSize);
if (thisChunk == NULL) {
// 如果分配失败的话,则进行垃圾收集后,再次进行分配,如果分配失败的话,则返回null
garbageCollect(realSize); /* So it knows what we need */
thisChunk = allocateFreeChunk(realSize);
if (thisChunk == NULL) {
return NULL;
}
}
/*
* 按照type参数来设定新配置的object header中type字段的值.
*/
*thisChunk |= (type << TYPE_SHIFT);
本文的内容比较简单,都是基于j2me_cldc/kvm/VmCommon/h/garbage.h而来.