admin管理员组文章数量:1576359
本文介绍garbageCollectForReal中的第3步–markWeakPointerLists,第4步–markWeakReferences.
markWeakPointerLists
其代码如下:
static void
markWeakPointerLists()
{
WEAKPOINTERLIST list;
/* 1. 保存本地方法指针 */
cell* currentNativeLp = NULL;
if (CurrentThread) {
currentNativeLp = CurrentThread->nativeLp;
}
// 2. 遍历WeakPointers
for (list = WeakPointers; list != NULL; list = list->gcReserved) {
void (*finalizer)(INSTANCE_HANDLE) = list->finalizer;
cellOrPointer *ptr = &list->data[0];
cellOrPointer *endPtr = ptr + list->length;
for (; ptr < endPtr; ptr++) {
cell* object = ptr->cellp;
if (object != NULL) {
// 如果该对象不是存活的,则调用finalizer方法
if (!ISKEPT((object)[-HEADERSIZE])) {
ptr->cellp = NULL;
if (finalizer) {
if (CurrentThread) {
CurrentThread->nativeLp = (cell *)&object;
}
finalizer((INSTANCE_HANDLE)&object);
}
}
}
}
}
/* 3. 恢复本地方法指针 */
if (CurrentThread) {
CurrentThread->nativeLp = currentNativeLp;
}
}
此处不难理解.其WeakPointers的定义如下:
struct weakPointerListStruct {
long length;
struct weakPointerListStruct* gcReserved; // 链表结构
void (*finalizer)(INSTANCE_HANDLE);
cellOrPointer data[1];
};
typedef struct weakPointerListStruct* WEAKPOINTERLIST;
WEAKPOINTERLIST WeakPointers;
而此处的WeakPointers是在markChildren中构建的:
case GCT_WEAKPOINTERLIST:
// 此处使用了头插法构建链表
((WEAKPOINTERLIST)object)->gcReserved = WeakPointers;
WeakPointers = (WEAKPOINTERLIST)object;
break;
而具有GCT_WEAKPOINTERLIST类型的object是在registerCleanup中创建的.代码如下:
void registerCleanup(INSTANCE_HANDLE instanceH, CleanupCallback cb) {
int i;
WEAKPOINTERLIST list = NULL;
cell **ptr, **endptr;
/* Check each known root to see if it is for this callback (cb) 1. 检查是否存在*/
for (i = CleanupRoots->length - 1; i >= 0; i--) {
list = (WEAKPOINTERLIST)CleanupRoots->data[i].charp;
if (list->finalizer == cb) {
break;
}
}
if (i < 0) {
int size;
/* Didn't find an array for this function, allocate a new one 2. 如果不存在,就重新创建 */
i = CleanupRoots->length;
if (i >= CLEANUP_ROOT_SIZE) {// 2.1 如果超过长度的话,则抛出异常
/* TBD: expand roots if not enough */
fatalError(KVM_MSG_ERROR_TOO_MANY_CLEANUP_REGISTRATIONS);
}
// StructSizeInCells(weakPointerListStruct)+((3)-1)
size = SIZEOF_WEAKPOINTERLIST(CLEANUP_ARRAY_SIZE); // CLEANUP_ARRAY_SIZE = 3
list = (WEAKPOINTERLIST)callocObject(size, GCT_WEAKPOINTERLIST);
list->length = CLEANUP_ARRAY_SIZE;
list->finalizer = cb;
list->data[CLEANUP_ARRAY_SIZE - 1].cellp = (cell *)unhand(instanceH); // 保存instance
/* Insert the function pointer into this new array 3. 添加到CleanupRoots 中 */
CleanupRoots->data[i].cellp = (cell *)list;
CleanupRoots->length = i + 1;
return;
}
/* We want to insert "instance" into the i-th element of CleanupRoots,
* which happens to be "list".
*/
/* Skip over 0th entry used by GC, 1st is function pointer data[0]是被gc所使用的*/
ptr = &list->data[0].cellp;
endptr = ptr + list->length;
//
for ( ; ptr < endptr; ptr++) {
if (*ptr == NULL) {
*ptr = (cell *)unhand(instanceH);
if (EXCESSIVE_GARBAGE_COLLECTION) {
/* Make sure people realize that this function really
* can cause an allocation to happen */
garbageCollect(0);
}
return;
}
}
/* We did not find an empty list. We need to make the list larger and
* copy the old one into the new one
* 如果没有找到空的,则需要重新分配一个大的
*/
{
int oldLength = list->length;
int newLength = oldLength + CLEANUP_ARRAY_GROW;//3
WEAKPOINTERLIST newList =
(WEAKPOINTERLIST)callocObject(SIZEOF_WEAKPOINTERLIST(newLength),
GCT_WEAKPOINTERLIST);
newList->length = newLength;
newList->finalizer = cb;
list = (WEAKPOINTERLIST)CleanupRoots->data[i].cellp; /*may have moved*/
CleanupRoots->data[i].cellp = (cell *)newList;
/* Update original elements of list, and insert the new element
* at the end.
*/
memcpy(newList->data, list->data, oldLength << log2CELL);
newList->data[newLength - 1].cellp = (cell *)unhand(instanceH);
}
}
而registerCleanup方法是在解释器处理new字节码时处理的.代码如下:
if (newObject != NULL) {
if (thisClass->finalizer != NULL) {
/* register finalizer for this object */
registerCleanup((INSTANCE_HANDLE)&newObject,
(CleanupCallback)thisClass->finalizer);
}
pushStackAsType(INSTANCE, newObject);
ip += 3;
}
markWeakReferences
此处的代码如下:
static void
markWeakReferences()
{
WEAKREFERENCE thisRef;
for (thisRef = WeakReferences; thisRef != NULL; thisRef = thisRef->gcReserved) {
/* 如果引用的对象不会存活对象,则清除引用*/
cell* referent = (cell*)thisRef->referent;
if (referent != NULL && !ISKEPT((referent)[-HEADERSIZE]))
thisRef->referent = NULL;
}
}
WEAKREFERENCE定义如下:
struct weakReferenceStruct {
COMMON_OBJECT_INFO(INSTANCE_CLASS)
cell* referent;
struct weakReferenceStruct* gcReserved;
};
而WEAKREFERENCE是在markChildren中构建的:
case GCT_WEAKREFERENCE: {
/
checkMonitorAndMark((OBJECT)object);
/* Push this object onto the linked list of weak refs */
((WEAKREFERENCE)object)->gcReserved = WeakReferences;
WeakReferences = (WEAKREFERENCE)object;
/* NOTE: We don't mark the 'referent' field of the */
/* weak reference object here, because we want to */
/* keep the referent alive only if there are */
/* strong references to it. */
break;
}
而具有GCT_WEAKPOINTERLIST类型的object是在WeakReference#initializeWeakReference中创建的.该方法为本地方法,代码如下:
private native void initializeWeakReference();
void Java_java_lang_ref_WeakReference_initializeWeakReference(void)
{
/* This implementation is very KVM-specific: */
/* We've added a new garbage collection (GCT) */
/* type specifically for weak references. */
/* We need to convert the object from a regular */
/* instance (GCT_INSTANCE) to GCT_WEAKREFERENCE. */
/* We do this by updating the header word of the */
/* garbage collector. */
/* First, read the 'this' pointer */
cell* instance = popStackAsType(cell*);
/* Find the garbage collector header word location */
cell* header = instance-HEADERSIZE;
/* Read the header and blow away old GCT type info */
cell headerData = *header & ~TYPEMASK;
/* Store new GCT type info into the header */
*header = headerData | (GCT_WEAKREFERENCE << TYPE_SHIFT); // 将所引用的对象的对象头设置为GCT_WEAKREFERENCE
}
版权声明:本文标题:kvm垃圾收集-005 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1727800103a1130719.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论