Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Ruby's GC 20


Published on

I will talk about some improvements of GC in Ruby 2.0.0. For instance, I will introduce about implementations of Bitmap Marking GC and so on, and show results of benchmarks after these are implemented.

Animation version is here: (premium version)

Published in: Technology
  • Be the first to comment

Ruby's GC 20

  1. 1. #rubykaigi 03nari/@nari3/authorNariNetwork Applied Communication Laboratory2013/05/31Rubys GC 2.0
  2. 2. Self-introduction➔nari, @nari3, authorNari➔A CRuby committer➔GC entertainer➔“Nakamura”– is the most powerful clan in Ruby World
  3. 3. I went to Cebu in Philippines➔I studied English a month.➔But I cant speak English....
  4. 4. Because I was always alone
  5. 5. Because Im shy
  6. 6. Todays Agenda➔Non-recursive Marking➔Bitmap Marking– My work in Ruby 2.0.0
  7. 7. What is GC ?
  8. 8. GC collects alldead objects
  9. 9. What is a deadobject?
  10. 10. What is a dead object?➔A dead object is an object that isno longer referenced by theprogram➔In GC terms, we say a that deadobject is unreachable from Roots
  11. 11. What is Roots?➔Roots is a set of pointers thatdirectly reference objects in theprogram.– e.g. Rubys local variables, etc..
  12. 12. What is GC ?
  13. 13. GC collects objectsthat are unreachablefrom Roots.
  14. 14. CRubys GCSummary
  15. 15. CRubys GC➔Mark&Sweep➔Mark phase– mark all live(reachable) objects➔Sweep phase– free up all dead(unreachable) objects– Unmark all marked objects
  16. 16. []Root@mamiLeg []Body []@mami = nil@mami = [Leg]@mami[1] = [Body]@mami[1][1] = [Head]Head@mami[1].pop #=> [Head]GC.start
  17. 17. []Root@mamiLeg []Body []HeadMark phase[]Leg []Bodymarkmarkmarkmark all live(reachable) objects
  18. 18. []Root@mamiLeg []Body []HeadSweep phase[]Leg [][]Bodyunmarkunmark unmarkunmarkfreeFree all dead(unreachable) objectsUnmark all marked objects
  19. 19. You can buy a GC book atRubyKaigi!!
  20. 20. with autograph :)
  21. 21. Please dont throw this away
  22. 22. Non-recursiveMarking
  23. 23. Introduction ofRecursive Marking(a traditional way in CRuby)
  24. 24. Recursive MarkingAn object graph Machine Stackgc_mark()gc_mark()gc_mark()Framegc_mark()gc_mark()gc_mark()Recursive call
  25. 25. A bad case of asimple recursive call
  26. 26. Recursive MarkingA deep object graphgc_mark()gc_mark()gc_mark()Framegc_mark()gc_mark()gc_mark()gc_mark()・・・MaxSuddenlySEGVOverflow!!Machine Stack
  27. 27. In order to avoid astack overflow,CRuby adopted ...
  28. 28. KnuthsAlgorithmPhoto:
  29. 29. Whats a Knuths Algorithm?➔To avoid a stack overflow➔There is a fail-safe system whichconsists of two stages.– Using a marking buffer– Rescanning all objects
  30. 30. Using a marking bufferAgc_mark()gc_mark()Frame gc_mark()・・・MaxMachine StackBD ECFG・・・Marking bufferB CACBpush pushAvoding overflow!!
  31. 31. Marking all objects of themarking buffer at the endof the mark phaseAFrame gc_mark()Machine StackBD ECFG・・・Marking bufferB CACBgc_mark()rescan rescanD E FG
  32. 32. How do you deal withan overflow of themarking buffer?
  33. 33. Rescanning all objectsABD ECFG・・・Marking bufferS OACBoverflow!!R A HIgnoringrescan rescanrescanD E FGIts very slow!!
  34. 34. There are twoproblems
  35. 35. 1. fail-safe system is slow➔Rescanning is so slow.– If you have some deep object graphs,GC may be always slow withrescanning.
  36. 36. 2. We cant precisely checkstack overflow➔There is a trade-off between speedand precision.– Marking will be slow if we check stackoverflow in each gc_mark().– So we checked it at the appropriatetime.– But, its not precise.
  37. 37. 2. We cant precisely checkstack overflow➔This causes SEGV in the worst casescenario– For instance, Fiber sometimes failsunexpectedly.– Fiber uses small machine stack(128 KB)– At times, checking for stack overflowsdoesnt work well with Fiber.
  38. 38. So I decided to saygood bye to Knuth
  39. 39. Non-recursiveMarking
  40. 40. Non-recursive Marking➔Marking w/o the machine stack– w/ own Array based stack➔Recursive => Iterative
  41. 41. Rescanning all objectsABD ECFGStack chunk BACBFGmarkCmarkFmarkGmarkmarkMarking stack
  42. 42. Allocating newa stack chunkABD ECFGMarking stackXACBFGXmarkX X X X DStack chunkE Allocate!
  43. 43. Pros and Cons➔Pros– Good-bye complex fail-safe systems– Good-bye SEGV!➔Cons– Fast enough?– There is a risk of allocating a stackchunk during GC
  44. 44. mark benchmark OPTS="-r 5"
  45. 45. bm_gc_deep.rb depth=5000246810121416originnon-recursive(sec)
  46. 46. In fact, Ruby 1.9.3has backported thispatch :-)
  47. 47. You can buy a GC book atRubyKaigi!!
  48. 48. BitmapMarking
  49. 49. Bitmap Marking in CRuby➔Mark-bits separate from objectheaders– for CoW friendly➔REE has adopted this approach– Since 2008– But we cant import this patch
  50. 50. Whats CopyOnWrite?(Unix)Process 1(P1)Page tableMemory Spacefork()Process 2(P2)Page tableAt first, P1 and P2 usesame memory space.
  51. 51. Whats CopyOnWrite?(Unix)Process 1(P1)Page tableMemory Spacefork()Process 2(P2)Page tablewriteP1 private use P2 private usecopy
  52. 52. If we have many forked processesProcess 1SharedProcess 2P1 P2Process 3 Process 4 ・・・copyP3 P4write・・・Increase memory usage of all forked processes
  53. 53. Marking in the old way… 16KB …Object… 16KB …Object・・・mb mb mb mb mb mb mbRuby HeapHeapBlock 1(HB)HeapBlock 2
  54. 54. GC.start… 16KB …Object… 16KB …Object・・・Ruby Heapmb mb mb mb mb mb mbwrite write write writeHeapBlock 1(HB)HeapBlock 2
  55. 55. This Marking isCoW not friendly!!Memory SpaceHB1 HB2 HB3Process 1 Process 2GC.start!!write write writecopyHB2HB1 HB3
  56. 56. Bitmap MarkingMark-bits are separated from the heap… 16KB …Object… 16KB …Object・・・mb mb mb mb mb mb mbRuby HeapHeapBlock 1HeapBlock 2Bitmapheaderheader
  57. 57. This Marking isCoW friendly!!Memory SpaceHB1 HB2 HB3Process 1 Process 2GC.start!!writecopyBMBitmap Bitmapdecrease!!
  58. 58. BitmapMarkingmakes prefork serverhappy!
  59. 59. e.g. Unicornw/ marking in the old wayMemory SpaceHB1 HB2UP1(parent) UP2(child)GC.start!!read onlywritecopy・・・Rails Rails appread/writeappwrite writeRails Rails
  60. 60. e.g. Unicornw/ BitmapMarkingMemory SpaceHB1 HB2UP1(parent) UP2(child)GC.start!!read onlywritecopy・・・Rails Rails appread/writeappwriteRailsBitmap Bitmap
  61. 61. How do you find anappropriate bit inBitmap?
  62. 62. Finding an appropriatebit for an object… 16KB …HB 1 markBitmapHeader16KB align(low 13 bits must be 0)Allocate a heap block using memory align& ~0x3fffHB1mark…
  63. 63. How do you allocatealigned memory?
  64. 64. Allocating aligned memory➔Using posix_memalign()– For Unix-like OS➔Using _aligned_malloc()– For Windows OS– mingw: __mingw_aligned_malloc()
  65. 65. Allocating aligned memory➔Using malloc()● Thanks to yugui-sans help!– For other environments– For instance, Max OS X Lion and so on– It allocates 32KB and returns an addresswhich is a multiple of 16KB● 16KB memory space is wasted● We should use mmap(), but ....
  66. 66. The structure ofRuby Heap waschanged.
  67. 67. The structure of Heap in Ruby 1.8ObjectheapsObjectheap block
  68. 68. ObjectObjectheap blockheaderheaderslot・・・・・・The structure of Heap in Ruby 2.0heapsslotfreelistfreelistEach slot has a freelist
  69. 69. Benchmark
  70. 70. skkzipcode memory private memory050100150200250originbmap(MB)
  71. 71. You can buy a GC book atRubyKaigi!!
  72. 72. Future
  73. 73. Other plans➔Introduce new obj_(alloc/free)events to TracePont.➔mmap()/munmap()
  74. 74. rgengcko1-san deserves praise!
  75. 75. Conclusion
  76. 76. Conclusion➔I implemented Non-recursiveMarking and Bitmap Marking.➔Rgengc is so cooooool!
  77. 77. Thank you!