Ruby 2.4

GC

module GC

GC模块为Ruby的标记和清理垃圾收集机制提供了一个接口。

一些底层方法也可以通过ObjectSpace模块获得。

您可以通过GC::Profiler获取有关GC操作的信息。

常量

INTERNAL_CONSTANTS OPTS

Public Class Methods

add_stress_to_class(*args) Show source

static VALUE rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self) { rb_objspace_t *objspace = &rb_objspace; if (!stress_to_class) { stress_to_class = rb_ary_tmp_new(argc } rb_ary_cat(stress_to_class, argv, argc return self; }

count → Integer Show source

GC发生的次数。

它返回自进程启动以来GC发生的次数。

static VALUE gc_count(VALUE self) { return SIZET2NUM(rb_gc_count() }

disable → true or false Show source

禁用垃圾收集,如果垃圾收集已被禁用则返回true

GC.disable #=> false GC.disable #=> true

VALUE rb_gc_disable(void) { rb_objspace_t *objspace = &rb_objspace; int old = dont_gc; gc_rest(objspace dont_gc = TRUE; return old ? Qtrue : Qfalse; }

enable → true or false Show source

启用垃圾回收,如果先前禁用垃圾回收,则返回true

GC.disable #=> false GC.enable #=> true GC.enable #=> false

VALUE rb_gc_enable(void) { rb_objspace_t *objspace = &rb_objspace; int old = dont_gc; dont_gc = FALSE; return old ? Qtrue : Qfalse; }

latest_gc_info -> {:gc_by→:newobj} Show source

latest_gc_info(hash) → hash

latest_gc_info(:major_by) → :malloc

返回有关最新垃圾回收的信息。

static VALUE gc_latest_gc_info(int argc, VALUE *argv, VALUE self) { rb_objspace_t *objspace = &rb_objspace; VALUE arg = Qnil; if (rb_scan_args(argc, argv, "01", &arg) == 1) { if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) { rb_raise(rb_eTypeError, "non-hash or symbol given" } } if (arg == Qnil) { arg = rb_hash_new( } return gc_info_decode(objspace, arg, 0 }

malloc_allocated_size → Integer Show source

返回由malloc()分配的内存大小。

只有在使用ruby构建时才可用CALC_EXACT_MALLOC_SIZE

static VALUE gc_malloc_allocated_size(VALUE self) { return UINT2NUM(rb_objspace.malloc_params.allocated_size }

malloc_allocations → Integer Show source

返回malloc()分配的数量。

只有在使用ruby构建时才可用CALC_EXACT_MALLOC_SIZE

static VALUE gc_malloc_allocations(VALUE self) { return UINT2NUM(rb_objspace.malloc_params.allocations }

remove_stress_to_class(*args) Show source

static VALUE rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self) { rb_objspace_t *objspace = &rb_objspace; int i; if (stress_to_class) { for (i = 0; i < argc; ++i) { rb_ary_delete_same(stress_to_class, argv[i] } if (RARRAY_LEN(stress_to_class) == 0) { stress_to_class = 0; } } return Qnil; }

start → nil Show source

start(full_mark: true, immediate_sweep: true) → nil

启动垃圾回收,除非手动禁用。

该方法使用默认为true的关键字参数进行定义:

def GC.start(full_mark: true, immediate_sweep: true end

使用full_mark:false来执行次要GC。使用immediate_sweep:false推迟清理(使用懒惰扫描)。

注意:这些关键字参数是实现和版本相关的。它们不保证与未来兼容,如果底层实现不支持它们,可能会被忽略。

static VALUE gc_start_internal(int argc, VALUE *argv, VALUE self) { rb_objspace_t *objspace = &rb_objspace; int full_mark = TRUE, immediate_mark = TRUE, immediate_sweep = TRUE; VALUE opt = Qnil; static ID keyword_ids[3]; rb_scan_args(argc, argv, "0:", &opt if (!NIL_P(opt)) { VALUE kwvals[3]; if (!keyword_ids[0]) { keyword_ids[0] = rb_intern("full_mark" keyword_ids[1] = rb_intern("immediate_mark" keyword_ids[2] = rb_intern("immediate_sweep" } rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals if (kwvals[0] != Qundef) full_mark = RTEST(kwvals[0] if (kwvals[1] != Qundef) immediate_mark = RTEST(kwvals[1] if (kwvals[2] != Qundef) immediate_sweep = RTEST(kwvals[2] } garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, GPR_FLAG_METHOD gc_finalize_deferred(objspace return Qnil; }

stat → Hash Show source

stat(hash) → hash

stat(:key) → Numeric

返回包含有关GC的信息的哈希。

哈希包含有关GC的内部统计信息,例如:

{ :count=>0, :heap_allocated_pages=>24, :heap_sorted_length=>24, :heap_allocatable_pages=>0, :heap_available_slots=>9783, :heap_live_slots=>7713, :heap_free_slots=>2070, :heap_final_slots=>0, :heap_marked_slots=>0, :heap_eden_pages=>24, :heap_tomb_pages=>0, :total_allocated_pages=>24, :total_freed_pages=>0, :total_allocated_objects=>7796, :total_freed_objects=>83, :malloc_increase_bytes=>2389312, :malloc_increase_bytes_limit=>16777216, :minor_gc_count=>0, :major_gc_count=>0, :remembered_wb_unprotected_objects=>0, :remembered_wb_unprotected_objects_limit=>0, :old_objects=>0, :old_objects_limit=>0, :oldmalloc_increase_bytes=>2389760, :oldmalloc_increase_bytes_limit=>16777216 }

散列的内容是特定于实现的,将来可能会更改。

此方法仅适用于C Ruby。

static VALUE gc_stat(int argc, VALUE *argv, VALUE self) { VALUE arg = Qnil; if (rb_scan_args(argc, argv, "01", &arg) == 1) { if (SYMBOL_P(arg)) { size_t value = gc_stat_internal(arg return SIZET2NUM(value } else if (!RB_TYPE_P(arg, T_HASH)) { rb_raise(rb_eTypeError, "non-hash or symbol given" } } if (arg == Qnil) { arg = rb_hash_new( } gc_stat_internal(arg return arg; }

stress → integer, true or false Show source

返回GC应力模式的当前状态。

static VALUE gc_stress_get(VALUE self) { rb_objspace_t *objspace = &rb_objspace; return ruby_gc_stress_mode; }

stress = flag → flag Show source

Updates the GC stress mode.

当启用压力模式时,GC会在每个GC机会中调用:所有内存和对象分配。

启用压力模式会降低性能,仅用于调试。

标志可以是true,false,或者是一个整型位或符号后面的标志。

0x01:: no major GC 0x02:: no immediate sweep 0x04:: full mark after malloc/calloc/realloc

static VALUE gc_stress_set_m(VALUE self, VALUE flag) { rb_objspace_t *objspace = &rb_objspace; gc_stress_set(objspace, flag return flag; }

verify_internal_consistency → nil Show source

验证内部一致性。

该方法是特定于实现的。现在,如果支持RGenGC,此方法将检查代数一致性。

static VALUE gc_verify_internal_consistency(VALUE dummy) { rb_objspace_t *objspace = &rb_objspace; struct verify_internal_consistency_struct data = {0}; struct each_obj_args eo_args; data.objspace = objspace; gc_report(5, objspace, "gc_verify_internal_consistency: start\n" /* check relations */ eo_args.callback = verify_internal_consistency_i; eo_args.data = (void *)&data; objspace_each_objects((VALUE)&eo_args if (data.err_count != 0) { #if RGENGC_CHECK_MODE >= 5 objspace->rgengc.error_count = data.err_count; gc_marks_check(objspace, NULL, NULL allrefs_dump(objspace #endif rb_bug("gc_verify_internal_consistency: found internal inconsistency." } /* check heap_page status */ gc_verify_heap_pages(objspace /* check counters */ if (!is_lazy_sweeping(heap_eden) && !finalizing) { if (objspace_live_slots(objspace) != data.live_object_count) { fprintf(stderr, "heap_pages_final_slots: %d, objspace->profile.total_freed_objects: %d\n", (int)heap_pages_final_slots, (int)objspace->profile.total_freed_objects rb_bug("inconsistent live slot nubmer: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace_live_slots(objspace), data.live_object_count } } #if USE_RGENGC if (!is_marking(objspace)) { if (objspace->rgengc.old_objects != data.old_object_count) { rb_bug("inconsistent old slot nubmer: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.old_objects, data.old_object_count } if (objspace->rgengc.uncollectible_wb_unprotected_objects != data.remembered_shady_count) { rb_bug("inconsistent old slot nubmer: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.uncollectible_wb_unprotected_objects, data.remembered_shady_count } } #endif if (!finalizing) { size_t list_count = 0; { VALUE z = heap_pages_deferred_final; while (z) { list_count++; z = RZOMBIE(z)->next; } } if (heap_pages_final_slots != data.zombie_object_count || heap_pages_final_slots != list_count) { rb_bug("inconsistent finalizing object count:\n" " expect %"PRIuSIZE"\n" " but %"PRIuSIZE" zombies\n" " heap_pages_deferred_final list has %"PRIuSIZE" items.", heap_pages_final_slots, data.zombie_object_count, list_count } } gc_report(5, objspace, "gc_verify_internal_consistency: OK\n" return Qnil; }

Public Instance Methods

garbage_collect → nil Show source

include GC; garbage_collect → nil

garbage_collect(full_mark: true, immediate_sweep: true) → nil

启动垃圾回收,除非手动禁用。

该方法使用默认为true的关键字参数进行定义:

def GC.start(full_mark: true, immediate_sweep: true end

使用full_mark:false来执行次要GC。使用immediate_sweep:false推迟清理(使用懒惰扫描)。

注意:这些关键字参数是实现和版本相关的。它们不保证与未来兼容,如果底层实现不支持它们,可能会被忽略。

static VALUE gc_start_internal(int argc, VALUE *argv, VALUE self) { rb_objspace_t *objspace = &rb_objspace; int full_mark = TRUE, immediate_mark = TRUE, immediate_sweep = TRUE; VALUE opt = Qnil; static ID keyword_ids[3]; rb_scan_args(argc, argv, "0:", &opt if (!NIL_P(opt)) { VALUE kwvals[3]; if (!keyword_ids[0]) { keyword_ids[0] = rb_intern("full_mark" keyword_ids[1] = rb_intern("immediate_mark" keyword_ids[2] = rb_intern("immediate_sweep" } rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals if (kwvals[0] != Qundef) full_mark = RTEST(kwvals[0] if (kwvals[1] != Qundef) immediate_mark = RTEST(kwvals[1] if (kwvals[2] != Qundef) immediate_sweep = RTEST(kwvals[2] } garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, GPR_FLAG_METHOD gc_finalize_deferred(objspace return Qnil; }