The simple answer is: Ruby runtime has a garbage collector. Different algorithms are used depending on the runtime (JRuby / JVM generational GC, IronRuby / CLR generational GC, classic Ruby / mark-sweep GC). But the basics are pretty simple:
- When asking for allocation, if "not enough free memory" is available - how much is not enough is one of the ingredients of the GC algorithm, then GC will start
- The GC begins by scanning the roots , which are global variables and stack locations (parameters and local variables), to discover which objects are still alive; he marks every object found.
- Then the GC process looks through the links (links) inside these objects and recurses into those objects that have not yet been marked
- Then the GC can start moving / copying all marked objects so that they are compacted in memory
- The "free pointer" where new allocations come from is reset to the end of this compact memory block
- If there is still "insufficient free memory," then more is allocated from the operating system.
- All old objects that were not marked during the scanning process are garbage and are implicitly discarded using the copy process and resetting the free pointer.
The collection frequency depends on the GC setting, which may be affected by the operating system, the amount of physical memory, the pressure in the operating system memory, user-controlled settings, revisions of the base platform version, dynamically optimized parameters, etc. Many of them come down to deciding where the bar is in the "insufficient free memory" test, although things become more complicated with collectors in collections.
Barry kelly
source share