GC 모듈
GC 모듈 (GC)
GC 모듈은 Ruby의 mark-and-sweep 가비지 컬렉션 메커니즘에 접근하는 인터페이스를 제공해요. 일부 하위 메서드는 ObjectSpace 모듈을 통해서도 사용할 수 있어요. GC 동작에 관한 정보는 GC::Profiler를 통해 얻을 수 있죠.
출처: Ruby 4.0 API
본문
::config (Public Class Method)
config → hash 또는 config(hash_to_merge) → hash — 현재 GC 설정에 관한 정보를 설정하거나 가져와요. 이 메서드는 CRuby 전용이에요. 설정 파라미터는 GC 구현별로 다르고 예고 없이 바뀔 수 있어요.
인자 없이 호출하면 설정을 담은 해시를 돌려줘요.
GC.config
# => {rgengc_allow_full_mark: true, implementation: "default"}
인자 hash_to_merge를 주면 그 해시를 저장된 설정 해시에 합치고, 알 수 없는 키는 무시한 뒤 설정 해시를 돌려줘요.
GC.config(rgengc_allow_full_mark: false)
# => {rgengc_allow_full_mark: false, implementation: "default"}
GC.config(foo: 'bar')
# => {rgengc_allow_full_mark: false, implementation: "default"}
모든 구현에 공통인 읽기 전용 항목은 하나예요 — :implementation: 구현의 문자열 이름(기본 구현은 'default'). 기본 구현의 구현별 항목은 :rgengc_allow_full_mark로, GC가 전체 마크(young & old 객체)를 실행할 수 있는지를 제어해요.
true(기본): GC가 major와 minor 컬렉션을 섞어 실행해요. 전체 마크가 요청됐다는 플래그가 설정되고,GC.latest_gc_info(:need_major_by)로 확인할 수 있어요.false: 사용자 코드가 명시적으로 지시하지 않는 한 GC가 전체 마크 사이클을 시작하지 않아요(GC.start참고). 이 설정은 young→old 승격을 비활성화해요. 성능상Process.warmup으로 앱을 예열한 뒤 이 값을false로 설정하는 걸 권장해요.
::count (Public Class Method)
count → integer — 가비지 컬렉션이 발생한 총 횟수를 돌려줘요.
GC.count # => 385
GC.start
GC.count # => 386
::disable (Public Class Method)
disable → true 또는 false — 가비지 컬렉션을 비활성화해요(단 GC.start는 여전히 동작). 이미 비활성화돼 있었는지를 돌려줘요.
GC.enable
GC.disable # => false
GC.disable # => true
::enable (Public Class Method)
enable → true 또는 false — 가비지 컬렉션을 활성화해요. 비활성화돼 있었는지를 돌려줘요.
GC.disable
GC.enable # => true
GC.enable # => false
::latest_gc_info (Public Class Method)
latest_gc_info → new_hash, latest_gc_info(key) → value, 또는 latest_gc_info(hash) → hash — 가장 최근 가비지 컬렉션에 관한 정보를 돌려줘요.
GC.latest_gc_info
# =>
{major_by: :force,
need_major_by: nil,
gc_by: :method,
have_finalizer: false,
immediate_sweep: true,
state: :none,
weak_references_count: 0,
retained_weak_references_count: 0}
심볼 key를 주면 그 키의 값을 돌려줘요.
GC.latest_gc_info(:gc_by) # => :newobj
해시를 주면 해당 해시에 GC 정보가 합쳐진 해시를 돌려줘요. 프로브 효과(probe effects)를 최소화하는 데 유용할 수 있어요.
::measure_total_time / ::measure_total_time= (Public Class Method)
measure_total_time → true 또는 false — GC 총 시간 측정 설정을 돌려줘요. 초기값은 true예요. GC.total_time 참고.
measure_total_time = setting → setting — GC 총 시간 측정을 활성화하거나 비활성화해요. 인자가 nil이나 false면 측정을 끄고, 그 외는 켜요.
GC.measure_total_time = nil # => nil
GC.measure_total_time # => false
GC.measure_total_time = true # => true
GC.measure_total_time # => true
총 시간 측정이 켜져 있으면 성능에 영향을 줘요.
::start (Public Class Method)
start(full_mark: true, immediate_mark: true, immediate_sweep: true) — GC.disable로 명시적으로 비활성화돼 있어도 가비지 컬렉션을 시작해요.
full_mark:true면 major GC 사이클(모든 객체, old와 new를 마크),false면 minor GC 사이클(young 객체만 마크)을 수행해요.immediate_mark:true면 메서드가 돌아오기 전에 마킹을 완료하고,false면 프로그램 실행과 섞어 부분적으로 수행해요.full_mark이false면immediate_mark값과 무관하게 마킹은 항상 즉시 수행돼요.immediate_sweep:true면 메서드 반환 전에 스위핑을 완료하고,false면 부분적으로 수행해요(lazy sweep).
이 키워드 인자들은 구현·버전에 따라 다르고, 미래 호환성이 보장되지 않으며, 일부 구현에서는 무시될 수 있어요.
::stat (Public Class Method)
stat → new_hash, stat(key) → value, 또는 stat(hash) → hash — GC 통계를 돌려줘요. CRuby 전용이고 일부 통계는 예고 없이 바뀔 수 있어요.
GC.stat
# =>
{count: 28,
time: 1,
marking_time: 1,
sweeping_time: 0,
heap_allocated_pages: 521,
...}
해시의 주요 항목들:
:count— 앱 시작 이후 실행된 GC 총 횟수(minor + major).:time— GC에 소비된 총 시간(밀리초).:heap_allocated_pages— 할당된 총 페이지 수.:heap_empty_pages— 살아있는 객체가 없어서 시스템에 반환될 수 있는 페이지 수.:heap_allocatable_pages— 추가 GC 없이 앱이 할당할 수 있는 총 페이지 수.:heap_available_slots— 모든:heap_allocated_pages의 슬롯 총 수.:heap_live_slots— 살아있는 객체를 담은 슬롯 수.:heap_free_slots— 살아있는 객체가 없는 슬롯 수.:heap_final_slots— 실행 대기 중인 finalizer가 있는 슬롯 수.:heap_marked_slots— 마지막 GC에서 마크된 객체 수.:heap_eden_pages— 살아있는 슬롯을 하나 이상 포함한 페이지 수.:total_allocated_pages/:total_freed_pages— 앱 시작 이후 누적 할당/해제 페이지 수.:total_allocated_objects/:total_freed_objects— 앱 시작 이후 누적 할당/해제 객체 수.:malloc_increase_bytes— 힙에 할당된 객체용 메모리 양. 어떤 GC든 실행되면 감소.:malloc_increase_bytes_limit—:malloc_increase_bytes가 이 한도를 넘으면 GC가 촉발.:minor_gc_count/:major_gc_count— 프로세스 시작 이후 minor/major GC 총 횟수.:compact_count— 프로세스 시작 이후 컴팩션 총 횟수.:read_barrier_faults— 컴팩션 중 read barrier가 촉발된 횟수.:total_moved_objects— 컴팩션이 이동시킨 객체 총 수.:remembered_wb_unprotected_objects— write barrier가 없는 객체 수. 한도를 넘으면 major GC 촉발.:old_objects— 최소 3번의 GC를 살아남은 살아있는 old 객체 수. 한도를 넘으면 major GC 촉발.:oldmalloc_increase_bytes— major GC에 의해 감소하는 힙 메모리 양.
심볼 key를 주면 그 키의 값만, 해시를 주면 그 해시에 통계가 합쳐진 해시를 돌려줘요.
::stat_heap (Public Class Method)
stat_heap → new_hash, stat_heap(heap_id), stat_heap(heap_id, key), stat_heap(nil, hash), stat_heap(heap_id, hash) — GC 힙에 대한 통계를 돌려줘요. CRuby 전용이에요.
GC.stat_heap
# =>
{0 => {slot_size: 40, ...}, 1 => {slot_size: 80, ...}, ...}
아우터 해시의 키는 힙 식별자예요. CRuby에서는 정수지만, 다른 구현에서는 문자열일 수 있어요.
GC.stat_heap.keys # => [0, 1, 2, 3, 4]
GC.stat_heap(2, :slot_size) # => 160
힙 통계에는 :slot_size(바이트 단위 슬롯 크기), :heap_allocatable_pages, :heap_eden_pages, :heap_eden_slots, :total_allocated_pages, :total_freed_pages, :force_major_gc_count(여유 슬롯 부족으로 major GC를 강제 시작한 횟수), :force_incremental_marking_finish_count(pooled 슬롯 부족으로 증분 마킹 완료를 강제한 횟수) 등이 있어요.
::stress / ::stress= (Public Class Method)
stress → setting — 현재 GC stress 모드 설정을 돌려줘요. 초기값은 false예요. GC.stress=로 설정할 수 있어요.
stress = value → value — stress 모드를 활성화하거나 비활성화해요. stress 모드는 성능을 떨어뜨리므로 디버깅용으로만 써야 해요.
value가nil또는false면 stress 모드를 끔.value가 정수면 특정 플래그로 stress 모드를 켬(비트:0x01major GC 없음,0x02즉시 sweep 없음,0x04malloc/calloc/realloc 후 전체 마크).- 그 외에는 stress 모드를 켜서 모든 GC 기회(모든 메모리·객체 할당)마다 GC를 호출.
::total_time (Public Class Method)
total_time → integer — GC 총 시간을 나노초 단위로 돌려줘요.
GC.total_time # => 156250
참고로 총 시간은 측정이 활성화됐을 때(GC.measure_total_time이 true일 때)만 누적돼요. 꺼져 있으면 GC.start를 해도 누적되지 않아요.
#garbage_collect (Public Instance Method)
garbage_collect(full_mark: true, immediate_mark: true, immediate_sweep: true) — GC.start의 별칭이에요.