ण໋ΦϒδΣΫτΛରͱͨ͠੩తղੳ
GC
ͷఏҊ
খ ࣨ
†Ѩ ෦ ެ ً
† {komuro,abe}@cacao.cs.uec.ac.jp ੈผ GC ΄ͱΜͲͷΦϒδΣΫτੜޙ·ͳ͘͝ΈͱͳΔण໋ΦϒδΣΫτͰ͋Δͱ͍ ͏ੑ࣭Λ༻͍ͯޮతʹ͝ΈΛճऩ͢Δ͕ɼण໋ΦϒδΣΫτͷผΛಈతʹߦ͏ͨΊॲཧ࣌ؒͷ ༧ଌ͕͍͠ɽຊݚڀͰʮण໋ΦϒδΣΫτͷଟ͘༗ޮൣғ͕੩తʹผՄೳͳΦϒδΣΫτ ͰΊΒΕΔͷͰͳ͍͔ʯͱͷ༧Λͨͯɼͦͷ͔֬͞Λݕূ͢Δɽͦͯ͠੩తղੳʹΑΓण໋ ΦϒδΣΫτͷผɾճऩΛޮྑ͘ߦ͏ख๏ΛఏҊ͢Δɽ༧ͷݕূΦϒδΣΫτࢦεΫϦϓ τݴޠͰ͋Δ Ruby ॲཧܥ MRI ʹͯߦ͏ɽRuby ۙ։ൃɾݚڀ༻్Ͱͷར༻͕·͍ͬͯΔ͕GCͷ࣮ະͩෆेͰ͋ΓɼఏҊख๏ʹΑΓੑೳ্͕ݟࠐΊΔɽ
Static Detection of Short-lived Objects for Effective GC
Sunao Komuro
†and Kouki Abe
†{komuro,abe}@cacao.cs.uec.ac.jp
Generational GC schemes effectively collect garbage objects utilizing the fact that most objects die young. However, the time required for the collection is unpredictable because the schemes detect the short-lived objects dynamically. In this paper, we put a hypothesis that most of the short-lived objects are those whose scopes can be statically detected, and we verify the hypothesis experimentally. We also propose a method which effectively collects the short-lived objects detected by the static analysis. The experimental verification is con-ducted using MRI, an interpreter of object-oriented scripting language Ruby. Ruby has been widely used for research and development purposes, but no effective implementation of GC is currently available. The proposed method is expected to improve the performance of Ruby interpreter.
1. ͡ Ί ʹ
ۙͰඞཁͱ͞ΕΔϓϩάϥϜͷڊେԽɾෳࡶԽ ʹͱͳ͍ϓϩάϥϜ։ൃʹ͔͔Δ͕࣌ؒ૿͓ͯ͠ ΓɼϓϩάϥϜ։ൃޮΛ্͛Δݚڀॏཁͳ՝ͱ ͳ͍ͬͯΔɽϓϩάϥϜ։ൃʹ͓͍ͯϝϞϦཧͷ ෳࡶ͕͞ϘτϧωοΫͷҰͭͰ͋Δɽಛʹಈతʹ֬อ ͨ͠ྖҬͷཧ͠͠μϯάϦϯάϙΠϯλɼϝ ϞϦϦʔΫͳͲόάͷݩͱͳΓ։ൃ࣌ؒΛංେԽ͞ ͤΔɽͦ͜Ͱಈతʹ֬อͨ͠ྖҬΛࣗಈతʹ։์͢Δ Garbage Collection(GC)͕͘༻͍ΒΕΔ1)ɽ ҰൠʹGCʹΑΓඞཁͳϝϞϦྖҬ૿Ճ͢Δɽ· ͨɼGCͷؒଞͷॲཧΛఀࢭ͢Δɽߋʹ͍ͭGC ͕ ൃੜ͢Δ͔༧Ͱ͖ͳ͍ͨΊϦΞϧλΠϜγεςϜʹ ΈࠐΉͷ͕͍͠ɽ͜ΕΒͷΛղܾ͢ΔͨΊʹ † ిؾ௨৴େֶ ใֶՊDepartment of Computer Science, The University of Electro-Communications ༷ʑͳख๏͕ఏҊ͞Ε͍ͯΔɽதͰੈผGC2),3) ΄ͱΜͲͷΦϒδΣΫτੜޙ·ͳ͘͝Έͱͳ Δͱ͍͏Ծઆ(ੈԾઆ)ʹج͖ͮण໋ΦϒδΣΫ τΛޮతʹճऩͰ͖Δɽ͔ͦ͠͠ͷ··Ͱอकత ΞϧΰϦζϜ4)Λద༻Ͱ͖ͳ͍ͳͲίετେ͖͍ɽ ຊݚڀͰʮण໋ΦϒδΣΫτͷଟ͘༗ޮൣғ ͕੩తʹผՄೳͳΦϒδΣΫτͰΊΒΕΔͷͰ ͳ͍͔ʯͱͷ༧Λͨͯɼͦͷ͔֬͞Λݕূ͢Δɽͦ ͯ͠੩తղੳʹΑΓण໋ΦϒδΣΫτͷൃݟɾճऩ Λߦ͏ख๏ΛఏҊ͢Δɽ༧ͷݕূΦϒδΣΫτࢦ εΫϦϓτݴޠͰ͋ΔRuby5)ॲཧܥMRIʹͯߦ ͏ɽRubyۙ։ൃɾݚڀ༻్Ͱͷར༻͕·ͬͯ ͍Δ͕GCͷ࣮ະͩෆेͰ͋ΓɼఏҊख๏ʹΑ Γੑೳ্͕ݟࠐΊΔɽ ҎԼୈ2ষͰGCͷ֓ཁͱؔ࿈ݚڀʹ͍ͭͯɼୈ 3ষͰείʔϓϩʔΧϧͳΦϒδΣΫτ͕ण໋Φ ϒδΣΫτͷଟ͘ΛΊΔͱͷ༧ͱɼ༧ʹج͍ͮ ͨ੩తղੳGCʹ͍ͭͯड़Δɽୈ4ষͰఏҊख๏ͷ
ݕূ࣮ݧͱͦͷ݁Ռɼୈ5ষͰߟΛड़ɼୈ6ষͰ ·ͱΊΔɽ
2. GC ͷ֓ཁͱؔ࿈ݚڀ
Mark Sweep GC6)ϧʔτηοτ(ώʔϓҎ֎ͷ ੩తྖҬɼελοΫɼϨδελΛ߹ΘͤͨྖҬ)͔Β ࢀরΛ࠶ؼతʹ୧Γ౸ୡՄೳͰ͋ΔΦϒδΣΫτΛੜ ͖ͨΦϒδΣΫτɼͦΕҎ֎Λ͝ΈΦϒδΣΫτͱݟ ͳ͢Tracing GCΞϧΰϦζϜͷҰͭͰ͋Δɽ࣮͕ ؆୯Ͱ͋Δ͜ͱ͋Γ͘ΘΕΔ͕ɼ୯७ʹͦͷ· ·࣮͢ΔͱੑೳΛٻΊΔ߹ʹෆेͰ͋Δɽ ੈผGCੈԾઆʹج͖ͮण໋ΦϒδΣΫτ ͰΊΒΕΔ৽ੈྖҬͱण໋ΦϒδΣΫτͰΊ ΒΕΔچੈྖҬʹ͚ͯཧ͢ΔGCͰ͋Δɽੈ Ծઆ(Generational Hypothesisɼ৽͘͠ੜ͞ΕͨΦ ϒδΣΫτݹ͍ΦϒδΣΫτΑΓੜଘ͕͍ͱͷ Ծઆ)ଟͷݚڀऀʹΑΓݕূ͞Εɼͦͷ͔͕֬͞ ࣔ͞Ε͍ͯΔɽϝϞϦྖҬ͕ރׇͨ͠ࡍʹ·ͣGC ରΛ৽ੈྖҬͱͨ͠Minor GCΛߦ͏ɽچੈ ྖҬΛؚΊͨશମΛରͱͨ͠Major GCMinor GCʹΑΓेͳྖҬ͕֬อͰ͖ͳ͔ͬͨ߹ͷΈʹ ߦΘΕΔɽ͋ΔఔͷճMinor GCΛੜ͖ͬͨ ΦϒδΣΫτچੈҠಈ͞ΕΔɽੈผGCͰ ͦͷॲཧͷଟ͘Λੜଘͷ͍ण໋ΦϒδΣΫτΛ ޮతʹճऩ͢ΔMinor GC͕Ίɼͦͷ݁Ռ୯७ ͳGCʹൺͯੑೳ্͕ݟࠐΊΔɽ͔͠͠ɼػߏͷ ෳࡶ͞ɼچੈ͔Β৽ੈͷࢀরΛه͢ΔͨΊͷ ϥΠτόϦΞͷॻ͖ࠐΈίετɼอकతGC (ϙΠϯ λͱͳΓ͏ΔΛ࣋ͭΦϒδΣΫτϙΠϯλͱݟͳ ͢ΞϧΰϦζϜ)ͱͷΈ߹Θ͕ͤࠔͳͲͷ͕ ͋Δɽ ϚϧνίΞϓϩηοαͷීٴʹ͍εϨουΤεέʔ ϓղੳ͕͞Ε͍ͯΔ7)ɽੜ͞ΕͨΦϒδΣΫτ ͕୯ҰͷεϨουͰΘΕΔ߹ʹεϨουϩʔΧ ϧͷώʔϓ͔Βղ์ͯ͠Α͍ɽ͜ͷώʔϓଞͷε ϨουͱಠཱʹճऩՄೳͰ͋Δɽ͜͏ͨ͠ߟ͑ͷݩʹ ͍͔ͭ͘ͷ࣮༻తͳΤεέʔϓղੳͷղੳਫ਼ʹͭ ͍ͯൺֱݕ౼͞Ε͍ͯΔ͕ɼείʔϓϩʔΧϧͳΦϒ δΣΫτण໋ΦϒδΣΫτͷதͷͲΕ͙Β͍ͷׂ߹ ΛΊΔ͔ͱ͍͏ʹؔ৺͕ΘΕ͍ͯͳ͍ɽ RubyɼखܰͳΦϒδΣΫτࢦϓϩάϥϛϯά Λ࣮ݱ͢ΔͨΊͷछʑͷػೳΛ࣋ͭΦϒδΣΫτࢦ εΫϦϓτݴޠͰ͋Δ5)ɽڧྗͳςΩετॲཧɼϓϩ άϥϛϯάΛ༰қʹ͢Δγϯϓϧͳจ๏ͳͲͷಛ͕ ͋Γɼۀɾݚڀ༻్ʹීٴ͖͍ͯͯ͠Δɽ͔͠͠ɼ ݱࡏओʹར༻͞Ε͍ͯΔRubyॲཧܥMRIͷGC ະͩෆेͰ͋Δɽ3. ఏ Ҋ ख ๏
ੈผGCण໋ΦϒδΣΫτΛޮతʹճऩ ͠ੑೳ্͕ݟࠐΊΔҰํͰɼͦͷίετখ͘͞ ͳ͍ɽຊݚڀͰण໋ΦϒδΣΫτʹରͯ͠ʮण ໋ΦϒδΣΫτͦͷଟ͕͘είʔϓϩʔΧϧͳΦϒ δΣΫτ͕ΊΔͷͰͳ͍͔ʯͱͷ༧Λݕূ͠ɼ ༧ʹج͍ͮͨ੩తղੳʹΑΔण໋ΦϒδΣΫτͷ ճऩख๏ʹ͍ͭͯఏҊ͢Δɽ 3.1 ण໋ΦϒδΣΫτʹؔ͢Δ༧ ΞηϯϒϦݴޠCɼC++ͱ͍ͬͨݴޠʹΑΓϓ ϩάϥϜΛهड़͢ΔϓϩάϥϚม͕ؔϝϞϦ தͷͲͷྖҬʹ֨ೲ͞ΕΔ͔ҙࣝ͢Δඞཁ͕͋Δɽ͜ ͷΑ͏ͳϓϩάϥϜͰɼؔҾฦΓɼҰ࣌ม ͳͲͷण໋͕͔͘ϓϩάϥϜͷߏจ͔Βͦͷม ͷࢀর͞Ε͏Δൣғ(είʔϓ)͕ఆ·͍ͬͯΔม ௨ৗελοΫྖҬʹ֬อ͞ΕΔɽ Ұํݹ͘Lisp͔Β࢝·Δߴڃϓϩάϥϛϯάύ ϥμΠϜʹ͓͍ͯϓϩάϥϚม͕ؔϝϞϦ தͷͲͷྖҬʹ֨ೲ͞ΕΔ͔ҙࣝ͢Δඞཁ͕ͳ͍ɽ͜ ͷ߹ϓϩάϥϚʹɼશͯͷมؔώʔϓʹ ֨ೲ͞ΕɼϓϩάϥϜऴྃ·ͰࢀরͰ͖ΔΦϒδΣΫ τʹݟ͑Δɽ͜ͷΑ͏ʹɼߴڃϓϩάϥϛϯάύϥμ ΠϜʹ͓͍ͯɼCͳͲͰελοΫྖҬʹҰ࣌తʹอ ͍࣋ͯͨ͠είʔϓϩʔΧϧͳมʹ͍ͭͯώʔϓ ྖҬʹ֨ೲ͢ΔɽશͯͷΦϒδΣΫτ͕ϓϩάϥϜऴ ྃ࣌·ͰώʔϓྖҬʹଘࡏ͠ଓ͚Δ͔ͷΑ͏ʹݟͤΔ ͨΊʹGC͕ඞཁͱͳΔɽҰൠʹGCͰείʔϓ ϩʔΧϧͳมʹ͍ͭͯಈతճऩͷରͱ͢Δɽಛ ʹੈผGCͰੜଘͷ͍ण໋ΦϒδΣΫτʹ ண͠ޮతʹճऩ͢Δɽण໋ΦϒδΣΫτͰ͋Δ ͔Ͳ͏͔ಈతʹఆ͢Δɽ GCʹ͓͍ͯޮྑ͘ΦϒδΣΫτΛճऩ͢ΔͨΊ ʹੜଘͷ͍ण໋ΦϒδΣΫτͷผ͕ॏཁͰ ͋ΔɽຊݚڀͰण໋ΦϒδΣΫτͷଟ͘είʔ ϓϩʔΧϧͳΦϒδΣΫτͰ͋Δͱͷ༧ΛͨͯΔɽ είʔϓϩʔΧϧͳΦϒδΣΫτϓϩάϥϜͷߏ ͔Βఆ·Γɼ੩తʹผ͕ՄೳͰ͋Δɽ͜ͷ༧͕ਖ਼ ͚͠Εੜଘͷ͍ण໋ΦϒδΣΫτͷଟ͕͘༰ қʹผͰ͖Δ͜ͱͱͳΓɼGCͷޮͷ্ʹཱ ͭͱߟ͑ΒΕΔɽ3.2 ੩తղੳʹΑΔण໋ΦϒδΣΫτͷผͱ ճऩ είʔϓϩʔΧϧͳΦϒδΣΫτϓϩάϥϜΛղ ੳ͢Δ͜ͱͰɼ࣮ߦͤͣͱগͳ͍ίετͰൃݟ͠ɼ ੜ͖͍ͯΔൣғΛௐΔ͜ͱ͕Ͱ͖Δɽͦ͜Ͱϓϩά ϥϜͷ੩తղੳʹΑΓ࣮ߦલʹण໋ΦϒδΣΫτΛ ผ͠ผ͞ΕͨΦϒδΣΫτΛ༻ޙʹճऩ͢Δํ ๏Λࣔ͢ɽ
RubyॲཧܥMRIʹ͓͍ͯɼϓϩάϥϜRuby
ݴޠͰॻ͘෦ͱCݴޠͰॻ͘ϥΠϒϥϦ෦͕͋ ΔͷͰɼͦΕͧΕʹ͍ͭͯϩʔΧϧΦϒδΣΫτͷ ผ͓Αͼճऩʹ͍ͭͯड़Δɽ ͜ͷख๏͕༗ޮͰ͋Δ͔Ͳ͏͔ɼ੩తղੳʹΑΓ ผ͞ΕΔείʔϓϩʔΧϧͳΦϒδΣΫτ͕ण໋ ΦϒδΣΫτશମͷଟ͘ΛΊΔͱͷ༧ͷଥੑʹ ґଘ͢Δɽ༧ͷݕূ࣍ষͰड़Δɽ 3.2.1 RubyϓϩάϥϜʹ͓͚ΔϩʔΧϧΦϒδΣ Ϋτ MRIೖྗͨ͠RubyϓϩάϥϜΛҰ୴ߏจͱ ͯ͠ߏஙͨ͠ޙʹRubyͷVirtual Machine(VM)ͷ όΠτίʔυʹίϯύΠϧ࣮ͯ͠ߦ͢ΔɽྻԽ͞Ε ͨόΠτίʔυߏΛ࣋ͭෳࡶͳߏจʹൺ ୯७Ͱղੳ͍ͨ͢͠ΊɼRubyϓϩάϥϜதʹग़ͯ ͘ΔϩʔΧϧΦϒδΣΫτͷผɾճऩͳͲόΠτ ίʔυʹରͯ͠ߦ͏ͷ͕దͰ͋Δͱߟ͑ΒΕΔɽ όΠτίʔυʹ͓͍ͯϩʔΧϧΦϒδΣΫτ͕Ͳͷ Α͏ʹੜ͞ΕΔ͔Λਤ1ͷΑ͏ͳؔstrΛྫͱ͠ ͯߟ͑Δɽ͜ͷϓϩάϥϜͷมa ɼb ͦΕͧΕ b = a + aɼ"hoge#{b}"ͱ͍͏ԋࢉҎ߱༻͞Ε ͳ͍ɽؔstrͷίϯύΠϧ݁ՌΛਤ2ʹࣔ͢ɽ0021 ൪ͷtostring໋ྩɼਤ3ͷίʔυͰఆٛ͞Εɼ༩ ͑ΒΕͨΦϒδΣΫτΛจࣈྻԽͯ͠ฦ͢ɽtostring Ͱੜ͞ΕͨจࣈྻΦϒδΣΫτ0022൪ͷ con-catstringsͰར༻͞ΕͨޙΘΕΔ͜ͱͳ͍ɽ͜ ΕΒͷείʔϓϩʔΧϧͳΦϒδΣΫτण໋Ͱ͋ ΔʹؔΘΒͣ࣍ճGC·Ͱੜ͖Γଓ͚Δɽ ͜ͷΑ͏ʹRubyόΠτίʔυϓϩάϥϜʹ͓͚Δ ϩʔΧϧΦϒδΣΫτɼਤ1ͷaɼbͷΑ͏ʹϓϩ άϥϚ͕ॻ͘ϓϩάϥϜதʹ໌ࣔతʹग़ݱ͢Δͷͱɼ ਤ2ͷtostringͰੜ͞ΕΔจࣈྻΦϒδΣΫτͷΑ ͏ʹͦ͏Ͱͳ͍ͷ͕͋Δ͕ɼ͍ͣΕRubyόΠτ ίʔυίϯύΠϥʹ࣍ͷΑ͏ͳ࠷దԽΛՃ͑Δ͜ͱͰ ରԠͰ͖Δ: ͦΕΒͷΦϒδΣΫτΛ༻ޙʹճऩ͢ ΔίʔυΛՃ͢Δɼ·ͨɼΦϒδΣΫτΛελο 1 def str 2 a = 10.0 3 b = a + a 4 return "hoge#{b}" 5 end ਤ 1 ؔ str(Ruby ϓϩάϥϜ) 0000 trace 8 0002 trace 1 0004 putobject 10.0 0006 setlocal a 0008 trace 1 0010 getlocal a 0012 getlocal a 0014 opt_plus 0015 setlocal b 0017 putobject "hoge" 0019 getlocal b 0021 tostring 0022 concatstrings 2 0024 trace 16 0026 leave ਤ 2 ؔ str(Ruby όΠτίʔυ) 1 /** 2 @c put 3 @e to_str 4 @j to_str ͷ݁ՌΛελοΫʹϓογϡ͢Δ 5 */ 6 DEFINE_INSN 7 tostring 8 () 9 (VALUE val) 10 (VALUE val) 11 { 12 val = rb_obj_as_string(val); 13 } ਤ 3 VM ໋ྩ tostring ΫׂΓͯʹΑΓੜ͢Δɽ 3.2.2 CݴޠϥΠϒϥϦʹ͓͚ΔϩʔΧϧΦϒδΣ Ϋτ MRIʹ͓͍ͯϥΠϒϥϦͷଟ͘CݴޠʹΑΓه ड़͞Ε͍ͯΔɽϩʔΧϧΦϒδΣΫτͷதʹ͜ͷC ݴޠͷϨϕϧͰੜ͞Ε͍ͯΔͷଟ͋͘Δɽ Ұྫͱͯ͠ਤ4ʹࣔ͢Bignum(ଟഒ)Φϒ δΣΫτͷՃࢉΛఆٛ͢Δؔ rb_big_plus Λͱ Γ͋͛Δɽ͜ͷίʔυதʹग़ͯ͘Δrb int2bigɼ Fixnum(ݻఆͷ)ΦϒδΣΫτΛҾͱͯ͠ BignumΦϒδΣΫτΛੜ͢ΔؔͰ͋Δɽ͜ͷ ίʔυͷ߹ɼ5ߦͰrb_int2big(FIX2LONG(y)); ʹ Α Γ ੜ ͞ Ε ͨ Φ ϒ δΣΫ τ y ɼ͜ ͷ ؔ rb_big_plusͷऴྃޙΞΫηε͞Εͳ͍͕ɼ࣍ճ GC͕ൃੜ͢Δ·Ͱώʔϓதʹੜ͖Γଓ͚Δɽ
1 rb_big_plus(VALUE x, VALUE y) 2 { 3 switch (TYPE(y)) { 4 case T_FIXNUM: 5 y = rb_int2big(FIX2LONG(y)); 6 /* fall through */ 7 case T_BIGNUM: 8 return bignorm(bigadd(x, y, 1)); 9 10 case T_FLOAT: 11 return DOUBLE2NUM(rb_big2dbl(x) 12 + RFLOAT_VALUE(y)); 13 14 default: 15 return rb_num_coerce_bin(x, y, ’+’); 16 } 17 }
ਤ 4 Bignum ͷՃࢉϝιουఆٛ rb big plus
ද 1 Ruby ϕϯνϚʔΫϓϩάϥϜͷઆ໌ app_factorial ֊ؔΛ࠶ؼతʹ܁Γฦ͢ app_raise ୯७ͳΈࠐΈྫ֎ͷൃੜͱ ิΛ܁Γฦ͢ so_object ΦϒδΣΫτͷੜΛ܁Γฦ ͢ so_random ුಈখͷԋࢉΛ܁Γฦ ͢ app_strconcat ࣜల։ʹΑΓจࣈྻͷ࿈݁Λ ܁Γฦ͢ so_concatenate จࣈྻͷ࿈݁Λ܁Γฦ͢ so_count_words ೖྗ͞ΕͨςΩετͷߦɼ ୯ޠɼจࣈΛΧϯτ͢ Δ so_exception Ϣʔβఆٛͷྫ֎ͷൃੜͱิ Λ܁Γฦ͢ so_lists ྻʹؔ͢ΔجຊతͳԋࢉΛ ܁Γฦ͢ so_matrix ଟ࣍ݩྻʹؔ͢Δجຊతͳ ԋࢉΛ܁Γฦ͢ vm2_array ྻϦςϥϧʹΑΓྻͷੜ Λ܁Γฦ͢ vm3_thread_create_join εϨουͷੜΛ܁Γฦ͢ hoge app_mandelbrot Ϛϯσϧϒϩʔू߹ܭࢉΛ͢ Δ ͜ͷΑ͏ͳ͝ΈΦϒδΣΫτɼCͷϥΠϒϥϦ ιʔείʔυΛΦϒδΣΫτ༻ޙʹճऩ͢ΔΑ͏ม ߋ͢Δ͔ɼΦϒδΣΫτΛελοΫׂΓͯʹΑΓੜ ͢Δͷͱ͢ΔɽϓϩάϥϚʹར༻͞ΕΔϥΠϒϥ Ϧͷ͜ͷΑ͏ͳมߋ༧Ίݴޠॲཧܥ࣮ʹΈࠐ Ή͜ͱ͕Ͱ͖Δɽ
4. ݕ ূ ࣮ ݧ
͜͜Ͱण໋ΦϒδΣΫτʹؔ͢Δ༧ͷݕূ࣮ ݧʹ͍ͭͯํ๏ͱ݁ՌΛड़Δɽ 1 def str 2 a = GC.mark_local(10.0) 3 b = GC.mark_local(a + a) 4 return "hoge#{b}" 5 end ਤ 5 ؔ str ͷ Ruby ϓϩάϥϜʹ͓͚ΔϚʔΩϯά 0000 trace 8 0002 trace 1 0004 getinlinecache <ic>, 11 0007 getconstant :GC 0009 setinlinecache 4 0011 putobject 10.00013 send :mark_local, 1, nil, 0, <ic> 0019 setlocal a 0021 trace 1 0023 getinlinecache <ic>, 30 0026 getconstant :GC 0028 setinlinecache 23 0030 getlocal a 0032 getlocal a 0034 opt_plus
0035 send :mark_local, 1, nil, 0, <ic> 0041 setlocal b 0043 putobject "hoge" 0045 getlocal b 0047 tostring 0048 concatstrings 2 0050 trace 16 0052 leave ਤ 6 ؔ str ͷ Ruby όΠτίʔυʹ͓͚ΔϚʔΩϯά 4.1 ํ ๏
Ruby Benchmark Suite8)ͷ͏ͪද1ʹࣔ͢Ruby
ϓϩάϥϜʹ͍ͭͯɼखಈͰϩʔΧϧΦϒδΣΫτΛ ϚʔΫͯ͠ΦϒδΣΫτશମʹର͢ΔൺΛௐΔɽ ࣮ݧʹMRI 1.9.0-4ʹҎԼͷมߋΛՃ͑ͨͷΛ༻ ͍ͨɽ • ΦϒδΣΫτʹϩʔΧϧΦϒδΣΫτͰ͋Δ͜ͱ Λࣔ͢ใΛ͚Δɽ • શΦϒδΣΫτͷੜ࣌ࠁɼ͝ΈʹͳΔ࣌ࠁɼϩʔ ΧϧΦϒδΣΫτใΛه͠ɼදࣔ͢Δɽ RubyϓϩάϥϜʹՃ͑Δมߋʹ͍ͭͯ3.2.1ͷਤ 1ɼਤ2Ͱࣔ͢ϓϩάϥϜΛྫͱͯ͠આ໌͢Δɽੜ ͞ΕΔϩʔΧϧΦϒδΣΫτͷ͏ͪɼRubyϓϩάϥ Ϝʹ໌ࣔతʹग़ݱ͢ΔϩʔΧϧมaɼbʹରͯ͠ ਤ5ɼਤ6ʹࣔ͢Α͏ʹGC.mark_local_object(x) ͱͯ͠ϚʔΫ͢ΔɽVM໋ྩͷtostringͰੜ͞Ε ΔϩʔΧϧΦϒδΣΫτʹରͯ͠ਤ7ʹࣔ͢Α͏ʹ tostring໋ྩͷఆٛΛมߋͯ͠ϚʔΫ͢Δɽ CݴޠϥΠϒϥϦʹՃ͑Δมߋɼྫ͑ਤ4ͷϥ ΠϒϥϦͷྫͰϓϩάϥϜதͷϩʔΧϧΦϒδΣΫ
1 DEFINE_INSN 2 tostring 3 () 4 (VALUE val) 5 (VALUE val) 6 { 7 val = rb_obj_as_string(val); 8 MARK_LOCAL(val); 9 } ਤ 7 VM ໋ྩ tostring ʹ͓͚ΔϚʔΩϯά 1 VALUE 2 rb_big_plus(VALUE x, VALUE y) 3 { 4 switch (TYPE(y)) { 5 case T_FIXNUM: 6 y = rb_int2big(FIX2LONG(y)); 7 MARK_LOCAL(y); 8 /* fall through */ 9 case T_BIGNUM: 10 return bignorm(bigadd(x, y, 1)); 11 12 case T_FLOAT: 13 return DOUBLE2NUM(rb_big2dbl(x) 14 + RFLOAT_VALUE(y)); 15 16 default: 17 return rb_num_coerce_bin(x, y, ’+’); 18 } 19 } ਤ 8 C ݴޠϥΠϒϥϦʹ͓͚ΔϚʔΩϯάͷྫ 0 20 40 60 80 100 0 20 40 60 80 100 collection rate
age at collection [allocation counts]
short-lived objects / all objects local objects / all objects
ਤ 9 app mandelbrot ʹ͓͚ΔΦϒδΣΫτճऩ (ԣ࣠Φϒ δΣΫτͷण໋ (age at collection) Λ ruby ͷΞϩέʔγϣ ϯճ (allocatin counts) Λ୯Ґͱͯ͋͠ΒΘ͢) τyʹରͯ͠ਤ8ʹࣔ͢Α͏ʹMARK_LOCALͰϚʔ Ϋ͢Δɽ 4.2 ݁ Ռ ϕ ϯ ν Ϛ ʔ Ϋ ϓ ϩ ά ϥ Ϝ app_mandelbrot ͱ so_count_wordsΛྫͱͯ͠ɼੜ͞ΕΔΦϒδΣΫ τͷճऩΛਤ9ɼਤ10ʹࣔ͢ɽԣ࣠ΦϒδΣΫτ ͷण໋(age at collection)ΛrubyͷΞϩέʔγϣϯճ
0 20 40 60 80 100 0 20 40 60 80 100 collection rate
age at collection [allocation counts]
short-lived objects / all objects local objects /all objects
ਤ 10 so count words ʹ͓͚ΔΦϒδΣΫτճऩ
(allocatin counts)Λ୯Ґͱͯ͋͠ΒΘ͢ɽ( ruby
ͷΞϩέʔγϣϯͰجຊతʹ5ϫʔυ֬อ͞ΕΔͷ Ͱɼ1 allocation count = 5 wordͱࢉͰ͖Δɽ)ॎ ࣠͋Δण໋ʹ͓͍ͯͦͷण໋ҎԼͷΦϒδΣΫτͷ ΦϒδΣΫτશମʹର͢Δׂ߹Λ͋ΒΘ͢ɽਤʹ͓͍ ͯɼ࣮ઢΦϒδΣΫτશମͷճऩɼഁઢϩʔΧ ϧΦϒδΣΫτͷճऩΛࣔ͢ɽਤ͔ΒΞϩέʔγϣ ϯճ20Ͱ΄ͱΜͲશͯͷΦϒδΣΫτ͕͝Έͱ ͳ͍ͬͯΔ͜ͱ͕Θ͔ΔɽଞͷϕϯνϚʔΫʹ͍ͭͯ ಉ༷Ͱ͋Δɽ ਤ11ද1ͷϕϯνϚʔΫϓϩάϥϜʹ͓͚Δશ ΦϒδΣΫτதͷण໋ΦϒδΣΫτͷׂ߹ͱશΦϒ δΣΫτதͷείʔϓϩʔΧϧͳΦϒδΣΫτͷׂ߹ Λࣔ͢ɽ͜͜Ͱ100ΞϩέʔγϣϯճҎԼͰ͝ ΈͱͳΔΦϒδΣΫτΛण໋ΦϒδΣΫτͱͨ͠ɽ ਤ͔Β΄ͱΜͲͷΦϒδΣΫτ͕ण໋ΦϒδΣΫτ Ͱ͋Δ͜ͱ͕Θ͔Δɽ·ͨɼগͷϓϩάϥϜͰྫ֎ ͋Δ͕ɼण໋ΦϒδΣΫτͷଟ͘Λείʔϓϩʔ ΧϧΦϒδΣΫτ͕Ί͍ͯΔ͜ͱ͕Θ͔ΔɽΑͬͯ ʮण໋ΦϒδΣΫτͦͷଟ͕͘είʔϓϩʔΧϧ ͳΦϒδΣΫτ͕ΊΔͷͰͳ͍͔ʯͱͷ༧ݕ ূ͞Εͨͱݴ͑Δɽ
5. ߟ
࣮ݧ݁Ռ͔Β༧ʹ͢ΔϕϯνϚʔΫϓϩάϥϜ ͍͔ͭ͘ଘࡏ͢ΔɽͦͷݪҼϩʔΧϧΦϒδΣΫ τͷதͰϚʔΫͰ͖ͳ͔ͬͨͷ͕ଘࡏ͢ΔͨΊͰ͋ ΔɽͦΕΒϚʔΫͰ͖ͳ͔ͬͨΦϒδΣΫτʹؔͯ͠ ҎԼͷΑ͏ͳཧ༝͕ߟ͑ΒΕΔɽ ( 1 ) ण໋ΦϒδΣΫτͰ͋Γ੩తղੳͷஈ֊Ͱݕ ग़ՄೳͳείʔϓϩʔΧϧΦϒδΣΫτͰ͋Δ1 2 3 4 5 6 7 8 9 10 11 12 13 0 20 40 60 80 100 short−lived / all local / all 1 app_factorial 2 app_raise 3 so_object 4 so_random 5 app_strconcat 6 so_concatenate 7 so_count_words 8 so_exception 9 so_lists 10 so_matrix 11 vm2_array 12 vm3_thread_create_join 13 app_mandelbrot ਤ 11 ද 1 ͷϕϯνϚʔΫϓϩάϥϜʹ͓͚ΔશΦϒδΣΫτதͷण໋ΦϒδΣΫτͷׂ߹ ͱશΦϒδΣΫτதͷείʔϓϩʔΧϧͳΦϒδΣΫτͷׂ߹ 1 $a = [] 2 class Float 3 def +(y) 4 $a.push(self) 5 $a.push(y) 6 self 7 end 8 end 9 def str 10 a = 10.0 11 b = a + a 12 return "hoge#{b}" 13 end 14 p str() # "hoge10.0" 15 p $a # [10.0, 10.0] ਤ 12 ϝιουͷ࠶ఆٛͷྫ ͕ɼࠓճͷ࣮ݧͰϚʔΫ࿙Ε͍ͯ͠Δɽ ( 2 ) Rubyݴޠʹ͓͍ͯΈࠐΈϝιου͕࠶ఆٛ ՄೳͰ͋Δ͜ͱʹΑΓϩʔΧϧΦϒδΣΫτͰ ͋Δ͔Ͳ͏͔͕Ұҙతʹఆ·Βͳ͍ɽ ( 3 ) ण໋ΦϒδΣΫτͰ͋Δ͕είʔϓϩʔΧϧ Ͱͳ͍ͷ͕ଘࡏ͠ɼೖྗʹΑΓण໋ʹͳ Δ߹ͱण໋ʹͳΔ߹͕͋Γɼ੩తղੳͷ ஈ֊ͰผෆՄೳͰ͋Δɽ ࠓճͷ࣮ݧͷ߹ϩʔΧϧΦϒδΣΫτͷผͱ ϚʔΩϯάखಈͰߦͬͨͨΊɼϚʔΫ࿙ΕҰ൪ ͷཧ༝ʹΑΔͷ͕΄ͱΜͲͰ͋ΓɼࣗಈԽʹΑͬͯ ͜ͷϚʔΫ࿙ΕݮগͰ͖Δͱߟ͑ΒΕΔɽ ͜͜Ͱೋ൪ͷRubyݴޠͷಛघੑʹ͍ͭͯߟ ͢ΔɽRubyʹͲΜͳΫϥεʹରͯ͠ϝιουͷ ࠶ఆ͕ٛͰ͖Δͱ͍͏ಛ͕͋Δɽྫ͑ਤ12ʹࣔ ͢Α͏ʹΈࠐΈΫϥεͰ͋ΔුಈখͷՃࢉϝ ιουʹ͍ͭͯ࠶ఆ͕ٛՄೳͰ͋Δɽؔstrਤ 1ͷఆٛͱಉ͕ͩ͡ɼ͜ͷؔstrʹ͓͚Δมa άϩʔόϧม$a͔Βࢀর͞Ε͍ͯΔͨΊείʔϓ ϩʔΧϧΦϒδΣΫτͱͳΒͳ͍ɽ͜ͷΑ͏ʹΈ ࠐΈͷՃࢉϝιουͰϩʔΧϧΦϒδΣΫτͱͳΔ ͕ɼ࠶ఆٛ͞ΕͨՃࢉϝιουͰϩʔΧϧΦϒδΣ ΫτͱͳΒͳ͍߹͕͋ΔɽΑͬͯRubyʹ͓͍ͯ੩ తղੳʹΑΔࣗಈճऩΛߦ͏ͨΊʹɼݪଇͱͯ͠ ΈࠐΈϝιουͷ࠶ఆ͕ٛߦΘΕ͍ͯͳ͍ͷͱ͠ɼ ࠶ఆ͕ٛߦΘΕͨ߹ʹ੩తղੳ͕ෆՄೳͰ͋Δͱ அ͢Δඞཁ͕͋Δɽ ࡾ൪ͷΑ͏ͳείʔϓϩʔΧϧͰͳ͍ण໋Φ ϒδΣΫτ੩తʹผෆՄೳͰ͋Δɽ Ҏ্ͷΑ͏ʹຊख๏Λద༻ͯ͠ण໋ΦϒδΣΫ τͷશͯ੩తʹผͰ͖ͳ͍ɽ͔͠͠ैདྷͷಈతͳ GCख๏ʹΑΓճऩ͖͢ΦϒδΣΫτͷྔݮগ͢ ΔɽϩʔΧϧΦϒδΣΫτΛ੩తʹղ์͢Δۭ͖༰
ྔ͕֬อ͞ΕɼGCͷස͕ݮΔͨΊੑೳ্͢Δɽ
6. ͓ Θ Γ ʹ
࣮ݧʹΑΓण໋ΦϒδΣΫτʹؔ͢Δʮण໋Φ ϒδΣΫτͦͷଟ͕͘είʔϓϩʔΧϧͳΦϒδΣ Ϋτ͕ΊΔͷͰͳ͍͔ʯͱͷ༧ͷ͔͕֬͞ݕূ ͞ΕͨɽࠓޙCݴޠϥΠϒϥϦͷϩʔΧϧΦϒδΣ ΫτͷߋͳΔআڈɼόΠτίʔυͷղੳʹΑΔϩʔΧ ϧΦϒδΣΫτͷࣗಈผ͓Αͼճऩ͕ߟ͑ΒΕΔɽࢀ ߟ จ ݙ
1) R. E. Jones. Garbage Collection: Algorithms
for Automatic Dynamic Memory Management.
Wiley, Chichester, July 1996.
2) ࢁਅਓ,ࠤݪେี,ా. ΦϒδΣΫτࢦ εΫϦϓτݴޠrubyͷੈผ͝ΈूΊ࣮ ख๏ͷվྑͱͦͷධՁ. ใॲཧֶձจࢽ,ϓ ϩάϥϛϯά, Vol. 43, No. 1, pp. 25–35, 2002. 3) M. Hirzel. Data layouts for object-oriented
programs. SIGMETRICS Perform. Eval. Rev., Vol. 35, No. 1, pp. 265–276, 2007.
4) H.-J. Boehm. Bounding space usage of con-servative garbage collectors. In Conference
Record of the Twenty-ninth Annual ACM Sym-posium on Principles of Programming Lan-guages, ACM SIGPLAN Notices. ACM Press,
January 2002.
5) RubyίϛϡχςΟ.ΦϒδΣΫτࢦεΫϦϓ τݴޠRuby. http://www.ruby-lang.org/ja/. 6) J. McCarthy. Recursive functions of symbolic
expressions and their computation by machine.
Communications of the ACM, Vol. 3, pp. 184–
195, 1960.
7) K. Lee, X. Fang, and S. P. Midkiff. Practical escape analyses: how good are they? In VEE
’07: Proceedings of the 3rd international con-ference on Virtual execution environments, pp.
180–190, New York, NY, USA, 2007. ACM. 8) The Ruby Benchmark Suite Project. Ruby
Benchmark Suite. http://groups.google.com/ group/ruby-benchmark-suite.