Share
Embed
Unity+C#で学ぶ! メモリレイアウトとvtableのすゝめ 〜動的ポリモーフィズムを実現する仕組み〜
Unityで開発する際にはメモリ周りについて考える方も多いでしょう。
今回はそのメモリに対して焦点を当てて、Unityでのメモリがどのようにレイアウトされているのか、また動的ポリモーフィズムがどのように実現されているのかを、図を用いてなるべくわかりやすい形で解説致します。
Kutani Mio
January 27, 2023
Transcript
22 slides
-
Unity+C#ͰֶͿʂ ϝϞϦϨΠΞτͱ vtableͷ͢ʍΊ CA.unity #6 2023-02-03 Ζͬ͞Ή
(Mio Kutani) ʙಈతϙϦϞʔϑΟζϜΛ࣮ݱ͢ΔΈʙ -
Introduce myself ABOUT ME ΠʔϒΠ͕͖ͳήʔϜΤϯδχΞͰ͢ɻ ͱ͋ΔήʔϜձࣾʹͯɺ ϦʔυΫϥΠΞϯτΤϯδχΞΛ୲ɻ ࠷ۙ࠾༻ͱϚωδϝϯτ͕ଟΊɻ
෭ۀͰϝλόʔεܥ͕ϝΠϯͰ͢ɻ Ζͬ͞Ή εΩϧηοτ Unity C# 5͘Β͍ (2D, 3Dʑ) Unreal Engine C++ 3(झຯࠐΈ) Jenkins͓͞Μͨ͠Γ ӳޠษڧͨ͠Γ 2018.3ʙ2022.3 MSMVPͰͨ͠ -
C#ଆͰ༻͞ΕΔɻ OSଆɺMono·ͨIL2CPPʹΑͬͯ ϝϞϦͷ֬อɾղ์͕ࣗಈతʹ ཧ͞ΕΔϝϞϦϨΠϠʔɻ ϚωʔδϝϞϦ ϝϞϦͷछྨ Unity͕ཧͯ͠ΔϝϞϦʹ͍ͭͯ C#ଆͰ༻͞ΕΔɻ JobSystemBurstΛ༻͢Δࡍʹ
͜ͷϝϞϦϨΠϠʔΛ͏ɻ ϝϞϦͷ֬อɾղ์ࣗݾͰߦ͏ɻ C#ͷΞϯϚωʔδϝϞϦ UnityଆͰ༻͞ΕΔɻ UnityࣗମΛ࣮ߦ͢ΔC++ͷͨΊͷ ϝϞϦϨΠϠʔͰ͋Γɺ ৮Δػձ͋·Γͳ͍ɻ ωΠςΟϒϝϞϦ -
C#ଆͰ༻͞ΕΔɻ OSଆɺMono·ͨIL2CPPʹΑͬͯ ϝϞϦͷ֬อɾղ์͕ࣗಈతʹ ཧ͞ΕΔϝϞϦϨΠϠʔɻ ϚωʔδϝϞϦ ϝϞϦͷछྨ Unity͕ཧͯ͠ΔϝϞϦʹ͍ͭͯ C#ଆͰ༻͞ΕΔɻ JobSystemBurstΛ༻͢Δࡍʹ
͜ͷϝϞϦϨΠϠʔΛ͏ɻ ϝϞϦͷ֬อɾղ์ࣗݾͰߦ͏ɻ C#ͷΞϯϚωʔδϝϞϦ UnityଆͰ༻͞ΕΔɻ UnityࣗମΛ࣮ߦ͢ΔC++ͷͨΊͷ ϝϞϦϨΠϠʔͰ͋Γɺ ৮Δػձ͋·Γͳ͍ɻ ωΠςΟϒϝϞϦ ຊղઆ͢Δͷ ϚωʔδϝϞϦͰͷ -
ϚωʔδϝϞϦʹ3ͭͷछྨ͕ଘࡏ͠ɺ͜ΕΒRAMʹอଘ͞ΕΔɻ ϝϞϦͷछྨ Unity͕ཧͯ͠ΔϝϞϦʹ͍ͭͯ ελοΫ ώʔϓ ωΠςΟϒVM ϝϞϦ (Ϛωʔδυώʔϓ) OS͕ཧ͢Δখ͞
ͳϝϞϦɻ ΞϓϦͷॳظԽஈ֊ ͰׂΓͯΒΕɺα ΠζมߋෆՄɻ ϥϯλΠϜʢMono, IL2CPPʣ͕ཧ͢ ΔϝϞϦɻ αΠζ࣮ߦ࣌ʹՄ มɻ ίʔυੜΛߦ͏ ίʔυΛ༻͢Δࡍ ʹ༻͢ΔϝϞϦɻ ීஈҙࣝ͢Δ͜ͱ ͋·Γແ͍ɻ -
ελοΫͱώʔϓ Unity͕ཧͯ͠ΔϝϞϦʹ͍ͭͯ ελοΫ ࢀরܕͷΫϥεͳͲͷதͰ એݴ͞Ε͍ͯͳ͍ܕͷม ߏମɺྻڍܕ ώʔϓϝϞϦͷΦϒδΣΫτͷΞυϨε stackallocͰ֬อͨ͠ྻ ࢀরܕͷม
(ྻɺΫϥεɺσϦήʔ τɺΦϒδΣΫτɺจࣈྻ) ϘοΫεԽ͞ΕͨܕΦϒδΣΫτ ϥϜμࣜΛؚΉແ໊ؔͷΩϟϓνϟ͞ Εͨม staticม ώʔϓ (Ϛωʔδυώʔϓ) ։ൃऀ͕ओʹ৮ΔͷελοΫͱώʔϓɻͦΕͧΕओʹ࣍ͷσʔλΛ֨ೲ͢Δɻ -
ελοΫͷϝϦοτɾσϝϦοτ Unity͕ཧͯ͠ΔϝϞϦʹ͍ͭͯ ελοΫ ϝϞϦσʔλͷΞΫηεߴɻ OSଆͰϝϞϦΛݫີʹཧ͍ͯ͠Δͨ ΊɺϝϞϦͷஅยԽͳͲΛ͙ɻ มʹܕͷൣғ֎ͷ͕ೖΔͱྫ֎ൃੜɻ ελοΫࣗମͷϝϞϦྔ͕গͳ͍ͨΊɺ ͍ͬͨ߹ʹྫ֎ൃੜɻ ελοΫͱώʔϓ
void Main() { int a; int b = 4; int c = b; } int a; int b; int c; void Main() { int a; int b = 4; int c = b; int d = 0; } int a; int b; int c; int d; before after +1 -
ॊೈੑ͕ߴ͘ɺඞཁͳΛਵ࣌֬อՄೳɻ GCʹΑͬͯࣗಈཧ͞ΕΔͨΊɺϝϞϦ ͷഁଛΤϥʔΛ࠷খݶʹ͑ΒΕΔɻ GCଆͰ༻ࡁΈϝϞϦͷཧ·Ͱ ߦͬͯ͘Εͳ͍ͨΊɺஅยԽ͕ى͖Δɻ ϝϞϦσʔλͷΞΫηεɻ ώʔϓ (Ϛωʔδυώʔϓ) ώʔϓͷϝϦοτɾσϝϦοτ Unity͕ཧͯ͠ΔϝϞϦʹ͍ͭͯ
ελοΫͱώʔϓ ΫϥεA ΦϒδΣΫτB ྻD จࣈྻE ϝϞϦஅยԽྫ จࣈྻ(ղ์ࡁΈ) ྻ(ղ์ࡁΈ) ΦϒδΣΫτF(ղ์ࡁΈ) ΦϒδΣΫτF(ղ์ࡁΈ) ΦϒδΣΫτF ҎԼͷαΠζͷ σʔλΛ֨ೲՄೳ -
Φϑηοτ جຊͷϝϞϦϨΠΞτ ࢀরܕͷม (ྻɺΫϥεɺσϦήʔ τɺΦϒδΣΫτɺจࣈྻ) ϘοΫεԽ͞ΕͨܕΦϒδΣΫτ ϥϜμࣜΛؚΉແ໊ؔͷΩϟϓνϟ͞ Εͨม staticม ώʔϓ
(Ϛωʔδυώʔϓ) Ϋϥε༻ͷϝϞϦώʔϓ্ʹ֬อ͞ΕΔɻ -
Φϑηοτ جຊͷϝϞϦϨΠΞτ intܕͷΫϥεม܈Λఆٛ͠ɺΠϯελϯεԽͨ͠߹ʢϝϞϦϨΠΞτॱংҰ୴ߟྀ͠ͳ͍ʣ public class Hoge { public int a;
public int b; public int c; } ΫϥεHogeͷ Πϯελϯε int c; int b; int a; +0x08 +0x04 +0x00 ઌ಄ΞυϨε͔Βͷ ڑʢΦϑηοτʣ -
ܧঝ࣌ͷΦϑηοτ جຊͷϝϞϦϨΠΞτ ୯७ͳܧঝΛߦͬͨΫϥε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(࠷ॳઌ಄Λࢦ͢) -
جຊͷϝϞϦϨΠΞτ ΫϥεCͷΦϒδΣΫτ͔ΒΫϥεBͰ࣮͍ͯ͠ΔHogeB()Λݺͼग़͢ࡍʹɺ thisϙΠϯλΛBͷΦϒδΣΫτ෦Ҡಈͤͯ͞ɺΫϥεBͷϙΠϯλΛಘΔඞཁ͕͋Δɻ ͦ͜ͰɺΫϥεC͕࣋ͭΫϥεB༻ͷΦϑηοτΛࢀরͯ͠ɺϙΠϯλΛͣΒ͢ɻ ΫϥεCͷΦϒδΣΫτ ΫϥεCͷใ ΫϥεBͷใ ΫϥεAͷใ this +
ΫϥεB༻ͷΦϑηοτ ΫϥεCͷઌ಄ΞυϨε void Main() { var C = new C(); c.HogeB(); } ܧঝ࣌ͷΦϑηοτ -
֓ཁ 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 -
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ʹ͍ͭͯ -
σϝϦοτ Ծؔอ࣋ΫϥεͷΠϯελϯε vtableΞΫηε͢Δ༻ͷϙΠϯλ͕ ҉Ͱઌ಄ʹՃ͞Εɺ গ͚ͩ͠αΠζ͕େ͖͘ͳΔɻ ΠϯελϯεαΠζͷ૿Ճ Ծؔͷݺͼग़͠vtableܦ༝ͰߦΘΕ ΔͨΊɺ͔ᷮʹύϑΥʔϚϯεϩε͕ى͜ Δɻ͜Εඇৗʹখ͍͞ͷͰ͋Δ͕ɺ
1ϑϨʔϜʹԿઍճݺͼग़͢ܗʹͳΔͱɺ ͙͢ʹΦʔόʔϔου͕ੵΈॏͳΔɻ ύϑΥʔϚϯεϩε Ծؔͷ༻ʹΑͬͯύϑΥʔϚ ϯε͕ଛͳΘΕͯɺͦΕ͕ݪҼͩ ͱಥ͖ࢭΊΔͷ͍͠ɻ ࠷ॳ͔ΒϦεΫΛ೦಄ʹஔ͍ͯ͏ ඞཁ͕͋Δɻ ϓϩϑΝΠϦϯάͷқ vtableʹ͍ͭͯ -
ࢀߟࢿྉ C++ͰֶͿʂϝϞϦϨΠΞτͱvtableͷ͢ʍΊ ʙಈతϙϦϞϑΟζϜΛ࣮ݱ͢ΔΈʙ Unity ύϑΥʔϚϯενϡʔχϯά όΠϒϧ Memory Management in Unity
Unity 2021 LTSͰϝϞϦͷ͍ํΛΧελϚΠζ͢Δ Unity ͷϝϞϦʢެࣜϦϑΝϨϯεʣ ʲUnityʳUnsafeUtilityʹ͍ͭͯవΊͯΈΔ UnityͷGCͲΜͳ࣮ʹͳ͍ͬͯΔͷ͔ VIRTUAL, NEW AND OVERRIDE IN C# [ࡶه]ଟॏܧঝͰ͖ͳ͍ཧ༝ ήʔϜΤϯδϯΞʔΩςΫνϟ ୈ3൛