Memory management
tuning in Ruby
Koichi Sasada<ko1@heroku.com>

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

1Summary of this talk• Introduction of new versions• Ruby 2.1 (2.1.1 was released)• Ruby 2.2 (currently working on)• Basic of Ruby’s memory management (GC)• GC tuning parameters• “What” and “How” we can tune by GC parameters

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

2Who am I ?
• Koichi Sasada a.k.a. ko1• From Japan• 笹田 (family name) 耕一 (given name) in Kanji character• “Ichi” (Kanji character “一”) means “1” or first• This naming rule represents I’m the first son of my parents• Ko”ichi” → ko1

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

3Who am I ?
• CRuby/MRI committer• Virtual machine (YARV) from Ruby 1.9• YARV development since 2004/1/1• Recently, improving GC performance• Matz team at Heroku, Inc.
• Full-time CRuby developer• Working in Japan• Director of Ruby Association
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

4Advertisement• Foundation to encourage Ruby developments andcommunities• Chairman is Matz
• Located at Matsue-city, Shimane, Japan• Activities• Maintenance of Ruby (Cruby) interpreter• Now, it is for Ruby 1.9.3• Ruby 2.0.0 in the future?

• Events, especially RubyWorld Conference• Ruby Prize• Grant project. We have selected 3 proposals in 2013
• Win32Utils Support, Conductor, Smalruby - smalruby-editor• We will make this grant 2014!!

• Donation for Ruby developments and communities
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

5Advertisement• Heroku, Inc. http://www.heroku.com
You should know about Heroku!!
• Heroku supports Ruby development• Many talents for Ruby, and also other languages• Heroku employs 3 Ruby interpreter core developers• Matz• Nobu• Ko1 (me)• We name our group “Matz team”

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

This talk isalso sponsoredby Heroku!
6

“Matz team” in Heroku
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

7

Matz team in Heroku
in JapanNobu @ Tochigi
Patch monster

Matz @ Shimane
Title collector

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

ko1 @ Tokyo8
EDD developer

Matz team at Heroku
HierarchyMatz @ Shimane
Title collector[Not stupid boss]

ko1 @ Tokyo
EDD developer

Communication
with Skype

Nobu @ Tochigi
Patch monster

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

9

Matz
Title collector• He has so many (job) title• Chairman - Ruby Association• Fellow - NaCl
• Chief architect, Ruby - Heroku• Research institute fellow – Rakuten• Chairman – NPO mruby Forum• Senior researcher – Kadokawa Ascii Research Lab• Visiting professor – Shimane University• Honorable citizen (living) – Matsue city
• Honorable member – Nihon Ruby no Kai• …

• This margin is too narrow to contain
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

10Message from Matz
“I am awfully sorry
for not being here.
But I love you.
Maybe next time!”

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

11

Nobu
Patch monster• Great patch creator

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

12

Nobu
Patch monster
COMMITRATIOIN LAST 5 YEARS
davidflanagan
technorama
a_matsuda
iwamatsu
murakenheadiusgotoken
okkez
eban
evan
kanemoto
tmm1
seki
arton
hsbt
jeg2
luislavena
takano32
duerst
kouji
suke
keiju
azav
wanabengoto
eregonnagai
xibbarshirosaki
charliesome
ryan
sorah
tarui
ayumin
nahi
ktsj
glass
nari
shyouheiemboss
mrkn
0%
0%
0%
0%
0%
0%
0%
0%
0%
0%
0%
0%
kou
0%
0%
0%
0%
yugui
0%
0%
nagachika
0%
1%
1%
shugo
1%
1%
knu
1%
nobu
1%
tadf
1%
29%
mame
2%
marcandre
2%
matz
2%
tenderlove
2%
zzak
2%
kazu
2%
2%
kosaki3%drbrain

3%

ko1
4%usa
naruse
4% 8%

svn
9%

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

akr
12%

13

Ko1
EDD developer
EurukoCommit number of ko1 (last 3 years)
2013
RubyKaigi
2013
RubyConf
RubyConf
2012
2013

25

20

15

Ruby 2.0
105

EDD: Event Driven Development
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

2013/11/8

2013/9/8

2013/7/8

2013/5/8

2013/3/8

2013/1/8

2012/11/8

2012/9/8

2012/7/8

2012/5/8

2012/3/8

2012/1/8

2011/11/8

2011/9/8

2011/7/8

2011/5/8

2011/3/8

2011/1/8

2010/11/8

0

14

Mission of Matz team
• Improve quality of next version of CRuby• Matz decides a spec finally• Nobu fixed huge number of bugs
• Ko1 improves the performance

Current target is Ruby 2.2!!
Now, Ruby 2.1 is old version for us.
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

15

Ruby 2.1
Current stable
http://www.flickr.com/photos/loginesta/5266114104

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

16

Ruby 2.1
• Ruby 2.1.0 was released at 2013/12/25• New features• Performance improvements• Ruby 2.1.1 was released at 2014/02/24• Includes many bug fixes found after 2.1.0 release• Introduce a new GC tuning parameter to change
generational GC behavior (introduce it later)

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

17Ruby 2.1 the biggest change
Version policy• Change the versioning policy• Drop “patch level” in the version• Teeny represents patch level• Release new teeny versions about every 3 month• Teeny upgrades keep compatibility• Minor upgrades can break backward compatibility• We make an effort to keep compatibility(recently. Remember Ruby 1.9 )

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

18

Ruby 2.1 New syntax• New syntaxes• Required keyword
parameter• Rational number literal• Complex number literal• `def’ returns symbol ofmethod namehttp://www.flickr.com/photos/rooreynolds/4133549889

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

19

Ruby 2.1 Syntax
Required keyword parameter• Keyword argument (from Ruby 2.0.0)• def foo(a: 1, b: 2); end• `a’ and `b’ are optional parameters• OK: foo(); foo(a: 1); foo(a: 1, b: 2); foo(b: 2)• Required keyword argument from 2.1• def foo(a: 1, b: )• `a’ is optional, but `b’ is required parameter• OK: foo(a: 1, b: 2); foo(b: 2)• NG: foo(); foo(a: 1)

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

20Ruby 2.1 Syntax
Rational number literals• To represent ½, in Ruby “Rational(1, 2)”→ Too long!!
• Introduce “r” suffix½ → 1/2r• “[digits]r” represents “Rational([digits], 1)”• ½ → 1/2r
• 1/2r#=> 1/Rational(2, 1)• 1/Rational(2, 1) #=> Rational(1/2)
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

21

Ruby 2.1 Syntax
Complex number literals• We already have “Integer#i” method to makeimaginary number like “1+2.i”• We already introduced “r” suffix for Rational→ No reason to prohibit “i” suffix!!
• [digits]i represents “Complex(0, [digits])”• 1+2i #=> 1+Complex(0, 2)• 1+Complex(0, 2) #=> Complex(1, 2)• You can mix “r” and “i” suffix
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

22

Ruby 2.1 Syntax
Return value of `def’ syntax• Return value of method definition• Method definition syntax returns symbol ofdefined method name• `def foo; …; end’ #=> :foo

• Method modifier methods• Example:• private def foo; …; end• public static void def main(args); …; end

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

23

Ruby 2.1 Runtime new features• String#scrub• Process.clock_gettime• Binding#local_variable_get/set• Bignum now uses GMP (if available)• Extending ObjectSpace

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

24

Ruby 2.1 Runtime new features
Object tracing• ObjectSpace. trace_object_allocations• Trace object allocation and record allocation-site• Record filename, line number, creator method’s id and class• Usage:
ObjectSpace.trace_object_allocations{ # record only in the blocko = Object.new
file = ObjectSpace.allocation_sourcefile(o) #=> __FILE__
line = ObjectSpace.allocation_sourceline(o) #=> __LINE__ -2}

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

25Performance improvements• Optimize “string literal”.freeze• Sophisticated inline method cache• Introducing Generational GC: RGenGC

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

26

RGenGC: Generational GC for Ruby
• RGenGC: Restricted Generational GC• Generational GC (minor/major GC uses M&S)
• Dramatically speedup for GC-bottleneck applications• New generational GC algorithm allows mixing “Writebarrier protected objects” and “WB unprotected objects”→ No (mostly) compatibility issue with C-exts• Inserting WBs gradually• We can concentrate WB insertion efforts for major objects
and major methods• Now, most of objects (such as Array, Hash, String, etc.) are
WB protected• Array, Hash, Object, String objects are very popular in Ruby
• Array objects using RARRAY_PTR() change to WB unprotected
objects (called as Shady objects), so existing codes still works.
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

27

Accumulated execution time (sec)

RGenGC
Performance evaluation (RDoc)
14
12
10
8
6

About x15 speedup!

4
20
Total mark time (ms)w/o RGenGC

Total sweep time (sec)
RGenGC* Disabled lazy sweep to measure correctly.

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

28

RGenGC
Performance evaluation (RDoc)
Total execution time (sec)

140
120

16.04393815
4.946003494

100
80
60
40

103.7627479

102.3799865

w/o RGenGC

RGenGC20

0other than GC

GC* 12% improvements compare with w/ and w/o RGenGC* Disabled lazy sweep to measure correctly.

29

Ruby 2.2
Next version
http://www.flickr.com/photos/adafruit/8483990604

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

30

Schedule of Ruby 2.2• Not published officially• Schedule draft is available by Naruse-san• https://bugs.ruby-lang.org/projects/rubytrunk/wiki/ReleaseEngineering22

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

31

Ruby 2.2 schedule
2013/12Ruby 2.1.0

Rubyconf.PH
3/28, 29

2014/12/25

We arehere!

Ruby 2.2.0

RDRC
6/26, 27
Rubyconf.tw
4/25, 26

RubyKaigi
9/18, 19, 20

RubyConf
11/17, 18, 19

Events are important for
EDD (Event Driven Development) Developers
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

32

Ruby 2.2 (rough) schedule
2013/12Ruby 2.1.0

We arehere!

2014/12/25
Ruby 2.2.0

Sep/2014
Preview 1
Big feature freeze

Bug fix only

Nov/2014
Preview2
Feature freeze

Critical Bug fix only
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

Dec/2014
Releasecandidate33

2.2 big features (planned)• New syntax: not available now• New method: not available now• Internal• GC• Symbol GC (merged recently)• 2age promotion strategy for RGenGC• Incremental GC to reduce major GC pause time

• VM
• More sophisticated method cache
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

34

Symbol GC• Symbols remain forever → Security issue• “n.times{|i| i.to_s.to_sym}”
creates “n” symbols and they are never collected• Symbol GC: Collect dynamically created symbols

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

35

Garbage collection
The automatic memory management

http://www.flickr.com/photos/circasassy/6817999189/

Today’s main subject
From basic to advanced topics

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

36

Automatic memory management
Basic concept• “Object.new” allocate a new object• “foo” (string literal) also allocate a new object• Everything are objects in Ruby!

• We don’t need to “de-allocate” objects manually

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

37

Automatic memory management
Basic concept• Garbage collector recycled “unused” objects
automaticallyMemory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>38

st
1 question

How to collect“unused” objects?

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

39

How to collect “unused” objects?
• Using (well-known) GC algorithm• Mark and sweep algorithm (from the first version of Ruby)• Generational GC algorithm (from Ruby 2.1)

http://www.flickr.com/photos/mirsasha/5644819639/
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

40

Mark & Sweep algorithm
Root objects
traverse
freemarkedtraverse

traverse

markedtraverse

markedmarkedtraversefree

1. Mark reachable
objects from rootobjects
2. Sweep unmarked
objects (collection
and de-allocation)

Collect unreachable
objects

markedfree
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

41

Generational GC (GenGC)• Weak generational hypothesis:“Most objects die young”

http://www.flickr.com/photos/ell-r-brown/5026593710→ Concentrate reclamation effort
only on the young objects
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

42

Generational hypothesis
Object lifetime in RDoc
(How many GCs surviving?)

Percentage of dead object#

100
90

95% of objects dead by the first GC

80

70
60
50
40
30
20
10
0
0

3

6

9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102

Lifetime (Survibing GC count)
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

43

Generational hypothesis
Percentage of dead object#

Object lifetime in RDoc
(How many GCs survive?)
100
90

Some type of objects (like Class)has long lifetime

80
70
60
50
40
30
20
10
0
0

3

6

9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102

Lifetime (Survibing GC count)
T_OBJECT

T_CLASS

T_MODULE

T_STRING

T_REGEXP

T_ARRAY

T_HASH

T_STRUCT

T_BIGNUM

T_FILE

T_DATA

T_MATCH

T_NODE

T_ICLASS

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

44

Generational GC (GenGC)• Separate young generation and old generation• Create objects as young generation• Promote to old generation after surviving n-th GC• In CRuby, n == 1 (after 1 GC, objects become old)

• Usually, GC on young space (minor GC)• GC on both spaces if no memory (major/full GC)

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

45

Generational GC (GenGC)• Minor GC and Major GC can use different GC
algorithm• Popular combination is:
Minor GC: Copy GC, Major GC: M&S• On the CRuby, we choose:
Minor GC: M&S, Major GC: M&S• Because of CRuby’s restriction (we can’t use moving
algorithm)

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

46

GenGC [Minor M&S GC] (1/2)
1st MinorGC• Mark reachable objects fromroot objects.

Root objects• Mark and promote to oldgeneration• Stop traversing after old
objects

traverse

new/
free

new
old
traverse

traversenew/freecollectnewoldtraverse
new
old

new
old
traverse
newold→ Reduce mark overhead• Sweep not (marked or old)
objects• Can’t collect Some
unreachable objects
Don’t collect old object
•
old/
free

even if it is unreachable.

47

GenGC [Minor M&S GC] (2/2)
2nd MinorGC• Mark reachable objects fromroot objects.

Root objects
traverse

new/
free

old
ignoreignorenew/freecollectoldignoreold

oldignoreold• Mark and promote to oldgeneration• Stop traversing after old
objects→ Reduce mark overhead• Sweep not (marked or old)
objects• Can’t collect Some
unreachable objects
Don’t collect old object•
Memory management tuning in Ruby,
old/
free

even if itRubyConfPH
is unreachable.
2014 by K.Sasada<ko1@heroku.com>

48

GenGC [Major M&S GC]• Normal M&S• Mark reachable objects fromroot objects

Root objects
traverse

new/
free

new
traverse

traverse

new/
free

• Mark and promote to old gen• Sweep unmarked objects

collectoldtraverse

oldnew• Sweep all unreachable(unused) objects

traverse
old

old/
free
collect
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

49

NOTE: Generational GC details• Skip details of generational GC• Remember set• Write barrier• RGenGC techniques• See my previous slides for details• http://www.atdot.net/~ko1/activities/#idx4

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>50

nd
2 question“When”
should we collect objects?

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

51

“When” collect objects?
1. Object space is full
2. Exceed limit of Malloc’ed memory size
3. User specified timing (GC.start, etc)
• (1) and (3) is easy to understand• (2) needs more explanation

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

52

Exceed limit of Malloc’ed memory size
• When many memories are allocated by “malloc()”• Introduce two variables• a counter “malloc_increase”• a threshold value “malloc_limit” (16MB)• Rule• (1) Increase “malloc_increase” by malloc’ed size
• (2) “malloc_increase” is reset at every GC time
→ “malloc_increase” represents “how many memory
allocated (by malloc()) without GC”• If “malloc_increase” > “malloc_limit”, then invoke GC
to recycle malloc’ed objects
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

53

Exceed limit of Malloc’ed memory size
Invoke GC
35

30

25

20

15

10

5

0
1

4

7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 67 70 73 76 79 82 85 88 91 94 97 100 103 106 109 112 115 118
increase(2.1)

limit(2.1)

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>54

rd
3 question“What happen”
when no space after GC?

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

55

What happen when no space
after GC?
• Terminology• Total slots: total prepared object places• Living objects: Used objects• GC detects “No Space” just after sweeping
if [# of Total slots] * 0.7 < [# of Living objects]• Allocate new space expand current space x1.8
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

56

What happen when no space
after GC?
# of total slots

x1.8# of living objects (after sweeping)
Exceeds
0.7 * [# of total slots]time
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

57

Trade-off
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

58

Speed-Memory Trade-off
Performance V.S. Memory usage• Many GCs slow application
performance• Few GC increase memory
consumption

http://www.flickr.com/photos/mcerasoli/6484117955/
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

59Speed-Memory Trade-off• Usually no problem• On big production application, this can be an issue

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

60Speed-Memory Trade-off• Solution 1: Use big memory machine

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

61Speed-Memory Trade-off• Solution 1: Use big memory machine• Recent price of memory is very cheep• Heroku provides “PX: Performance dyno” (6GB)
Advertisement

https://blog.heroku.com/archives/2014/2/3/heroku-xl
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

62Speed-Memory Trade-off• Solution 2: Find out good points• Choose good “GC tuning parameters”

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

63

GC tuning parameters
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

64

GC tuning parameters• There are several GC tuning parameters• Specified by environment variables• Use like that: $ RUBY_GC_INIT_SLOTS=10000 ruby script.rb• Affect only launched time

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

65

GC tuning parameters• How many GC parameters now?
• Please raise your hand if you think it is:

①3
②7
③ 10
④ 11
⑤ 13
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

66

GC tuning parameters• How many GC parameters now?
• Please raise your hand if you think it is:① 3 (ruby 1.9)
②7
③ 10 (ruby 2.1.0)④ 11 (ruby 2.1.1) ← Now!!
⑤ 13
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

67

GC tuning parameters (Ruby 2.1.1)
1. RUBY_GC_HEAP_INIT_SLOTS
2. RUBY_GC_HEAP_FREE_SLOTS
3. RUBY_GC_HEAP_GROWTH_FACTOR (new from 2.1)
4. RUBY_GC_HEAP_GROWTH_MAX_SLOTS (new from 2.1)
5. RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR (new from 2.1.1)
6. RUBY_GC_MALLOC_LIMIT
7. RUBY_GC_MALLOC_LIMIT_MAX (new from 2.1)
8. RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR (new from 2.1)
9. RUBY_GC_OLDMALLOC_LIMIT (new from 2.1)
10. RUBY_GC_OLDMALLOC_LIMIT_MAX (new from 2.1)
11. RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR (new from 2.1)
• Obsolete• RUBY_FREE_MIN-> RUBY_GC_HEAP_FREE_SLOTS (from 2.1)
• RUBY_HEAP_MIN_SLOTS -> RUBY_GC_HEAP_INIT_SLOTS (from 2.1)
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

68GC_HEAP_INIT/FREE_SLOTS• RUBY_GC_HEAP_INIT_SLOTS (default: 10000)• How many slots prepared at initialize• RUBY_GC_HEAP_FREE_SLOTS (default: 4096)• At least how many slots are available after GC• free_min = max(RUBY_GC_HEAP_FREE_SLOTS , total_slots * 0.3)
x1.8

# of total slots

RUBY_GC_HEAP_INIT_SLOTS
free_min# of living objects

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

time
69

RUBY_GC_HEAP_GROWTH_FACTOR (new from 2.1)
• RUBY_GC_HEAP_GROWTH_FACTOR (default: 1.8)
• Growth factor of expanding object space• Grow object space exponentially to reduce GC time
# of total slots
total_slots =total_slots * RUBY_GC_HEAP_GROWTH_FACTOR

free_min# of living objects

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

time
70

GC_HEAP_GROWTH_MAX_SLOTS (new from Ruby 2.1)

• GC_HEAP_GROWTH_MAX_SLOTS (default: 0)• Stop exponential expanding, start linear expanding• The value “0” remove this cap# of total slots
y=x*C
GC_HEAP_GROWTH_MAX_SLOTS
y=x1.8

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

time
71

RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR (from Ruby 2.1.1)• RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR• Default value: 2.0• Tuning major (full) GC frequency• Bigger value: rare, Smaller value: frequent• < 1.0: Every GC will be major (full) GC
Invoke major GC

OLDOBJECT_LIMIT

when OLDOBJECT_LIMIT < [# of old objects]

OLDOBJECT_LIMIT =[# of old objects] * RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR# of old objects

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

time
72

RUBY_GC_MALLOC_LIMIT(…)• RUBY_GC_MALLOC_LIMIT (default: 16MB)• Initial value of “malloc_limt”• Tuning GC frequency• Bigger: rare → High throughput, but consumes memory• Smaller: frequent → Low throughput, small memory• RUBY_GC_MALLOC_LIMIT_MAX (default: 32MB)• Maximum value of “malloc_limit”• RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR(default: 1.4)
• Growth ratio of “malloc_limit”
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

73

RUBY_GC_MALLOC_LIMIT(…)
RUBY_GC_MALLOC_LIMIT_MAX (= 32MB)

35

30

25

malloc_limit = malloc_limit *RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR (= 1.4)
20

15

10

5

increase(2.1)

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

117

113

109

105

97

101

93

89

85

81

77

73

69

65

61

57

53

49

45

41

37

33

29

25

21

17

9

13

5

0

1

RUBY_GC_MALLOC_LIMIT(= 16MB)

limit(2.1)

74

RUBY_GC_OLDMALLOC_LIMIT(…)• RUBY_GC_OLDMALLOC_LIMIT (default: 16MB)• RUBY_GC_OLDMALLOC_LIMIT_MAX (default: 128MB)• RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR (default: 1.2)
• Similar to RUBY_GC_MALLOC_LIMIT(…), but parameter for major (full)GC timing

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>75

th
4 question

How to use tuning
parameters?

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

76How to use tuning parameters?
1. Profile your application
2. Try GC parameters (environment variables)

http://www.flickr.com/photos/nasa_goddard/5188180370
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

77

Profile memory management
GC.stat (MRI specific)• “GC.stat” returns statistics information about GC• Counts• :count=>2,• :minor_gc_count=>2,• :major_gc_count=>0,# GC count# minor GC count# major GC count• Current slot information• :heap_live_slot=>6836, #=> # of live objects• :heap_free_slot=>519, #=> # of freed objects• :heap_final_slot=>0, #=> # of waiting finalizer objects• total_slots = heap_live_slot + heap_free_slot + heap_final_slot• Statistics• :total_allocated_object=>7674,• :total_freed_object=>838,# total allocated objects# total freed objects• Current living objects = total_allocated_object - total_freed_object
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

78

Profile memory management
GC.latest_gc_info (MRI specific)• “GC.latest_gc_info” returns details of latest GC• :gc_by=>:newobj# why GC invoked?

• newobj: no slots available• malloc: malloc_increase > malloc_limit• :major_by=>nil• :have_finalizer=>false• :immediate_sweep=>false# why major GC invoked?
# have finalizer?
# immediate sweep?

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

79

Profile memory management“gc_tracer” gem (MRI 2.1.0 later!!)• GC::Tracer.start_logging(filename)• Save all GC.stat/GC.latest_gc_info results at every GC events
into specified file
• GC events:• Start• End marking• End sweeping
GC startMark

GC end sweeping
Sweep

Sweep

GC startMark

GC end marking
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

GC end sweeping
Sweep

Sweep

GC end marking

80Profile memory management“gc_tracer” gem• Run your application with gc_tracer• Plot with Excel!

http://www.flickr.com/photos/microsoftsweden/5394685465
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

81

120
100
80
60
40
20
0

1
7
13
19
25
31
37
43
49
55
61
67
73
79
85
91
97
103
109
115
121
127
133
139
145
151
157
163
169
175
181
187
193
199
205
211
217
223
229
235
241
247
253
259
265
271
277

Profile memory management“gc_tracer” gemminor_gc_countmajor_gc_countMemory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

82

Profile memory management“gc_tracer” gem
40,000,000

35,000,000

30,000,000

25,000,000

20,000,000

15,000,000

10,000,000

5,000,000

1
7
13
19
25
31
37
43
49
55
61
67
73
79
85
91
97
103
109
115
121
127
133
139
145
151
157
163
169
175
181
187
193
199
205
211
217
223
229
235
241
247
253
259
265
271
277

0

total_allocated_object

total_freed_object

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

83Profile memory management“gc_tracer” gem
1,000,000
900,000
800,000
700,000
600,000
500,000
400,000
300,000
200,000
100,000

1
7
13
19
25
31
37
43
49
55
61
67
73
79
85
91
97
103
109
115
121
127
133
139
145
151
157
163
169
175
181
187
193
199
205
211
217
223
229
235
241
247
253
259
265
271
277

0

total_slots

heap_swept_slot

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

84

Profile memory management“gc_tracer” gemruby 2.2 dev/RUBY_GC_HEAP_OLDOBJECT_FACTOR=2.0 (default)
1600000
1400000
1200000
1000000
800000600000400000200000

1
7
13
19
25
31
37
43
49
55
61
67
73
79
85
91
97
103
109
115
121
127
133
139
145
151
157
163
169
175
181
187
193
199
205
211
217
223
229
235
241
247
253
259
265

0

total_slots

old_object

old_object_limit

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

85

Profile memory management“gc_tracer” gem
Ruby 2.2dev w/ RUBY_GC_HEAP_OLDOBJECT_FACTOR=1.3
1000000
900000800000700000600000500000400000300000200000100000

1
7
13
19
25
31
37
43
49
55
61
67
73
79
85
91
97
103
109
115
121
127
133
139
145
151
157
163
169
175
181
187
193
199
205
211
217
223
229
235
241
247
253
259
265
271
277

0

total_slots

old_object

old_object_limit

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

86Try GC parameters• General concept

Speed <-> Memory trade-off• You have huge memory→ Increase parameters to improve performance• RUBY_GC_HEAP_INIT_SLOTS (initial slots)• RUBY_GC_HEAP_FREE_SLOTS (prepared free slots after GC)• RUBY_GC_MALLOC_LIMIT (reduce GC frequency)
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

87Try GC parameters• You have small memory
Reduce parameters to reduce memory usage• IaaS, PaaS environments (ex: Heroku 1X dyno (512MB))• RUBY_GC_HEAP_GROWTH_FACTOR (heap expanding factor)• RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR (for more full GC)• If you have memory usage trouble when migrating from 2.0 to
2.1, please try to reduce this variable
Advertisement

Or you can try
Heroku 2X dyno (1GB) / PX dyno (6GB)!!
Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

88Try GC parameters• There is no silver bullet• No one answer for all applications• You should not believe other applications settings easily• Try and try and try!

http://www.flickr.com/photos/rowanbank/8483526808

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

89See also• Excellent blog articles by @tmm1• http://tmm1.net/• Demystifying the Ruby GC by Sam Saffron• http://samsaffron.com/archive/2013/11/22/demystifying-the-ruby-gc• Why I am excited about Ruby 2.1? by Sam Saffron• https://speakerdeck.com/samsaffron/why-ruby-2-dot-1excites-me• http://vimeo.com/89491942

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

90Summary of this talk
• New versions• Ruby 2.1 (released)• Ruby 2.2 (currently working on)• Basic of Ruby’s memory management (GC)• GC tuning parameters• “What” and “How” we can tune by GC parameters

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

91Thank you for your attention
Q&A?
Koichi Sasada<ko1@heroku.com>

Memory management tuning in Ruby,
RubyConfPH 2014 by K.Sasada<ko1@heroku.com>

92