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虚拟机