0
点赞
收藏
分享

微信扫一扫

copy_to_survivor_space

颜路在路上 2022-02-18 阅读 147


copy_to_survivor_space

defNewGeneration.cpp

784

copy_to_survivor_space

oop DefNewGeneration::copy_to_survivor_space(oop old) {
assert(is_in_reserved(old) && !old->is_forwarded(),
"shouldn't be scavenging this oop");
size_t s = old->size(); // 旧对象的大小
oop obj = NULL;

// Try allocating obj in to-space (unless too old)
if (old->age() < tenuring_threshold()) { // 没达到老年代的年龄(还是在新生代分配-to空间分配)
obj = (oop) to()->allocate_aligned(s); // 如果对象的年龄低于tenuring_threshold,则该在to区申请一块同样大小的内存
}

// Otherwise try allocating obj tenured
if (obj == NULL) { // 如果如果对象的年龄大于tenuring_threshold或者to区申请内存失败
obj = _next_gen->promote(old, s); // 则尝试将该对象复制到老年代
if (obj == NULL) { //老年代复制失败
handle_promotion_failure(old);
return old;
}
} else {
// Prefetch beyond obj to区中申请内存成功
const intx interval = PrefetchCopyIntervalInBytes;
Prefetch::write(obj, interval);

// Copy obj 对象复制
Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)obj, s);

// Increment age if obj still in new generation
obj->incr_age(); // 增加年龄,增加对应年龄的总对象大小 注意此处是增加复制对象而非原来对象的分代年龄
age_table()->add(obj, s); // 并修改age_table
}

// Done, insert forward pointer to obj in this header
old->forward_to(obj); // 将对象头指针指向新地址

return obj;
}

oopDesc::forward_to

oop.inline.hpp:629

inline void oopDesc::forward_to(oop p) {
assert(check_obj_alignment(p), // //校验oop的地址是对齐的
"forwarding to something not aligned");
assert(Universe::heap()->is_in_reserved(p), //校验p在Java堆中
"forwarding to something not in heap");
markOop m = markOopDesc::encode_pointer_as_mark(p); //利用地址p生成一个新的对象头,将该对象头打上GC标记,最后修改当前对象的对象头
assert(m->decode_pointer() == p, "encoding must be reversable"); //校验新对象头解析出来的地址等于p
set_mark(m);
}

oopDesc::is_forwarded()

inline bool oopDesc::is_forwarded() const {
// The extra heap check is needed since the obj might be locked, in which case the
// mark would point to a stack location and have the sentinel bit cleared
return mark()->is_marked(); // 11
}

参考书籍

深入剖析Java虚拟机



举报

相关推荐

0 条评论