Java教程

jvm源码解读--14 defNewGeneration.cpp gc标记复制之后,进行空间清理

本文主要是介绍jvm源码解读--14 defNewGeneration.cpp gc标记复制之后,进行空间清理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

进入Eden()->clean()函数

void EdenSpace::clear(bool mangle_space) {
  ContiguousSpace::clear(mangle_space);
  set_soft_end(end());
}

进入

void ContiguousSpace::clear(bool mangle_space) {
  set_top(bottom());
  set_saved_mark();
  CompactibleSpace::clear(mangle_space);
}

打印对象,这个是eden

(gdb) p this 
$154 = (EdenSpace * const) 0x7f4780020328
(gdb) p * this 
$155 = (EdenSpace) {
  <ContiguousSpace> = {
    <CompactibleSpace> = {
      <Space> = {
        <CHeapObj<1280u>> = {
          <AllocatedObj> = {
            _vptr.AllocatedObj = 0x7f4788515a90 <vtable for EdenSpace+16>
          }, <No data fields>}, 
        members of Space: 
        _bottom = 0xf3800000, 
        _end = 0xf5600000, 
        _saved_mark_word = 0xf4dccdb8, 
        _preconsumptionDirtyCardClosure = 0x0, 
        _par_seq_tasks = {
          <StackObj> = {
            <AllocatedObj> = {
              _vptr.AllocatedObj = 0x7f47884fb650 <vtable for SequentialSubTasksDone+16>
            }, <No data fields>}, 
          members of SequentialSubTasksDone: 
          _n_tasks = 0, 
          _n_claimed = 0, 
          _n_threads = 0, 
          _n_completed = 0
        }
      }, 
      members of CompactibleSpace: 
      _compaction_top = 0xf3800000, 
      _next_compaction_space = 0x7f4780020438, 
      _first_dead = 0xf1f1f1f1f1f1f1f1, 
      _end_of_live = 0xf1f1f1f1f1f1f1f1
    }, 
    members of ContiguousSpace: 
    _top = 0xf4dccdb8, 
    _concurrent_iteration_safe_limit = 0xf3800000, 
    _mangler = 0x7f47800203e8
  }, 
  members of EdenSpace: 
  _gen = 0x7f478001f1c8, 
  _soft_end = 0xf5600000
}

看实现

(gdb) p bottom()
$156 = (HeapWord *) 0xf3800000
(gdb) p top()
$157 = (HeapWord *) 0xf4dccdb8

将top清空

设置mark

 virtual void set_saved_mark()    { _saved_mark_word = top();    }

清理完之后的对象

(gdb) p *this
$159 = (EdenSpace) {
  <ContiguousSpace> = {
    <CompactibleSpace> = {
      <Space> = {
        <CHeapObj<1280u>> = {
          <AllocatedObj> = {
            _vptr.AllocatedObj = 0x7f4788515a90 <vtable for EdenSpace+16>
          }, <No data fields>}, 
        members of Space: 
        _bottom = 0xf3800000, 
        _end = 0xf5600000, 
        _saved_mark_word = 0xf3800000, 
        _preconsumptionDirtyCardClosure = 0x0, 
        _par_seq_tasks = {
          <StackObj> = {
            <AllocatedObj> = {
              _vptr.AllocatedObj = 0x7f47884fb650 <vtable for SequentialSubTasksDone+16>
            }, <No data fields>}, 
          members of SequentialSubTasksDone: 
          _n_tasks = 0, 
          _n_claimed = 0, 
          _n_threads = 0, 
          _n_completed = 0
        }
      }, 
      members of CompactibleSpace: 
      _compaction_top = 0xf3800000, 
      _next_compaction_space = 0x7f4780020438, 
      _first_dead = 0xf1f1f1f1f1f1f1f1, 
      _end_of_live = 0xf1f1f1f1f1f1f1f1
    }, 
    members of ContiguousSpace: 
    _top = 0xf3800000, 
    _concurrent_iteration_safe_limit = 0xf3800000, 
    _mangler = 0x7f47800203e8
  }, 
  members of EdenSpace: 
  _gen = 0x7f478001f1c8, 
  _soft_end = 0xf5600000
}

接着看

CompactibleSpace::clear(mangle_space);
----------------------------------------------
void CompactibleSpace::clear(bool mangle_space) {
  Space::clear(mangle_space);
  _compaction_top = bottom();
}
----------------------------------------------
void Space::clear(bool mangle_space) {
  if (ZapUnusedHeapArea && mangle_space) {
    mangle_unused_area();
  }
}

-------------------------------------------------
void ContiguousSpace::mangle_unused_area() {
  mangler()->mangle_unused_area();
}
-----------------------------------------------------
void SpaceMangler::mangle_unused_area() {
  assert(ZapUnusedHeapArea, "Mangling should not be in use");
  // Mangle between top and the high water mark.  Safeguard
  // against the space changing since top_for_allocations was
  // set.
  HeapWord* mangled_end = MIN2(top_for_allocations(), end());
  if (top() < mangled_end) {
    MemRegion mangle_mr(top(), mangled_end);
    SpaceMangler::mangle_region(mangle_mr);
    // Light weight check of mangling.
    check_mangled_unused_area(end());
  }
  // Complete check of unused area which is functional when
  // DEBUG_MANGLING is defined.
  check_mangled_unused_area_complete();
}

打印这个spaceMangler对象

(gdb) p _mangler
$162 = (GenSpaceMangler *) 0x7f47800203e8
(gdb) p *_mangler
$163 = (GenSpaceMangler) {
  <SpaceMangler> = {
    <CHeapObj<1280u>> = {
      <AllocatedObj> = {
        _vptr.AllocatedObj = 0x7f47885163d0 <vtable for GenSpaceMangler+16>
      }, <No data fields>}, 
    members of SpaceMangler: 
    _top_for_allocations = 0xf4dccdb8
  }, 
  members of GenSpaceMangler: 
  _sp = 0x7f4780020328
}

查看紫色函数

(gdb) p end()
$164 = (HeapWord *) 0xf5600000
(gdb) p _top_for_allocations
$165 = (HeapWord *) 0xf4dccdb8

进入棕色函数

// Simply mangle the MemRegion mr.
void SpaceMangler::mangle_region(MemRegion mr) {
  assert(ZapUnusedHeapArea, "Mangling should not be in use");
#ifdef ASSERT
  if(TraceZapUnusedHeapArea) {
    gclog_or_tty->print("Mangling [0x%x to 0x%x)", mr.start(), mr.end());
  }
  Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord);
  if(TraceZapUnusedHeapArea) {
    gclog_or_tty->print_cr(" done");
  }
#endif
}

进入函数

  // Fill methods

  // Fill word-aligned words, not atomic on each word
  // set_words
  static void fill_to_words(HeapWord* to, size_t count, juint value = 0) {
    assert_params_ok(to, LogHeapWordSize);
    pd_fill_to_words(to, count, value);
  }

进入

static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
#ifdef AMD64
  julong* to = (julong*) tohw;
  julong  v  = ((julong) value << 32) | value;
  while (count-- > 0) {
    *to++ = v;
  }
#else..无用..
#endif // AMD64
}

看badHeapWord的值

(gdb) p/x value 
$171 = 0xbaadbabe

那么上述过程就是将heap的值全部设置成了0xbaadbabe

接着就是对from区域

 

(gdb) p from()
$175 = (ContiguousSpace *) 0x7f4780020438

重要的交换空间

    swap_spaces();

交换之前

(gdb) p this 
$181 = (DefNewGeneration * const) 0x7f478001f1c8
(gdb) p* this
$182 = (DefNewGeneration) {
  <Generation> = {
    <CHeapObj<1280u>> = {
      <AllocatedObj> = {
        _vptr.AllocatedObj = 0x7f47884ff590 <vtable for DefNewGeneration+16>
      }, <No data fields>}, 
    members of Generation: 
    _time_of_last_gc = -1012762419733073423, 
    _prev_used_region = {
      _start = 0x0, 
      _word_size = 0
    }, 
    _reserved = {
      _start = 0xf3800000, 
      _word_size = 6553600
    }, 
....略部分
  _promo_failure_drain_in_progress = false, 
  _gen_counters = 0x7f4780020638, 
  _eden_counters = 0x7f478000d678, 
  _from_counters = 0x7f4780021888, 
  _to_counters = 0x7f4780021d78, 
  _max_eden_size = 31457280, 
  _max_survivor_size = 10485760, 
  _should_allocate_from_space = false, 
  _eden_space = 0x7f4780020328, 
  _from_space = 0x7f4780020438, 
  _to_space = 0x7f4780020538, 
  _gc_timer = 0x7f4780022268
}

代码为

void DefNewGeneration::swap_spaces() {
  ContiguousSpace* s = from();
  _from_space        = to();
  _to_space          = s;
  eden()->set_next_compaction_space(from());
  // The to-space is normally empty before a compaction so need
  // not be considered.  The exception is during promotion
  // failure handling when to-space can contain live objects.
  from()->set_next_compaction_space(NULL);

  if (UsePerfData) {
    CSpaceCounters* c = _from_counters;
    _from_counters = _to_counters;
    _to_counters = c;
  }
}

这个函数为  eden()->set_next_compaction_space(from());

  void set_next_compaction_space(CompactibleSpace* csp) {
    _next_compaction_space = csp;
  }

将eden()的值设置为新的from值,(即原来的from空间已经变为了to空间)

  if (UsePerfData) {
    CSpaceCounters* c = _from_counters;
    _from_counters = _to_counters;
    _to_counters = c;
  }

设置完成后就结束了

 

这篇关于jvm源码解读--14 defNewGeneration.cpp gc标记复制之后,进行空间清理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!