class IdleGC

Overview

IdleGC runs garbage collection periodically in order to keep memory usage low. It attempts to do so when the process is otherwise idle.

To start, just call:

IdleGC.start

That is all that most use cases will need! Tweaks and tuning information are below.

You may manually force a collection now (synchronously) with IdleGC.collect. Or, if you would like to manually run collection synchronously but only if idle, call IdleGC.collect_if_idle. To request a collection at the next idle opportunity, use IdleGC.background_collect.

In addition to timer-based periodic operation which is started by IdleGC.start, you may wish to use request-based operation. For example, this could do background GC after every 100 web requests, or after every 10 MB served. To use this mode, first set IdleGC::Request.request_limit = 100*1024*1024 (for example), and then call IdleGC::Request.request(num_bytes) to increment. This IdleGC::Request module will wait until the count overflows your limit, and will then fire off an IdleGC.background_collect.

In the extremely unlikely case that your code does not yield or do any I/O, you may need to add explicit calls to Fiber.yield to allow IdleGC's background Fiber to have a chance to work.

By default, IdleGC::Timer polls every 1 second, and if more than 0 bytes have been allocated on the heap, it runs garbage collection. To make IdleGC::Timer less aggressive (and use less CPU time, at the cost of higher memory usage), you may raise both of these settings, for example: IdleGC::Timer.poll_interval = 5.seconds and IdleGC::Timer.bytes_since_gc_threshold = 128*1024.

Idle detection is based on a measurement of how long it takes Fiber.yield to return, and can be tuned with IdleGC::IdleDetection.idle_threshold=. If interactive performance (latency) is not a concern for your application, it is recommended that you disable idle detection with IdleGC::IdleDetection.enabled = false.

Since idle detection may be inaccurate, there is a IdleGC::Timer.force_gc_period= which is set to force a collection every 2 minutes by default. You may disable this with IdleGC::Timer.force_gc_period = nil.

Defined in:

idle-gc.cr
idle-gc/idle_detection.cr
idle-gc/request.cr
idle-gc/timer.cr

Constant Summary

DEFAULT_BACKGROUND_COLLECT_POLL_INTERVAL = 10.milliseconds
VERSION = "1.0.1"

Class Method Summary

Class Method Detail

def self.background_collect : Bool #

Kick off a Fiber to do collection at the next idle opportunity.

Returns true if a background collection was scheduled. Returns false if there was already one scheduled.


[View source]
def self.background_collect_poll_interval=(v : Time::Span) : Nil #

How often should the background_collect Fiber check for idle?


[View source]
def self.collect : Nil #

Explicitly force collection now.


[View source]
def self.collect_if_idle : Bool #

Collect now, but only if process is idle.


[View source]
def self.last_checked_at : Time::Span | Nil #

Relative to Time.monotonic, when did IdleGC last check whether or not to run garbage collect?

Returns nil if we've never checked.


[View source]
def self.last_collected_at : Time::Span | Nil #

Relative to Time.monotonic, when did IdleGC last initiate GC.collect?

Returns nil if we've never collected.


[View source]
def self.last_collected_duration : Time::Span | Nil #

How long did GC.collect take to run?

Returns nil if we've never collected.


[View source]
def self.start : Nil #

Start a background Fiber that runs garbage collection periodically.

(Also runs garbage collection immediately.)


[View source]