在之前的文章中,簡要說了一下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而來.