Search code examples
rubyuuid

Why does the string created with SecureRandom.uuid in Ruby take 77 bytes?


Why does the string created with SecureRandom.uuid in Ruby 2.6.6 take exactly 77 bytes?

irb(main):018:0> ObjectSpace.memsize_of(SecureRandom.uuid)
=> 77

If I copy and paste the string it will take only 40.

irb(main):021:0> SecureRandom.uuid
=> "bfd59b9c-3248-409f-bcba-2df11df62c13"
irb(main):022:0> ObjectSpace.memsize_of("bfd59b9c-3248-409f-bcba-2df11df62c13")
=> 40

Solution

  • If you look here https://github.com/ruby/ruby/blob/b59077eecf912a16efefc0256f6e94a000ce3888/gc.c#L4066 you can see, that memsize_of returns

    size + sizeof(RVALUE)
    

    where size calculation is kinda complicated, but you should be able to find the proper branch for T_STRING easily:

    size += rb_str_memsize(obj);
    

    In turn, if you look at the latter - https://github.com/ruby/ruby/blob/8c2e5bbf58e562ea410b53c2f77e4186d5ca9da3/string.c#L1404 - you will see it returns either 0 or STR_HEAP_SIZE(str) - the actual space allocated for the string's content.

    I don't fully understand the flags' meaning (don't know Ruby internals well enough), but I suppose they are just different for literals and strings created in runtime - so your last case gives you just the size of RVALUE itself (40 bytes) while the first one adds the real string data size to it...