Memory overhead for small objects: often underestimated
Added information about the cost of a Symbol (also heavier than you might have expected), and the RStruct optimization in 1.9.
It is well known that the minimal space overhead for a non-immediate object in Ruby is 20 bytes*1. But the overhead will be much higher if your object happens to have instance variables (read: almost always).
Take for instance
class Stupid; attr_accessor :foo end class Stupid2; attr_accessor :foo, :bar end o1 = Stupid.new o1.foo = 1 o2 = Stupid2.new o2.foo = 1 o2.bar = 2
o1 will take around and o2 bytes, i.e. for objects with under 55 instance variables, the memory footprint is around 100 bytes plus 20 bytes per instance variable --- that's quite heavy.
The exact numbers depend on the behavior of malloc regarding memory alignment and overhead. Doug Lea's malloc, in wide use, takes 8 or 4 bytes per chunk.
Here are some other overheads for Arrays, Hashes, Symbols, etc. (+M denotes the malloc overhead per allocated chunk, normally 4 or 8 bytes):
- basic RVALUE overhead: 20 bytes
- Array: add 16 * 4 (+M) [ptr] (up to 16 elements)
- object with instance variables: add 16(+M) [st_table] + 11 * 4 (+M) [bins] + 4 * 4 (+M) [st_table_entry] (bins: constant up to 55 instance variables; add 4 * 4 (+M) per element)
- Hash: add 16(+M) + 11 * 4 (+M) + 4 * 4 (similar to the iv_tbl overhead)
- Struct: add 4 (+M) per "attribute"
- a Symbol takes sym.to_s.size + 1 (typically padded to 8 bytes, with a minimum of 16 bytes) plus 2 * (16 (+M)) (minimum), e.g. after you do "foo".to_sym, ~56 bytes are allocated, never to be released
In Ruby 1.9, up to 3 attributes can be packed in the internal RStruct structure, which means that in
Foo = Struct.new(:a, :b, :c) a = Foo.new(1,2,3)
the object referenced by a takes only 20 bytes, instead of 44/68 bytes as in previous versions. Compare that cost (20 bytes in 1.9, ~50 in 1.8) to that of a normal object with 3 instance variables: around 160 bytes, that is 3 to 8 times heavier!
*1 all the values given here correspond to a 32bit platform
- 44 http://planetruby.0x42.net
- 33 http://www.artima.com/forums/flat.jsp?forum=123&thread=155877
- 21 http://anarchaia.org
- 18 http://www.artima.com/buzz/community.jsp?forum=123
- 18 http://ozmm.org
- 14 http://lists.netisland.net/archives/phillyonrails/phillyonrails-2006/msg00133.html
- 13 http://lists.netisland.net/archives/phillyonrails/phillyonrails-2006/msg00132.html
- 9 http://www.anarchaia.org
- 7 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/242128
- 7 http://anarchaia.org/archive/2006/04/11.html