Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Public Class Methods
2.1.
Allocation_generation(object) → integer or nil
2.2.
Allocation_class_path(object) → string
2.3.
allocation_method_id(object) → string
2.4.
Allocation_sourcefile(object) → string
2.5.
Allocation_sourceline(object) → string
2.6.
count_imemo_objects([result_hash]) → hash
2.7.
count_nodes([result_hash]) → hash
3.
Garbage Collection
3.1.
How does Garbage Collection work in Ruby? 
3.2.
Mark and Sweep Algorithms
3.3.
 Type of Garbage Collection
4.
Frequently Asked Questions
4.1.
What is Object Space?
4.2.
What is Garbage Collection?
4.3.
What are the types of garbage collection?
5.
Conclusion
Last Updated: Mar 27, 2024
Easy

Object Space and Garbage Collections in Ruby

Author Sarthak
0 upvote

Introduction

 Various functions in the ObjectSpace module interact with the trash collection system and help you use an iterator to traverse all living objects. The ObjectSpace module can be extended by the “objspace” library, which also includes several methods for retrieving internal statistics regarding object/memory management. To utilize this extension module, you must specify the requirement "objspace". You may use an iterator to traverse all living objects thanks to various procedures in the ObjectSpace module that interface with the garbage collection system. The procs known as object finalizers, which ObjectSpace supports, are called right before a specific object is destroyed by garbage collection.

Object Space and GC
require 'objspace'
a = "A"
b = "B"
ObjectSpace.define_finalizer(a, proc {|id| puts "Finalizer one on #{id}" })
ObjectSpace.define_finalizer(b, proc {|id| puts "Finalizer two on #{id}" })
Gives:
Finalizer two on 537763470
Finalizer one on 537763480
You can also try this code with Online Ruby Compiler
Run Code

Public Class Methods

_id2ref→ an_object

In this, we will convert the object id to a reference to the object. It may not called on an object id passed as a parameter to a finalizer.

s = "It is a string" #=> "It is a string"
r = ObjectSpace._id2ref(s.object_id) #=> "I am a string"
r == s #=> true
You can also try this code with Online Ruby Compiler
Run Code

Allocation_generation(object) → integer or nil

class B
  include ObjectSpace
  def foo
    trace_object_allocations do
      obj = Object.new
      p "Generation is #{allocation_generation(obj)}"
    end
  end
end

B.new.foo #=> "Generation is 3"
You can also try this code with Online Ruby Compiler
Run Code

Allocation_class_path(object) → string

class A
  def foo
    ObjectSpace::trace_object_allocations do
      obj = Object.new
      p "#{ObjectSpace::allocation_class_path(obj)}"
    end
  end
end

A.new.foo #=> "Class"
You can also try this code with Online Ruby Compiler
Run Code

allocation_method_id(object) → string

It returns the method identifier for the given object.

class A

include ObjectSpace

  def foo
    trace_object_allocations do
      obj = Object.new
      p "#{allocation_class_path(obj)}##{allocation_method_id(obj)}"
    end
  end
end

A.new.foo #=> "Class#new"
You can also try this code with Online Ruby Compiler
Run Code

Allocation_sourcefile(object) → string

It returns the source file origin from the given object.

Allocation_sourceline(object) → string

It will return the original line from the source for the given object.

count_imemo_objects([result_hash]) → hash

Counts objects for each T_IMEMO type.

Only MRI developers who are curious about the speed and memory consumption of Ruby programmes should use this technique. It returns the  hash as :-

{:imemo_ifunc=>8,
 :imemo_svar=>7,
 :imemo_cref=>509,
 :imemo_memo=>1,
 :imemo_throw_data=>1}
You can also try this code with Online Ruby Compiler
Run Code

The result hash argument, which is optional, is overwritten and returned. It is done to prevent the probing effect. The returned hash's contents are implementation-specific and subject to change. The keys are symbol objects in this version.Only C Ruby is anticipated to function with this method.

count_nodes([result_hash]) → hash

counts the number of each sort of node.

Only MRI developers are curious about Ruby application speed and memory utilization should use this technique.

It returns a hash as:

{:NODE_METHOD=>2027,
 :NODE_FBODY=>1927,
 :NODE_CFUNC=>1798, ...}
You can also try this code with Online Ruby Compiler
Run Code

The result hash parameter, which is optional, is overwritten and returned. It is done to prevent the probing effect.

Note: The contents of the returned hash are implementation-defined. In the future, it could change.

Only C Ruby is anticipated to function with this technique.

Garbage Collection

The management of computer program memory utilization is done by garbage collection. The concept underlying garbage collection and other memory management techniques like reference counting are that the language keeps track of which a program, not the programmer, is using objects. It allows the programmer to concentrate on the business logic or other issue rather than stressing over the specifics of allocating and clearing memory. It also improves application stability and security because poor memory management can cause crashes and memory management problems to account for any security flaws. 

Despite the wide variety of trash collection methods, the fundamental idea never changes. The runtime of a programming language periodically searches through the program's memory to "figure out" whether objects or data structures are no longer in use. A piece of data or something no longer in use is trash. Other software components may release and utilize its memory. The trash collector must free that memory. The garbage collection method and implementation determine how and when the object scanning and use determination occurs.

How does Garbage Collection work in Ruby? 

The simplest form of creating a Ruby object is allocating memory for it. The thing continues to exist for a time, ideally serving a purpose. Ruby designates that memory region as open for future use by other objects after the object is no longer in use.

You may read GCC if you want the full implementation with nothing left out. All you need to do is read C. There are around 12,000 lines in it. Whew. Let's review the critical components of the Ruby garbage collector instead of doing that.

Ruby uses two distinct types of memory. The malloc heap is first. This chunk of memory contains all the information in your application. If Ruby determines that the memory is not being utilized after a garbage collection, it is not released back to the operating system. Data structures controlled by a C extension and string buffers are two examples of items that reside in this heap.

The Ruby object heap is the second. Most Ruby objects are stored in this section of the malloc heap. They could point to the malloc heap if they are huge. This post will concentrate on the Ruby heap, which is what the Ruby garbage collector watches over and cleans up.

Pages are used to divide up the Ruby heap, Slots exist on pages and can be either empty or reference an object and Forty bytes are used for objects.

Mark and Sweep Algorithms

Any trash collection algorithm must complete two fundamental tasks. One, it must be able to identify all inaccessible objects, and two, it must recover the heap space that the garbage objects had taken up and make it available to the program once more. It has two phases:-

  • Mark phase
  • Sweep phase

Mark Phase:-The mark bit of an object is set to 0 when it is formed (false). In the Mark phase, we set the marked bit to 1 for any objects that are reachable or that the user can refer to (true). We now only need to traverse the graph to complete this operation; a depth-first search strategy would be suitable for us.

Sweep Phase:- In this phase, It eliminates all of the unreachable objects from the heap memory. All objects with marked values set to false are removed from heap memory, and the marked bit is set to true for all other objects. Since we will run the algorithm (if necessary) and repeat the mark phase to mark all the reachable items, the mark value for all the reachable objects is currently set to false.

 Type of Garbage Collection

There are various types of garbage collection:-

  • Incremental Garbage Collection
  • Generational Garbage Collection

Incremental Garbage Collection:- The absence of write barriers is a significant obstacle to total marking implementation in the Ruby interpreter (CRuby). There are not enough write barriers in Ruby.

Write barriers are required for the generational GC that was built. We developed a novel mechanism called "write unprotected barrier objects" to introduce generational GC. Thus, all items are separated into "write barrier protected objects" (protected objects) and "write unprotected barrier objects" (unprotected objects). We promise to manage every reference to protected objects. References from unprotected objects are not under our control. With the "unprotected object" concept, a generational GC can be implemented.

We can appropriately implement incremental GC with unprotected objects as well:

(1) Give everything in the world a white hue.

(2) Shade all alive things in grey, including those in the stack.

Choosing one grey item, go to each object it refers to, and then colour it grey. Make the original item black in colour. Repeat this process until only black and white remain. This action is carried out gradually.

(4) Since unprotected black objects can point to white things, it is best to scan all objects from unprotected black objects at once.

(5) Collect white items since all living things are black in hue.

Generational Garbage Collections:- Many items are utilized for a short time before being discarded. The heap of Ruby is big. When some objects are only alive during a function call, and others are alive for the length of a running program, it is ridiculous to inspect every item constantly. Ruby handles this by utilizing a generational trash collector to make the mark phase smarter.

We will keep track of how many times they have seen an object,

as Ruby 2.1 generational garbage collector takes use of the variations in object lifespan. An item is designated as being a "old" object and is handled differently from the younger objects if it has been viewed three times.

There are several regions of the Ruby heap when you use generational garbage collection. All new object allocations are kept in a section called "new object," which is present. Minor trash collection is the term used to describe frequent garbage collection of this sector, which is smaller than the total heap. Only during what is referred to be a complete trash collection are items in the "old object" area gathered as garbage.

Minor garbage collection also addresses other edge situations, such as new objects that reference an older object. Because of this, the Ruby approach is called Restricted Generational Garbage Collection (RGenGC). However, at the moment, CRuby employs the mark and sweep technique for both minor and major garbage collections. There is no requirement that both trash collections use the same algorithm.

Frequently Asked Questions

What is Object Space?

A variety of functions in the ObjectSpace module interact with the trash collection system and let you use an iterator to traverse all living objects. It also supports object finalizers, which are procs that are called just before a particular object is destroyed by garbage collection.

What is Garbage Collection?

Ruby suspends the execution of your program to perform garbage collection! We refer to this rubbish collection as "stop-the-world." It is necessary so that your code won't try to allocate memory when determining what has to be cleaned up.

Therefore, garbage collection must be as quick as feasible if our application has to pause every time it performs garbage collection.

What are the types of garbage collection?

There are different types of garbage collection:-

  1. Generational Garbage collection
  2. Incremental Garbage collection

Conclusion

In this blog, We have learned about Object space, types of Object Space, Garbage Collection, types of garbage collections, etc. 

After reading about Block Structure in Ruby, are you not feeling excited to read/explore more articles on the topic of Ruby? Don't worry; Coding Ninjas has you covered. To learn, see Ruby OOPs, and Object References in Ruby.

Refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingJavaScriptSystem Design, and many more! 

Do upvote our blogs if you find them helpful and engaging!

Live masterclass