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










