Visualizing Garbage Collection in Rubinius, JRuby and Ruby 2.0

Visualizing Garbage Collection in Rubinius, JRuby and Ruby 2.0

In this talk we’ll dive into Ruby internals and take a close look at an ugly topic: garbage collection. How do these Ruby VM’s allocate memory for new objects? How do they identify unused objects? How do they reclaim memory from garbage objects, allowing it to be used again?

You can learn a lot about someone from their garbage. Using a series of diagrams, we’ll visually compare and contrast the complex algorithms these very different Ruby implementations use. What computer science research is behind each garbage collector? We’ll also look at the GC changes planned for the upcoming Ruby 2.1 release.

Eb5382b137146b381dd13740d165d1f2?s=128

Pat Shaughnessy

November 09, 2013
Tweet

Transcript

  1. None
  2. allocate identify reclaim

  3. None
  4. None
  5. class Node def initialize(val) @value = val end end p

    Node.new(1) => #<Node:0x007fc72a17e5f0 @value=1> p Node.new(2) => #<Node:0x007fc72a17e4b0 @value=2>
  6. allocate identify reclaim generational

  7. None
  8. n1 "ABC" n1 = Node.new("ABC")

  9. n2 = Node.new("DEF") n1 "ABC" n2 "DEF"

  10. n1 "ABC" n3 = Node.new("GHI") n3 "GHI" n2 "DEF"

  11. Courtesy MIT Museum

  12. Courtesy MIT Museum Mike Bernstein? from Code Climate

  13. Courtesy MIT Museum John McCarthy

  14. None
  15. None
  16. n1 = Node.new("ABC") n1 next "ABC"

  17. n2 = Node.new("DEF") next n1 "ABC" n2 "DEF"

  18. n3 = Node.new("GHI") next n1 "ABC" n2 "DEF" n3 "GHI"

  19. n1 "ABC" n1 = Node.new("ABC") Node klass @value (RObject) (RString)

    (RClass) RVALUE
  20. M n1 = Node.new("More than 23 chars here...") (RString) o

    r e t h a n etc...
  21. n1 = Node.new("More than 23 chars here...") n1 next (RubyObject)

    Node (RubyClass) (RubyString) "More than 23 chars here..." (ByteArray)
  22. allocate identify reclaim generational

  23. n1 "ABC" n3 = Node.new("GHI") n3 "GHI" n2 "DEF"

  24. n3 "GHI" n2 "DEF" "ABC" n1 "JKL" n1 = Node.new("JKL")

  25. n3 "GHI" n2 "DEF" "ABC" n1 "MNO" "JKL" n1 =

    Node.new("MNO")
  26. n3 "GHI" n2 "DEF" "ABC" "JKL" "MNO" n1 "PQR" n1

    = Node.new("PQR")
  27. None
  28. n2 n3 n1

  29. stop the world marking

  30. n2 n3 n1 M M M

  31. n2 n3 n1 1 1 1 0 0 0 0

    0
  32. n2 n3 n1 M M M

  33. M M M M M M

  34. concurrent marking

  35. M M M M Collector

  36. M M M M Collector New Object "Mutator"

  37. M M M M not garbage! M M

  38. None
  39. None
  40. Root Objects Remaining Objects Collector

  41. Mark Stack Remaining Objects Collector M Marked Objects

  42. M M Garbage Objects Live Objects M M

  43. M New Object Mark Stack Remaining Objects Marked Objects Collector

    "Mutator"
  44. None
  45. M M New Object "Mutator" write barrier

  46. allocate identify reclaim generational

  47. n2 n3 n1 M M M

  48. n2 n3 n1 M M M

  49. M M M M M From-Space To-Space

  50. M M M M M next allocation From-Space To-Space

  51. next allocation From-Space To-Space

  52. None
  53. Eden Heap next allocation From-Space To-Space

  54. allocate identify reclaim generational

  55. M M M M M next allocation From-Space To-Space

  56. n1 = Node.new("ABC")

  57. weak generational hypothesis

  58. From-Space To-Space promoted promoted

  59. Young Generation Mature Generation ?

  60. jruby -J-XX:+UseConcMarkSweepGC jruby -J-XX:+UseParallelGC jruby -J-XX:+UseSerialGC jruby -J-XX:+UseG1GC

  61. None
  62. None
  63. None
  64. MRI Ruby 2.1

  65. Young Objects Mature Objects

  66. Young Objects Mature Objects

  67. Always marked Not marked again until a full GC

  68. ? live or garbage? Young Mature

  69. Write Barrier ? live or garbage? Young Mature

  70. None
  71. None