Object lifetime analysis with Ruby 2atdot.net/~ko1/activities/2014_rubyconf_tw_pub.pdfObject...

Post on 21-May-2020

7 views 0 download

Transcript of Object lifetime analysis with Ruby 2atdot.net/~ko1/activities/2014_rubyconf_tw_pub.pdfObject...

Object lifetime analysis with Ruby 2.1

Koichi Sasada<ko1@heroku.inc>

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

1

Who am I ?

• Koichi Sasada a.k.a. ko1

• From Japan

• 笹田 (family name) 耕一 (given name) in Kanji character

2Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.

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

3Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.

• Foundation to encourage Ruby dev. and communities• Chairman is Matz, Located at Matsue-city, Shimane, Japan

• Activities• Ruby programmer certification program

• http://www.ruby.or.jp/en/certification/examination/ in English

• 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

Advertisement

4Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.

• Heroku, Inc. http://www.heroku.com

You should know about Heroku!!

Advertisement

5Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.

This presentation is supported by

6Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.

Advertisement

• Heroku, Inc. http://www.heroku.com

• Heroku supports OSSs / 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”

Advertisement

7Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.

Matz team in Herokuin Japan

8

Matz @ ShimaneTitle collector

Nobu @ TochigiPatch monster

ko1 @ TokyoEDD developer

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

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.

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

9

Ruby 2.1Current stable

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

10

http://www.flickr.com/photos/loginesta/5266114104

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)

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

11

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 )

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

12

Ruby 2.1 New syntax

•New syntaxes• Required keyword

parameter• Rational number literal• Complex number literal• `def’ returns symbol of

method name

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

13

http://www.flickr.com/photos/rooreynolds/4133549889

Ruby 2.1 Runtime new features

• String#scrub

• Process.clock_gettime

• Binding#local_variable_get/set

• Bignum now uses GMP (if available)

• Extending ObjectSpace

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

14

Performance improvements

• Optimize “string literal”.freeze

• Sophisticated inline method cache

• Introducing Generational GC: RGenGC

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

15

0

2

4

6

8

10

12

14

Total mark time (ms) Total sweep time (sec)

Acc

um

ula

ted

exe

cuti

on

tim

e (

sec)

w/o RGenGC RGenGC

RGenGCPerformance evaluation (RDoc)

16

About x15 speedup!

* Disabled lazy sweep to measure correctly.Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.

RGenGCPerformance evaluation (RDoc)

17

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

103.7627479 102.3799865

16.043938154.946003494

0

20

40

60

80

100

120

140

w/o RGenGC RGenGC

Tota

l exe

cuti

on

tim

e (s

ec)

other than GC GC

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

Ruby 2.2Next version

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

18

http://www.flickr.com/photos/adafruit/8483990604

Schedule of Ruby 2.2

• Not published officially

• Schedule draft is available by Naruse-san• https://bugs.ruby-lang.org/projects/ruby-

trunk/wiki/ReleaseEngineering22

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

19

Ruby 2.2 schedule

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

20

2014/12/25Ruby 2.2.0

RubyKaigi9/18, 19, 20

RubyConf11/17, 18, 19Rubyconf.tw

4/25, 26

Rubyconf.PH3/28, 29

We are here!2013/12

Ruby 2.1.0

RDRC6/26, 27

Events are important forEDD (Event Driven Development) Developers

Ruby 2.2 (rough) schedule

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

21

2014/12/25Ruby 2.2.0

2013/12Ruby 2.1.0

Sep/2014Preview 1

Big feature freeze

Nov/2014Preview2

Feature freeze

Dec/2014Release

candidate

Bug fix only

Critical Bug fix only

We are here!

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

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

22

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

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

23

Object lifetime

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

24

Ruby’s object/memory management• “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

Why we don’t need to clean up objects?

Memory management tuning in Ruby, RubyConfPH 2014 by K.Sasada

<ko1@heroku.com>25

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

Garbage collectionThe automatic memory management

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

26

Garbage collectionThe automatic memory management

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

27

Garbage collectionThe automatic memory management

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

28

Object lifetime

• Human’s lifetime

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

29

Birth DeathLifetime

Birth Death

Object lifetime

# Object creationobj = Object.new

# Collected by GC# when nobody refers it

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

30

Birth Death

Object lifetime

GC surviving count→ Age

GC GC GC

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

31

Age at the dying→ Lifetime

Why lifetime is important?

• Old objects slow down major (full) GC• RGenGC have reduced GC overhead comes from

old objects• However, major (full) GC needs a time

• Long life (old) objects can be unexpected memory leak

Reducing old objects makesRuby program faster

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

32

Questions

•How to measure object lifetime?

•How to find old objects?

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

33

Allocation tracer gem

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

34

Allocation tracer

•Trace object allocations• Two features

1. Show statistics data by line2. Show lifetime statistics table

• Using newobj/freeobj internal hooks introduced from Ruby 2.1.0.

• So that this gem only supports Ruby 2.1 and later

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

35

Allocation Tracer(1) Show statistics data by line• Show statistics data by each lines

• Collect following data• Allocation count

• Old object count

• Total object lifetime (average lifetime by dividing allocation count)

• Min/Max lifetime

• Total amount of memory usage (average memory usage by dividing allocation count)

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

36

Allocation Tracer(1) Show statistics data by lineDemo

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

37

Allocation Tracer(2) Object lifetime statistics• Show object lifetime statistics table for each type

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

38

Age 0 1 2 3 4 5 6 7 8 9 10T_OBJECT 7534 435532 6695 12916 2841 2298 2570 4222 3256 2659 4839

T_CLASS 0 90 1 0 0 0 0 0 4 5 1

T_STRING 116307 17706739 24244 97981 9461 5470 4825 7243 6533 5581 15826

T_REGEXP 0 41192 1 0 0 0 0 0 0 3 0

T_ARRAY 32874 4490228 5878 9262 4863 2567 2485 5697 3752 3033 5672

T_HASH 872 89158 113 323 90 85 93 138 161 101 183

T_STRUCT 1 8507 247 197 62 55 59 9 42 67 127

T_FILE 1 9330 5 2 1 1 0 0 0 0 0

T_DATA 8510 578913 146 69 96 53 77 54 65 90 62

T_MATCH 7 829992 52 0 0 0 0 0 0 0 0

T_RATIONAL

0 2 0 0 0 0 0 0 0 0 0

T_NODE 9333 649080 19438 4948 2665 7 17 5 9 26 135

T_ICLASS 0 90 1 0 0 0 0 0 0 1 1

T_MODULE

0 0 0 0 0 0 0 0 0 0 0

T_FLOAT 0 0 0 0 0 0 0 0 0 0 0

Allocation Tracer(2) Object lifetime statistics• Show object lifetime table for each type

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

39

0

2000000

4000000

6000000

8000000

10000000

12000000

14000000

16000000

18000000

20000000

1 5 9

13

17

21

25

29

33

37

41

45

49

53

57

61

65

69

73

77

81

85

89

93

97

10

1

10

5

10

9

11

3

11

7

12

1

12

5

12

9

13

3

13

7

14

1

14

5

14

9

15

3

15

7

16

1

16

5

16

9

17

3

17

7

18

1

18

5

18

9

Ob

ject

co

un

t

Object lifetime

T_OBJECT T_CLASS T_STRING T_REGEXP T_ARRAY T_HASH T_STRUCT T_FILE

T_DATA T_MATCH T_RATIONAL T_NODE T_ICLASS T_MODULE T_FLOAT

Allocation Tracer(2) Object lifetime statistics• Show object lifetime table for each type

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

40

0

0.2

0.4

0.6

0.8

1

1.2

1 5 9

13

17

21

25

29

33

37

41

45

49

53

57

61

65

69

73

77

81

85

89

93

97

10

1

10

5

10

9

11

3

11

7

12

1

12

5

12

9

13

3

13

7

14

1

14

5

14

9

15

3

15

7

16

1

16

5

16

9

17

3

17

7

18

1

18

5

18

9

Per

cen

tage

of

ob

ject

s

Object lifetime

Age/percentage

T_OBJECT T_CLASS T_STRING T_REGEXP T_ARRAY T_HASH T_STRUCT T_FILE

T_DATA T_MATCH T_RATIONAL T_NODE T_ICLASS T_MODULE T_FLOAT

Allocation Tracer(2) Object lifetime statistics

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

41

T_STRING69%

T_ARRAY18%

T_OBJECT4%

T_MATCH3%

T_NODE3%

T_DATA2%

T_HASH1%

T_REGEXP0%

T_STRUCT0%

T_FILE0%

T_CLASS0%

T_ICLASS0%

T_MODULE0%

T_FLOAT0%

T_RATIONAL0%

Most of allocated objects are String

Allocation Tracer demo(2) Object lifetime statistics

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

42

T_STRING

Most of String die at first GC

Allocation Tracer example

• Using “by line” statistics on RDoc program

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

43

Allocation Tracer example

path line counttotal_memsize

/home/ko1/src/ruby/trunk/lib/rdoc/markup/parser.rb

327 128,097 498,086,366

/home/ko1/src/ruby/trunk/lib/rdoc/parser/c.rb 644 3,132 111,437,037

/home/ko1/src/ruby/trunk/lib/time.rb 325 1,146,900 85,714,539

/home/ko1/src/ruby/trunk/lib/rdoc/token_stream.rb

59 1,267,168 81,137,600

/home/ko1/src/ruby/trunk/lib/rdoc/store.rb 892 23,038 65,504,272

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

44

lib/rdoc/markup/parser.rb:327

@input.byteslice(0, byte_offset).length

• @input is String

• @input.byteslice(0, byte_offset) makes new String

• Return only length of sliced string

→ Created string object is completely temporary

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

45

lib/rdoc/markup/parser.rb:327

Introduce String#byteslice_length

@input.byteslice_length(0, byte_offset)

• No temporary String object

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

46

After introducing new method…

path line count total_memsize/home/ko1/src/ruby/trunk/lib/rdoc/parser/c.rb

644 4,369 93,019,334

/home/ko1/src/ruby/trunk/lib/rdoc/token_stream.rb

59 1,386,966 88,834,304

/home/ko1/src/ruby/trunk/lib/time.rb

325 1,137,612 84,959,225

/home/ko1/src/ruby/trunk/lib/rdoc/ruby_lex.rb

162 944,833 60,724,300

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

47

And total consuming memory reduced fromabout 140MB to 120MB

Another GC tipGC Tracer

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

48

gc_tracer gem

• Helper gem to analyze GC behavior for tuning

http://www.flickr.com/photos/nasa_goddard/5188180370

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

49

How to use tuning parameters?

1. Profile your application

2. Try GC parameters (environment variables)

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

50

Profile memory managementGC.stat (MRI specific)• “GC.stat” returns statistics information about GC

• Counts• :count=>2, # GC count• :minor_gc_count=>2, # minor GC count• :major_gc_count=>0, # 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 allocated objects• :total_freed_object=>838, # total freed objects• Current living objects = total_allocated_object - total_freed_object

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

51

Profile memory managementGC.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 # why major GC invoked?

• :have_finalizer=>false # have finalizer?

• :immediate_sweep=>false # immediate sweep?

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

52

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

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

53

Sweep Sweep

GC start

GC end marking

GC end sweepingMark Sweep Sweep

GC start

GC end marking

GC end sweepingMark

Profile memory management“gc_tracer” gem• Run your application with gc_tracer

• Plot with Excel!

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

54

http://www.flickr.com/photos/microsoftsweden/5394685465

Profile memory management“gc_tracer” gem

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

55

0

20

40

60

80

100

120

1 7

13

19

25

31

37

43

49

55

61

67

73

79

85

91

97

10

3

10

9

11

5

12

1

12

7

13

3

13

9

14

5

15

1

15

7

16

3

16

9

17

5

18

1

18

7

19

3

19

9

20

5

21

1

21

7

22

3

22

9

23

5

24

1

24

7

25

3

25

9

26

5

27

1

27

7

minor_gc_count major_gc_count

Profile memory management“gc_tracer” gem

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

56

0

5,000,000

10,000,000

15,000,000

20,000,000

25,000,000

30,000,000

35,000,000

40,000,000

1 7

13

19

25

31

37

43

49

55

61

67

73

79

85

91

97

10

3

10

9

11

5

12

1

12

7

13

3

13

9

14

5

15

1

15

7

16

3

16

9

17

5

18

1

18

7

19

3

19

9

20

5

21

1

21

7

22

3

22

9

23

5

24

1

24

7

25

3

25

9

26

5

27

1

27

7

total_allocated_object total_freed_object

Profile memory management“gc_tracer” gem

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

57

0

100,000

200,000

300,000

400,000

500,000

600,000

700,000

800,000

900,000

1,000,000

1 7

13

19

25

31

37

43

49

55

61

67

73

79

85

91

97

10

3

10

9

11

5

12

1

12

7

13

3

13

9

14

5

15

1

15

7

16

3

16

9

17

5

18

1

18

7

19

3

19

9

20

5

21

1

21

7

22

3

22

9

23

5

24

1

24

7

25

3

25

9

26

5

27

1

27

7

total_slots heap_swept_slot

Profile memory management“gc_tracer” gem

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

58

0

200000

400000

600000

800000

1000000

1200000

1400000

1600000

1 7

13

19

25

31

37

43

49

55

61

67

73

79

85

91

97

10

3

10

9

11

5

12

1

12

7

13

3

13

9

14

5

15

1

15

7

16

3

16

9

17

5

18

1

18

7

19

3

19

9

20

5

21

1

21

7

22

3

22

9

23

5

24

1

24

7

25

3

25

9

26

5

ruby 2.2 dev/RUBY_GC_HEAP_OLDOBJECT_FACTOR=2.0 (default)

total_slots old_object old_object_limit

Profile memory management“gc_tracer” gem

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

59

0

100000

200000

300000

400000

500000

600000

700000

800000

900000

1000000

1 7

13

19

25

31

37

43

49

55

61

67

73

79

85

91

97

10

3

10

9

11

5

12

1

12

7

13

3

13

9

14

5

15

1

15

7

16

3

16

9

17

5

18

1

18

7

19

3

19

9

20

5

21

1

21

7

22

3

22

9

23

5

24

1

24

7

25

3

25

9

26

5

27

1

27

7

Ruby 2.2dev w/ RUBY_GC_HEAP_OLDOBJECT_FACTOR=1.3

total_slots old_object old_object_limit

For more information

Please refer my slide at RubyConf PH 2014

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

60

Summary of this talk

• Ruby 2.1 was released and 2.2 will be released this year

• Object lifetime analysis is important for program tuning

• Allocation Tracer gem helps how applications allocate objects

• Another GC Tips• GC Tracer gem helps GC behavior analysis for GC tuning

Object lifetime analysis with Ruby 2.1, RubyConf.tw 2014, K.Sasada from Heroku, Inc.

61

Thank you for your attentionQ&A?

Koichi Sasada<ko1@heroku.com>

62Object lifetime analysis with Ruby 2.1,

RubyConf.tw 2014, K.Sasada from Heroku, Inc.