模块 GC
GC 模块为 Ruby 的标记清除垃圾回收机制提供了一个接口。
一些底层方法也可以通过 ObjectSpace
模块访问。
您可以通过 GC::Profiler 获取有关 GC 操作的信息。
公共类方法
设置或获取有关当前 GC 配置的信息。
配置参数特定于 GC 实现,可能会在不通知的情况下更改。
此方法可以不带参数调用,以检索当前配置,作为带有 Symbol
键的 Hash
。
此方法也可以使用 Hash
参数调用,以将值分配给有效的配置键。传递的 Hash
中缺少的配置键将保持不变。
如果将一个不对应于正在使用的 GC 实现的有效配置键的键/值对传递给此函数,则不会更新任何配置,该键将出现在返回的 Hash
中,其值将为 nil
。这是为了方便在 GC 实现之间轻松迁移。
在两种调用序列中,GC.config
的返回值都将是一个 Hash
,其中包含最新的完整配置,即特定 GC 实现定义的所有键和值。在配置更新的情况下,返回值将包括正在更新的新值。
此方法预计仅在 CRuby 上有效。
GC 实现无关的值¶ ↑
GC.config
哈希还可以包含全局且只读的键。这些键不特定于任何一个 GC 库实现,尝试写入它们将引发 ArgumentError
。
当前只有一个全局只读键
- 实现
-
返回一个
String
,其中包含当前加载的 GC 库的名称(如果已使用RUBY_GC_LIBRARY
加载),否则返回“default”
GC 实现特定的值¶ ↑
GC 库应该记录自己的配置。Ruby 默认 GC 实现的有效键是
- rgengc_allow_full_mark
-
控制是否允许 GC 运行完全标记(年轻和旧对象)。
当为
true
时,GC 会交错进行主要和次要的回收。这是默认设置。GC 将按预期运行。当为
false
时,除非用户代码显式请求,否则 GC 永远不会触发完全标记循环。相反,只会运行次要标记——只会标记年轻对象。当堆空间耗尽时,将立即分配新页面,而不是运行完全标记。将设置一个标志来通知已请求完全标记。可以使用
GC.latest_gc_info(:needs_major_by)
访问此标志用户可以随时使用
GC.start(full_mark: true)
触发主要回收当为
false
时,禁用从年轻到旧对象的提升。出于性能原因,建议在将此参数设置为false
之前使用Process.warmup
预热应用程序。
# File ruby_3_4_1/gc.rb, line 318 def self.config hash = nil return Primitive.gc_config_get unless hash 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 else raise ArgumentError end end
返回自进程启动以来发生 GC 的次数。
# File ruby_3_4_1/gc.rb, line 100 def self.count Primitive.gc_count end
禁用垃圾回收,如果垃圾回收已禁用,则返回 true
。
GC.disable #=> false GC.disable #=> true
# File ruby_3_4_1/gc.rb, line 66 def self.disable Primitive.gc_disable end
启用垃圾回收,如果先前禁用垃圾回收,则返回 true
。
GC.disable #=> false GC.enable #=> true GC.enable #=> false
# File ruby_3_4_1/gc.rb, line 54 def self.enable Primitive.gc_enable end
返回有关最近垃圾回收的信息。
如果给定的参数 hash
是一个 Hash
对象,则它会被覆盖并返回。这是为了避免探针效应。
如果给定的参数 key
是一个 Symbol
对象,则它返回与该键关联的值。这等效于 GC.latest_gc_info[key]
。
# File ruby_3_4_1/gc.rb, line 346 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
返回 measure_total_time
标志(默认值:true
)。请注意,测量可能会影响应用程序的性能。
# File ruby_3_4_1/gc.rb, line 376 def self.measure_total_time Primitive.cexpr! %{ RBOOL(rb_gc_impl_get_measure_total_time(rb_gc_get_objspace())) } end
启用测量 GC 时间。您可以使用 GC.stat(:time)
获取结果。请注意,GC 时间测量可能会导致一些性能开销。
# File ruby_3_4_1/gc.rb, line 364 def self.measure_total_time=(flag) Primitive.cstmt! %{ rb_gc_impl_set_measure_total_time(rb_gc_get_objspace(), flag); return flag; } end
启动垃圾回收,即使手动禁用也是如此。
full_mark
关键字参数确定是否执行主要垃圾回收循环。设置为 true
时,将运行主要垃圾回收循环,这意味着将标记所有对象。设置为 false
时,将运行次要垃圾回收循环,这意味着仅标记年轻对象。
immediate_mark
关键字参数确定是否执行增量标记。设置为 true
时,标记会在调用此方法期间完成。设置为 false
时,标记会分步骤执行,与未来的 Ruby 代码执行交错,因此标记可能不会在此方法调用期间完成。请注意,如果 full_mark
为 false
,则无论 immediate_mark
的值如何,标记都将始终是即时的。
immediate_sweep
关键字参数确定是否延迟扫描(使用延迟扫描)。设置为 false
时,扫描会分步骤执行,与未来的 Ruby 代码执行交错,因此扫描可能不会在此方法调用期间完成。设置为 true
时,扫描会在调用此方法期间完成。
注意:这些关键字参数依赖于实现和版本。不能保证它们在未来兼容,如果底层实现不支持,则可能会被忽略。
# File ruby_3_4_1/gc.rb, line 35 def self.start full_mark: true, immediate_mark: true, immediate_sweep: true Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false end
返回一个 Hash
,其中包含有关 GC 的信息。
哈希的内容特定于实现,可能会在未来更改,恕不另行通知。
哈希包含有关 GC 的内部统计信息,例如
- 计数
-
自应用程序启动以来运行的垃圾回收总数(计数包括次要和主要垃圾回收)
- 时间
-
在垃圾回收中花费的总时间(以毫秒为单位)
- heap_allocated_pages
-
:heap_eden_pages
+:heap_tomb_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
-
包含至少一个活动槽的页面总数
- heap_tomb_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
如果给定可选参数哈希,则会覆盖并返回它。这是为了避免探针效应。
此方法预计仅在 CRuby 上有效。
# File ruby_3_4_1/gc.rb, line 184 def self.stat hash_or_key = nil Primitive.gc_stat hash_or_key end
返回 GC 中堆的信息。
如果传入第一个可选参数 heap_name
且不为 nil
,则返回一个包含特定堆信息的 Hash
。否则,它将返回一个 Hash
,其中堆名称为键,包含堆信息的 Hash
为值。
如果第二个可选参数 hash_or_key
作为 Hash
给出,它将被覆盖并返回。这旨在避免探测效应。
如果同时传入两个可选参数,并且第二个可选参数是一个符号,它将返回特定堆的 Numeric
值。
在 CRuby 上,heap_name
的类型为 Integer
,但在其他实现上可能为 String
类型。
哈希的内容特定于实现,可能会在未来更改,恕不另行通知。
如果给出了可选参数 hash,它将被覆盖并返回。
此方法预计仅在 CRuby 上有效。
该哈希包含有关 GC 内部信息的以下键
- slot_size
-
堆的槽大小(以字节为单位)。
- heap_allocatable_pages
-
在不触发新的垃圾回收周期的情况下可以分配的页数。
- heap_eden_pages
-
伊甸园堆中的页数。
- heap_eden_slots
-
伊甸园堆中所有页的总槽数。
- heap_tomb_pages
-
墓地堆中的页数。墓地堆仅包含没有任何活动对象的页面。
- heap_tomb_slots
-
墓地堆中所有页的总槽数。
- total_allocated_pages
-
堆中已分配的总页数。
- total_freed_pages
-
堆中已释放并返回给系统的总页数。
- force_major_gc_count
-
由于空闲槽耗尽,此堆已强制启动主垃圾回收周期的次数。
- force_incremental_marking_finish_count
-
由于池化槽耗尽,此堆已强制完成增量标记的次数。
# File ruby_3_4_1/gc.rb, line 247 def self.stat_heap heap_name = nil, hash_or_key = nil Primitive.gc_stat_heap heap_name, hash_or_key end
返回 GC 压力模式的当前状态。
# File ruby_3_4_1/gc.rb, line 74 def self.stress Primitive.gc_stress_get end
更新 GC 压力模式。
当启用压力模式时,GC 会在每个 GC 机会时被调用:所有内存和对象分配。
启用压力模式会降低性能;它仅用于调试。
标志可以是 true、false 或与以下标志按位或运算的整数
0x01:: no major GC 0x02:: no immediate sweep 0x04:: full mark after malloc/calloc/realloc
# File ruby_3_4_1/gc.rb, line 92 def self.stress=(flag) Primitive.gc_stress_set_m flag end
以纳秒为单位返回测量的 GC 总时间。
# File ruby_3_4_1/gc.rb, line 386 def self.total_time Primitive.cexpr! %{ ULL2NUM(rb_gc_impl_get_total_time(rb_gc_get_objspace())) } end
公共实例方法
GC.start
的别名
# File ruby_3_4_1/gc.rb, line 40 def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false end