module GC
GC 模块提供了一个接口,用于访问 Ruby 的标记-清除垃圾回收机制。
一些底层方法也可通过 ObjectSpace 模块获得。
您可以通过 GC::Profiler 获取关于 GC 操作的信息。
Public Class Methods
Source
# File gc.rb, line 444 def self.config hash = nil if Primitive.cexpr!("RBOOL(RB_TYPE_P(hash, T_HASH))") if hash.include?(:implementation) raise ArgumentError, 'Attempting to set read-only key "Implementation"' end Primitive.gc_config_set hash elsif hash != nil raise ArgumentError end Primitive.gc_config_get end
此方法是 CRuby 的特定实现。
设置或获取有关当前 GC 配置的信息。
配置参数是 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:实现的字符串名称;对于 Ruby 默认实现,为'default'。
特定实现的配置
GC 实现维护其自己的特定于实现的配置。
对于 Ruby 的默认实现,唯一条目是
-
:rgengc_allow_full_mark:控制 GC 是否允许运行完全标记(年轻和年老对象)-
true(默认):GC 交替进行主次收集。设置一个标志以通知GC已请求完全标记。此标志可通过GC.latest_gc_info(:need_major_by) 访问。 -
false:除非用户代码明确指示,否则 GC 不会启动完整的标记周期;请参阅GC.start。将此参数设置为false会禁用年轻到年老对象的提升。出于性能原因,我们建议在使用Process.warmup预热应用程序后再将此参数设置为false。
-
Source
# File gc.rb, line 124 def self.count Primitive.gc_count end
返回垃圾回收发生的总次数
GC.count # => 385 GC.start GC.count # => 386
Source
# File gc.rb, line 76 def self.disable Primitive.gc_disable end
禁用垃圾回收(但 GC.start 仍然有效):返回垃圾回收是否已被禁用。
GC.enable GC.disable # => false GC.disable # => true
Source
# File gc.rb, line 62 def self.enable Primitive.gc_enable end
启用垃圾回收;返回垃圾回收是否已被禁用
GC.disable GC.enable # => true GC.enable # => false
Source
# File gc.rb, line 500 def self.latest_gc_info hash_or_key = nil if hash_or_key == nil hash_or_key = {} elsif Primitive.cexpr!("RBOOL(!SYMBOL_P(hash_or_key) && !RB_TYPE_P(hash_or_key, T_HASH))") raise TypeError, "non-hash or symbol given" end Primitive.cstmt! %{ return rb_gc_latest_gc_info(hash_or_key); } end
如果没有给出参数,则返回最近一次垃圾回收的信息
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
如果给出了哈希参数 hash,则返回该哈希,并将 GC 信息合并到其内容中;此形式可能有助于最小化 探测效应
h = {foo: 0, bar: 1} GC.latest_gc_info(h) # => {foo: 0, bar: 1, major_by: nil, need_major_by: nil, gc_by: :newobj, have_finalizer: false, immediate_sweep: false, state: :sweeping, weak_references_count: 0, retained_weak_references_count: 0}
Source
# File gc.rb, line 549 def self.measure_total_time Primitive.cexpr! %{ RBOOL(rb_gc_impl_get_measure_total_time(rb_gc_get_objspace())) } end
返回 GC 总时间测量的设置;初始设置为 true。请参阅 GC.total_time。
Source
# File gc.rb, line 536 def self.measure_total_time=(flag) Primitive.cstmt! %{ rb_gc_impl_set_measure_total_time(rb_gc_get_objspace(), flag); return flag; } end
启用或禁用 GC 总时间测量;返回 setting。请参阅 GC.total_time。
当参数 object 为 nil 或 false 时,禁用总时间测量;GC.measure_total_time 则返回 false
GC.measure_total_time = nil # => nil GC.measure_total_time # => false GC.measure_total_time = false # => false GC.measure_total_time # => false
否则,启用总时间测量;GC.measure_total_time 则返回 true
GC.measure_total_time = true # => true GC.measure_total_time # => true GC.measure_total_time = :foo # => :foo GC.measure_total_time # => true
请注意,启用总时间测量会影响性能。
Source
# File gc.rb, line 43 def self.start full_mark: true, immediate_mark: true, immediate_sweep: true Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false end
发起垃圾回收,即使它已被 GC.disable 明确禁用。
关键字参数
-
full_mark:其布尔值决定是否执行主垃圾回收周期-
true:发起主垃圾回收周期,意味着所有对象(年老和年轻)都被标记。 -
false:发起次垃圾回收周期,意味着只有年轻对象被标记。
-
-
immediate_mark:其布尔值决定是否执行增量标记-
true:标记在方法返回前完成。 -
false:标记分块进行,与方法返回前以及返回后的程序执行交织在一起;因此标记可能在方法返回前未完成。请注意,如果full_mark为false,则无论immediate_mark的值如何,标记都将是即时的。
-
-
immediate_sweep:其布尔值决定是否推迟清理(使用延迟清理)-
true:清理在方法返回前完成。 -
false:清理分块进行,与方法返回前以及返回后的程序执行交织在一起;因此清理可能在方法返回前未完成。
-
请注意,这些关键字参数是特定于实现和版本的,不保证未来兼容性,并且可能在某些实现中被忽略。
Source
# File gc.rb, line 250 def self.stat hash_or_key = nil Primitive.gc_stat hash_or_key end
此方法是 CRuby 的特定实现。
返回 GC 统计信息。具体的统计信息是特定于实现的,并且将来可能会在不另行通知的情况下更改。
如果没有给出参数,则返回最近一次垃圾回收的信息
GC.stat # => {count: 28, time: 1, marking_time: 1, sweeping_time: 0, heap_allocated_pages: 521, heap_empty_pages: 0, heap_allocatable_slots: 0, heap_available_slots: 539590, heap_live_slots: 422243, heap_free_slots: 117347, heap_final_slots: 0, heap_marked_slots: 264877, heap_eden_pages: 521, total_allocated_pages: 521, total_freed_pages: 0, total_allocated_objects: 2246376, total_freed_objects: 1824133, malloc_increase_bytes: 50982, malloc_increase_bytes_limit: 18535172, minor_gc_count: 18, major_gc_count: 10, compact_count: 0, read_barrier_faults: 0, total_moved_objects: 0, remembered_wb_unprotected_objects: 0, remembered_wb_unprotected_objects_limit: 2162, old_objects: 216365, old_objects_limit: 432540, oldmalloc_increase_bytes: 1654232, oldmalloc_increase_bytes_limit: 16846103}
如果给出了符号参数 key,则返回该键的值
GC.stat(:count) # => 30
如果给出了哈希参数 hash,则返回该哈希,并将 GC 统计信息合并到其内容中;此形式可能有助于最小化 探测效应
h = {foo: 0, bar: 1} GC.stat(h) h.keys.take(5) # => [:foo, :bar, :count, :time, :marking_time]
哈希包含条目,例如
-
:count:自应用程序启动以来运行的垃圾回收总次数(计数包括次要和主要垃圾回收)。 -
:time:花费在垃圾回收上的总时间(以毫秒为单位)。 -
:heap_allocated_pages:已分配页面的总数。 -
:heap_empty_pages:没有活动对象的页面数量,可以释放给系统。 -
:heap_sorted_length:可以放入保存所有页面引用的缓冲区的页面数量。 -
:heap_allocatable_pages:应用程序无需额外 GC 即可分配的总页面数量。 -
:heap_available_slots:所有:heap_allocated_pages中的总槽数。 -
:heap_live_slots:包含活动对象的总槽数。 -
:heap_free_slots:不包含活动对象的总槽数。 -
:heap_final_slots:具有待运行终结器的总槽数。 -
: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:自进程启动以来运行的主垃圾回收总次数。 -
:compact_count:自进程启动以来运行的压缩总次数。 -
:read_barrier_faults:在压缩期间触发读屏障的总次数。 -
:total_moved_objects:压缩已移动的总对象数。 -
:remembered_wb_unprotected_objects:没有写屏障的对象总数。 -
:remembered_wb_unprotected_objects_limit:当:remembered_wb_unprotected_objects跨越此限制时,将触发主 GC。 -
:old_objects:至少经历了 3 次垃圾回收的活动年老对象数量。 -
:old_objects_limit:当:old_objects跨越此限制时,将触发主 GC。 -
:oldmalloc_increase_bytes:为对象在堆上分配的内存量。主 GC 会减少此值。 -
:oldmalloc_increase_bytes_limit:当:oldmalloc_increase_bytes跨越此限制时,将触发主 GC。
Source
# File gc.rb, line 389 def self.stat_heap heap_name = nil, hash_or_key = nil Primitive.gc_stat_heap heap_name, hash_or_key end
此方法是 CRuby 的特定实现。
返回 GC 堆的统计信息。具体的统计信息是特定于实现的,并且将来可能会在不另行通知的情况下更改。
如果没有给出参数,则返回所有堆的统计信息
GC.stat_heap # => {0 => {slot_size: 40, heap_eden_pages: 246, heap_eden_slots: 402802, total_allocated_pages: 246, force_major_gc_count: 2, force_incremental_marking_finish_count: 1, total_allocated_objects: 33867152, total_freed_objects: 33520523}, 1 => {slot_size: 80, heap_eden_pages: 84, heap_eden_slots: 68746, total_allocated_pages: 84, force_major_gc_count: 1, force_incremental_marking_finish_count: 4, total_allocated_objects: 147491, total_freed_objects: 90699}, 2 => {slot_size: 160, heap_eden_pages: 157, heap_eden_slots: 64182, total_allocated_pages: 157, force_major_gc_count: 0, force_incremental_marking_finish_count: 0, total_allocated_objects: 211460, total_freed_objects: 190075}, 3 => {slot_size: 320, heap_eden_pages: 8, heap_eden_slots: 1631, total_allocated_pages: 8, force_major_gc_count: 0, force_incremental_marking_finish_count: 0, total_allocated_objects: 1422, total_freed_objects: 700}, 4 => {slot_size: 640, heap_eden_pages: 16, heap_eden_slots: 1628, total_allocated_pages: 16, force_major_gc_count: 0, force_incremental_marking_finish_count: 0, total_allocated_objects: 1230, total_freed_objects: 309}}
在上例中,外层哈希的键是堆标识符
GC.stat_heap.keys # => [0, 1, 2, 3, 4]
在 CRuby 上,每个堆标识符都是一个整数;在其他实现上,堆标识符可能是字符串。
如果只给出参数 heap_id,则返回给定堆标识符的统计信息
GC.stat_heap(2) # => {slot_size: 160, heap_eden_pages: 157, heap_eden_slots: 64182, total_allocated_pages: 157, force_major_gc_count: 0, force_incremental_marking_finish_count: 0, total_allocated_objects: 225018, total_freed_objects: 206647}
如果给出了参数 heap_id 和 key,则返回给定堆中给定键的值
GC.stat_heap(2, :slot_size) # => 160
如果给出了参数 nil 和 hash,则将所有堆的统计信息合并到给定的哈希中
h = {foo: 0, bar: 1} GC.stat_heap(nil, h).keys # => [:foo, :bar, 0, 1, 2, 3, 4]
如果给出了参数 heap_id 和 hash,则将给定堆的统计信息合并到给定的哈希中
h = {foo: 0, bar: 1} GC.stat_heap(2, h).keys # => [:foo, :bar, :slot_size, :heap_eden_pages, :heap_eden_slots, :total_allocated_pages, :force_major_gc_count, :force_incremental_marking_finish_count, :total_allocated_objects, :total_freed_objects]
堆的统计信息可能包括
-
:slot_size:堆的槽大小(以字节为单位)。 -
:heap_allocatable_pages:在不触发新的垃圾回收周期的情况下可以分配的页面数量。 -
:heap_eden_pages:eden 堆中的页面数量。 -
:heap_eden_slots:eden 堆中所有页面的总槽数。 -
:total_allocated_pages:堆中已分配的总页面数。 -
:total_freed_pages:已释放并返回给系统的堆中总页面数。 -
:force_major_gc_count:由于缺乏空闲槽而强制启动主垃圾回收周期的次数。 -
:force_incremental_marking_finish_count:由于缺乏池化槽而强制完成增量标记的次数。
Source
# File gc.rb, line 87 def self.stress Primitive.gc_stress_get end
返回当前的 GC 压力模式设置,初始为 false。
可以通过方法 GC.stress= 设置压力模式。
Source
# File gc.rb, line 111 def self.stress=(flag) Primitive.gc_stress_set_m flag end
启用或禁用压力模式;启用压力模式会降低性能;仅用于调试。
将当前 GC 压力模式设置为给定值
-
如果值为
nil或false,则禁用压力模式。 -
如果值为整数,则启用带有特定标志的压力模式;请参阅下文。
-
否则,启用压力模式;GC 在每个 GC 机会被调用:所有内存和对象分配。
标志是给定整数中的位
-
0x01:无主 GC。 -
0x02:无即时清理。 -
0x04:malloc/calloc/realloc 后完全标记。
Source
# File gc.rb, line 585 def self.total_time Primitive.cexpr! %{ ULL2NUM(rb_gc_impl_get_total_time(rb_gc_get_objspace())) } end
返回 GC 总时间(以纳秒为单位)
GC.total_time # => 156250
请注意,总时间仅在启用总时间测量时累加(即,当 GC.measure_total_time 为 true 时)
GC.measure_total_time # => true GC.total_time # => 625000 GC.start GC.total_time # => 937500 GC.start GC.total_time # => 1093750 GC.measure_total_time = false GC.total_time # => 1250000 GC.start GC.total_time # => 1250000 GC.start GC.total_time # => 1250000 GC.measure_total_time = true GC.total_time # => 1250000 GC.start GC.total_time # => 1406250
Public Instance Methods
Source
# File gc.rb, line 48 def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false end
是 GC.start 的别名