Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unity+C#で学ぶ! メモリレイアウトとvtableのすゝめ 〜動的ポリモーフィズムを実現する仕組み〜

Kutani Mio
January 27, 2023

Unity+C#で学ぶ! メモリレイアウトとvtableのすゝめ 〜動的ポリモーフィズムを実現する仕組み〜

Unityで開発する際にはメモリ周りについて考える方も多いでしょう。
今回はそのメモリに対して焦点を当てて、Unityでのメモリがどのようにレイアウトされているのか、また動的ポリモーフィズムがどのように実現されているのかを、図を用いてなるべくわかりやすい形で解説致します。

Kutani Mio

January 27, 2023
Tweet

More Decks by Kutani Mio

Other Decks in Programming

Transcript

  1. Introduce myself ABOUT ME ΠʔϒΠ͕޷͖ͳήʔϜΤϯδχΞͰ͢ɻ ͱ͋ΔήʔϜձࣾʹͯɺ 
 ϦʔυΫϥΠΞϯτΤϯδχΞΛ୲౰ɻ ࠷ۙ͸࠾༻ͱϚωδϝϯτ͕ଟΊɻ 


    ෭ۀͰ͸ϝλόʔεܥ͕ϝΠϯͰ͢ɻ Ζͬ͞Ή εΩϧηοτ Unity C# 5೥͘Β͍ (2D, 3D൒ʑ) Unreal Engine C++ 3೥(झຯࠐΈ) 
 Jenkins͓͹͞Μͨ͠Γ ӳޠษڧͨ͠Γ 2018.3ʙ2022.3 MSMVPͰͨ͠
  2. C#ଆͰ࢖༻͞ΕΔɻ OSଆ΍ɺMono·ͨ͸IL2CPPʹΑͬͯ ϝϞϦͷ֬อɾղ์͕ࣗಈతʹ 
 ؅ཧ͞ΕΔϝϞϦϨΠϠʔɻ ϚωʔδϝϞϦ ϝϞϦͷछྨ Unity͕؅ཧͯ͠ΔϝϞϦʹ͍ͭͯ C#ଆͰ࢖༻͞ΕΔɻ JobSystem΍BurstΛ࢖༻͢Δࡍʹ͸

    ͜ͷϝϞϦϨΠϠʔΛ࢖͏ɻ ϝϞϦͷ֬อɾղ์͸ࣗݾ੹೚Ͱߦ͏ɻ C#ͷΞϯϚωʔδϝϞϦ UnityଆͰ࢖༻͞ΕΔɻ UnityࣗମΛ࣮ߦ͢ΔC++ͷͨΊͷ 
 ϝϞϦϨΠϠʔͰ͋Γɺ 
 ௚઀৮Δػձ͸͋·Γͳ͍ɻ ωΠςΟϒϝϞϦ
  3. C#ଆͰ࢖༻͞ΕΔɻ OSଆ΍ɺMono·ͨ͸IL2CPPʹΑͬͯ ϝϞϦͷ֬อɾղ์͕ࣗಈతʹ 
 ؅ཧ͞ΕΔϝϞϦϨΠϠʔɻ ϚωʔδϝϞϦ ϝϞϦͷछྨ Unity͕؅ཧͯ͠ΔϝϞϦʹ͍ͭͯ C#ଆͰ࢖༻͞ΕΔɻ JobSystem΍BurstΛ࢖༻͢Δࡍʹ͸

    ͜ͷϝϞϦϨΠϠʔΛ࢖͏ɻ ϝϞϦͷ֬อɾղ์͸ࣗݾ੹೚Ͱߦ͏ɻ C#ͷΞϯϚωʔδϝϞϦ UnityଆͰ࢖༻͞ΕΔɻ UnityࣗମΛ࣮ߦ͢ΔC++ͷͨΊͷ 
 ϝϞϦϨΠϠʔͰ͋Γɺ 
 ௚઀৮Δػձ͸͋·Γͳ͍ɻ ωΠςΟϒϝϞϦ ຊ೔ղઆ͢Δͷ͸ 
 ϚωʔδϝϞϦ಺Ͱͷ࿩
  4. ϚωʔδϝϞϦʹ͸3ͭͷछྨ͕ଘࡏ͠ɺ͜ΕΒ͸RAM಺ʹอଘ͞ΕΔɻ ϝϞϦͷछྨ Unity͕؅ཧͯ͠ΔϝϞϦʹ͍ͭͯ ελοΫ ώʔϓ ωΠςΟϒVM 
 ϝϞϦ (Ϛωʔδυώʔϓ) OS͕؅ཧ͢Δখ͞

    ͳϝϞϦɻ ΞϓϦͷॳظԽஈ֊ ͰׂΓ౰ͯΒΕɺα Πζ͸มߋෆՄɻ ϥϯλΠϜʢMono, IL2CPPʣ͕؅ཧ͢ ΔϝϞϦɻ αΠζ͸࣮ߦ࣌ʹՄ มɻ ίʔυੜ੒Λߦ͏ ίʔυΛ࢖༻͢Δࡍ ʹ࢖༻͢ΔϝϞϦɻ ීஈ͸ҙࣝ͢Δ͜ͱ ͸͋·Γແ͍ɻ
  5. ελοΫͱώʔϓ Unity͕؅ཧͯ͠ΔϝϞϦʹ͍ͭͯ ελοΫ ࢀরܕͷΫϥεͳͲͷதͰ 
 એݴ͞Ε͍ͯͳ͍஋ܕͷม਺ ߏ଄ମɺྻڍܕ ώʔϓϝϞϦ಺ͷΦϒδΣΫτͷΞυϨε stackallocͰ֬อͨ͠഑ྻ ࢀরܕͷม਺

    (഑ྻɺΫϥεɺσϦήʔ τɺΦϒδΣΫτɺจࣈྻ) ϘοΫεԽ͞Εͨ஋ܕΦϒδΣΫτ ϥϜμࣜΛؚΉແ໊ؔ਺಺ͷΩϟϓνϟ͞ Εͨม਺ staticม਺ ώʔϓ (Ϛωʔδυώʔϓ) ։ൃऀ͕ओʹ৮Δͷ͸ελοΫͱώʔϓɻͦΕͧΕओʹ࣍ͷσʔλΛ֨ೲ͢Δɻ
  6. Φϑηοτ جຊͷϝϞϦϨΠΞ΢τ intܕͷΫϥεม਺܈Λఆٛ͠ɺΠϯελϯεԽͨ͠৔߹ʢϝϞϦϨΠΞ΢τॱং͸Ұ୴ߟྀ͠ͳ͍ʣ public class Hoge { public int a;

    public int b; public int c; } ΫϥεHogeͷ Πϯελϯε int c; int b; int a; +0x08 +0x04 +0x00 ઌ಄ΞυϨε͔Βͷ ڑ཭ʢΦϑηοτʣ
  7. ܧঝ࣌ͷΦϑηοτ جຊͷϝϞϦϨΠΞ΢τ ୯७ͳܧঝΛߦͬͨΫϥεCͷ৔߹ɺίϯύΠϧ࣌ˍϦϯΫ࣌ʹؔ਺܈ͷΞυϨεΛܭࢉ͢Δɻ 
 ΫϥεCΠϯελϯεͷϝϞϦׂΓ౰ͯߏ੒͸ҎԼͷΑ͏ͳܗʹͳΔɻ public class A { public

    void HogeA() { … } } public class B : A { public void HogeB() { … } } public class C : B { public void HogeC() { … } } ΫϥεCͷΦϒδΣΫτ ΫϥεCͷ৘ใ ΫϥεBͷ৘ใ ΫϥεAͷ৘ใ this(࠷ॳ͸ઌ಄Λࢦ͢)
  8. ֓ཁ vtableʹ͍ͭͯ ܕʹґଘͨؔ͠਺ݺͼग़͠ΛʮԾ૝ؔ਺ςʔϒϧ : virtual method table(vtable)ʯΛ࢖༻ͯ͠ղܾ͢Δɻ ͜Ε͸֘౰Ϋϥεʹؔ࿈͢ΔԾ૝ؔ਺ͷϙΠϯλΛ·ͱΊͨ΋ͷɻ গͳ͘ͱ΋ҰͭͷԾ૝ϝιουΛ࣋ͭ৔߹ɺ֤Ϋϥε޲͚ʹಠࣗͷvtable͕࡞੒͞ΕΔɻ public

    class Base { public virtual int GetId() { … } } public class A : Base { public override int GetId() { … } } public class B : A { public new int GetId() { … } } ΫϥεBaseͷΦϒδΣΫτ ΫϥεBaseͷ৘ใ ΫϥεBase༻ͷvtable ΫϥεAͷΦϒδΣΫτ ΫϥεBaseɾΫϥεAͷ৘ใ ΫϥεA༻ͷvtable ΫϥεBͷΦϒδΣΫτ ΫϥεBaseɾΫϥεAɾΫϥεBͷ৘ใ ΫϥεB༻ͷvtable
  9. public class Base { public virtual int GetId() { …

    } } public class A : Base { public override int GetId() { … } } public class B : A { public new int GetId() { … } } ΫϥεBͷΦϒδΣΫτ ΫϥεBaseɾΫϥεAɾΫϥεBͷ৘ใ ΫϥεB༻ͷvtable ྫ͑͹ΫϥεBͷςʔϒϧ৘ใΛݟΔͱɺoverrideͨ͠GetId()Λ࣋ͭAଆͷؔ਺ϙΠϯλͱɺ newͰΫϥεB༻ʹ࠶ఆٛͨ͠GetId()ͷؔ਺ϙΠϯλ͕֨ೲ͞Ε͍ͯΔɻ A:GetId() B:GetId() vtableͷྫ vtableʹ͍ͭͯ
  10. σϝϦοτ Ծ૝ؔ਺อ࣋ΫϥεͷΠϯελϯε͸ vtable΁ΞΫηε͢Δ༻ͷϙΠϯλ͕ ҉໧Ͱઌ಄ʹ௥Ճ͞Εɺ গ͚ͩ͠αΠζ͕େ͖͘ͳΔɻ ΠϯελϯεαΠζͷ૿Ճ Ծ૝ؔ਺ͷݺͼग़͠͸vtableܦ༝ͰߦΘΕ ΔͨΊɺ͔ᷮʹύϑΥʔϚϯεϩε͕ى͜ Δɻ͜Ε͸ඇৗʹখ͍͞΋ͷͰ͸͋Δ͕ɺ 


    1ϑϨʔϜʹԿઍճ΋ݺͼग़͢ܗʹͳΔͱɺ ͙͢ʹΦʔόʔϔου͕ੵΈॏͳΔɻ ύϑΥʔϚϯεϩε Ծ૝ؔ਺ͷ࢖༻ʹΑͬͯύϑΥʔϚ ϯε͕ଛͳΘΕͯ΋ɺͦΕ͕ݪҼͩ ͱಥ͖ࢭΊΔͷ͸೉͍͠ɻ ࠷ॳ͔ΒϦεΫΛ೦಄ʹஔ͍ͯ࢖͏ ඞཁ͕͋Δɻ ϓϩϑΝΠϦϯάͷ೉қ౓ vtableʹ͍ͭͯ
  11. ࢀߟࢿྉ C++ͰֶͿʂϝϞϦϨΠΞ΢τͱvtableͷ͢ʍΊ ʙಈతϙϦϞϑΟζϜΛ࣮ݱ͢Δ࢓૊Έʙ Unity ύϑΥʔϚϯενϡʔχϯά όΠϒϧ Memory Management in Unity

    Unity 2021 LTSͰϝϞϦͷ࢖͍ํΛΧελϚΠζ͢Δ Unity ͷϝϞϦʢެࣜϦϑΝϨϯεʣ ʲUnityʳUnsafeUtilityʹ͍ͭͯవΊͯΈΔ UnityͷGC͸ͲΜͳ࣮૷ʹͳ͍ͬͯΔͷ͔ VIRTUAL, NEW AND OVERRIDE IN C# [ࡶه]ଟॏܧঝͰ͖ͳ͍ཧ༝ ήʔϜΤϯδϯΞʔΩςΫνϟ ୈ3൛