hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp
void PSPermGen::compute_new_size(size_t used_before_collection) {
{- -------------------------------------------
(1) 前回の GC 時からの増加量を計算して, _avg_size の値を更新しておく.
---------------------------------------- -}
// Update our padded average of objects allocated in perm
// gen between collections.
assert(used_before_collection >= _last_used,
"negative allocation amount since last GC?");
const size_t alloc_since_last_gc = used_before_collection - _last_used;
_avg_size->sample(alloc_since_last_gc);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
const size_t current_live = used_in_bytes();
// Stash away the current amount live for the next call to this method.
_last_used = current_live;
// We have different alignment constraints than the rest of the heap.
const size_t alignment = MAX2(MinPermHeapExpansion,
virtual_space()->alignment());
{- -------------------------------------------
(1) 新しい領域長を以下のように計算する.
(1) まず次の値を計算する
「現在の使用量(GC後の使用量. 以下の current_live)
+ 次のGCまでの間に増える量(の予測値. これまでの実績量の平均を使用. 以下の _avg_size->padded_average())」
(2) この値を, MinPermHeapExpansion または PSVirtualSpace::alignment() の大きい方の値(以下の alignment)で切り上げる
(3) その結果が _max_gen_size を超えていたり _min_gen_size を下回っている場合には,
それぞれ _max_gen_size/_min_gen_size に切り詰める.
(_min_gen_size ~ _max_gen_size の範囲に収まっていれば, (2) の結果をそのまま使用する)
---------------------------------------- -}
// Compute the desired size:
// The free space is the newly computed padded average,
// so the desired size is what's live + the free space.
size_t desired_size = current_live + (size_t)_avg_size->padded_average();
desired_size = align_size_up(desired_size, alignment);
// ...and no larger or smaller than our max and min allowed.
desired_size = MAX2(MIN2(desired_size, _max_gen_size), _min_gen_size);
assert(desired_size <= _max_gen_size, "just checking");
{- -------------------------------------------
(1) もし計算結果が現在の領域長と同じであれば, 何もすることはないので, ここでリターン.
---------------------------------------- -}
const size_t size_before = _virtual_space->committed_size();
if (desired_size == size_before) {
// no change, we're done
return;
}
{- -------------------------------------------
(1) ExpandHeap_lock ロックを保持した状態で, Perm 領域の大きさを変更する.
(計算結果が現在の領域長よりも大きければ, PSOldGen::expand_by() で領域を拡大する.
逆に, 現在の領域長よりも小さければ, PSOldGen::shrink() で領域を縮小する.)
---------------------------------------- -}
{
// We'll be growing or shrinking the heap: in either case,
// we need to hold a lock.
MutexLocker x(ExpandHeap_lock);
if (desired_size > size_before) {
const size_t change_bytes = desired_size - size_before;
const size_t aligned_change_bytes =
align_size_up(change_bytes, alignment);
expand_by(aligned_change_bytes);
} else {
// Shrinking
const size_t change_bytes =
size_before - desired_size;
const size_t aligned_change_bytes = align_size_down(change_bytes, alignment);
shrink(aligned_change_bytes);
}
}
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
// While this code isn't controlled by AdaptiveSizePolicy, it's
// convenient to see all resizing decsions under the same flag.
if (PrintAdaptiveSizePolicy) {
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
gclog_or_tty->print_cr("AdaptiveSizePolicy::perm generation size: "
"collection: %d "
"(" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ",
heap->total_collections(),
size_before, _virtual_space->committed_size());
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.