Skip to content

g1 region Num_Committed

ceragon edited this page Feb 25, 2022 · 1 revision

G1 的 region 个数变化规则

概述

在 G1 GC 中,堆内存被划分成了多个 region,最大个数和 -Xmx 参数有关。但 JVM 启动时并不会直接把这些 region 都创建出来,而是按需创建。所以就有了一个当前已创建的 region 个数的概念,下面来探究一下源码中这个个数是怎么变化的。

HeapRegionManger

class HeapRegionManager: public CHeapObj<mtGC> {
    // _regions 是个数组,每个元素都是一个 region 对象
    G1HeapRegionTable _regions;
    // 已创建的 region 个数
    uint _num_committed; 
    public:
    HeapRegionManager() : _regions(),_num_committed(0) {
    }
};

_num_committed 增加

void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
    _num_committed += (uint)num_regions;
}
void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) {
    commit_regions(start, num_regions, pretouch_gang);
    for (uint i = start; i < start + num_regions; i++) {
        if (_regions.get_by_index(i) == NULL) {
            HeapRegion* new_hr = new_heap_region(i);
            _regions.set_by_index(i, new_hr);
            _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1);
        }
    }
}
uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
    uint cur = start;
    uint idx_last_found = 0;
    uint num_last_found = 0;
    uint expanded = 0;
    while (expanded < num_regions &&
           (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
        uint to_expand = MIN2(num_regions - expanded, num_last_found);
        make_regions_available(idx_last_found, to_expand, pretouch_workers);
        expanded += to_expand;
        cur = idx_last_found + num_last_found + 1;
    }
    return expanded;
}

_num_committed 减少

void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
    _num_committed -= (uint)num_regions;
}
void HeapRegionManager::shrink_at(uint index, size_t num_regions) {
    uncommit_regions(index, num_regions);
}

初始大小

jint G1CollectedHeap::initialize() {
    size_t init_byte_size = collector_policy()->initial_heap_byte_size();
    if (!expand(init_byte_size, _workers)) {
        return JNI_ENOMEM;
    }
}
bool G1CollectedHeap::expand(size_t expand_bytes, WorkGang* pretouch_workers, double* expand_time_ms) {
    size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
    aligned_expand_bytes = align_up(aligned_expand_bytes, HeapRegion::GrainBytes);
    uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
    uint expanded_by = _hrm.expand_by(regions_to_expand, pretouch_workers);
}
uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) {
    return expand_at(0, num_regions, pretouch_workers);
}

Clone this wiki locally