Unityで開発する際にはメモリ周りについて考える方も多いでしょう。 今回はそのメモリに対して焦点を当てて、Unityでのメモリがどのようにレイアウトされているのか、また動的ポリモーフィズムがどのように実現されているのかを、図を用いてなるべくわかりやすい形で解説致します。
Unity+C#ͰֶͿʂϝϞϦϨΠΞτͱ vtableͷ͢ʍΊCA.unity #6 2023-02-03 Ζͬ͞Ή (Mio Kutani)ʙಈతϙϦϞʔϑΟζϜΛ࣮ݱ͢ΔΈʙ
View Slide
Introduce myselfABOUT MEΠʔϒΠ͕͖ͳήʔϜΤϯδχΞͰ͢ɻͱ͋ΔήʔϜձࣾʹͯɺ ϦʔυΫϥΠΞϯτΤϯδχΞΛ୲ɻ࠷ۙ࠾༻ͱϚωδϝϯτ͕ଟΊɻ ෭ۀͰϝλόʔεܥ͕ϝΠϯͰ͢ɻΖͬ͞ΉεΩϧηοτUnity C# 5͘Β͍ (2D, 3Dʑ)Unreal Engine C++ 3(झຯࠐΈ) Jenkins͓͞Μͨ͠Γӳޠษڧͨ͠Γ2018.3ʙ2022.3 MSMVPͰͨ͠
ࠓճͷεϥΠυͷݩهࣄhttps://qiita.com/4_mio_11/items/aa71f18b24ab55e4cb3d
ContentsUnity͕ཧͯ͠ΔϝϞϦʹ͍ͭͯϝϞϦͷछྨελοΫͱώʔϓجຊͷϝϞϦϨΠΞτΦϑηοτܧঝ࣌ͷΦϑηοτvtableʹ͍ͭͯ֓ཁσϝϦοτ
Unity͕ཧͯ͠Δ ϝϞϦʹ͍ͭͯ
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;beforeafter+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ʹ͍ͭͯ
֓ཁ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 UnityUnity 2021 LTSͰϝϞϦͷ͍ํΛΧελϚΠζ͢ΔUnity ͷϝϞϦʢެࣜϦϑΝϨϯεʣʲUnityʳUnsafeUtilityʹ͍ͭͯవΊͯΈΔUnityͷGCͲΜͳ࣮ʹͳ͍ͬͯΔͷ͔VIRTUAL, NEW AND OVERRIDE IN C#[ࡶه]ଟॏܧঝͰ͖ͳ͍ཧ༝ήʔϜΤϯδϯΞʔΩςΫνϟ ୈ3൛
͝ਗ਼ௌ༗͏ޚ࠲͍·ͨ͠ʂ