Search code examples
rubymemorymethods

Size of object, in bytes


Is there a method to see the size of allocated memory for a class instance in Ruby?

I have built a custom class and I would like to know its size its objects in memory. So is there a function with the likeness of sizeof() in C?

I am simply trying to initialize a new object like so

test = MyClass.new

and trying to find a method to print out the size of the object that has been allocated to memory.

Is this even possible in Ruby?


Solution

  • There is no language feature that calculates the size of a class in the same way as C.

    The memory size of an object is implementation dependent. It depends on the implementation of the base class object. It is also not simple to estimate the memory used. For example, strings can be embedded in an RString structure if they are short, but stored in the heap if they are long (Never create Ruby strings longer than 23 characters).

    The memory taken by some objects has been tabulated for different ruby implementations: Memory footprint of objects in Ruby 1.8, EE, 1.9, and OCaml

    Finally, the object size may differ even with two objects from the same class, since it is possible to arbitrarily add extra instance variables, without hardcoding what instance variables are present. For example, see instance_variable_get and instance_variable_set


    If you use MRI ruby 1.9.2+, there is a method you can try (be warned that it is looking at only part of the object, this is obvious from the fact that integers and strings appear to have zero size):

    irb(main):176:0> require 'objspace'
    => true
    irb(main):176:0> ObjectSpace.memsize_of(134)
    => 0
    irb(main):177:0> ObjectSpace.memsize_of("asdf")
    => 0
    irb(main):178:0> ObjectSpace.memsize_of({a: 4})
    => 184
    irb(main):179:0> ObjectSpace.memsize_of({a: 4, b: 5})
    => 232
    irb(main):180:0> ObjectSpace.memsize_of(/a/.match("a"))
    => 80
    

    You can also try memsize_of_all (note that it looks at the memory usage of the whole interpreter, and overwriting a variable does not appear to delete the old copy immediately):

    irb(main):190:0> ObjectSpace.memsize_of_all
    => 4190347
    irb(main):191:0> asdf = 4
    => 4
    irb(main):192:0> ObjectSpace.memsize_of_all
    => 4201350
    irb(main):193:0> asdf = 4
    => 4
    irb(main):194:0> ObjectSpace.memsize_of_all
    => 4212353
    irb(main):195:0> asdf = 4.5
    => 4.5
    irb(main):196:0> ObjectSpace.memsize_of_all
    => 4223596
    irb(main):197:0> asdf = "a"
    => "a"
    irb(main):198:0> ObjectSpace.memsize_of_all
    => 4234879
    

    You should be very careful because there is no guarantee when the Ruby interpreter will perform garbage collection. While you might use this for testing and experimentation, it is recommended that this is NOT used in production!