සියලුම GC ක්රියාවට නැංවීම සඳහා සුදුසු ක්රමයක් පිළිබඳව ඔබට සැබවින්ම හිස් ප්රකාශ කළ නොහැක . ඒවා වල් වෙනස් වේ. ඒ නිසා මම මුලින් සඳහන් කළ .NET එක සමඟ කතා කරන්නම්.
ඕනෑම තර්කනයකින් හෝ හේතුවක් ඇතිව මෙය සිදු කිරීම සඳහා ඔබ GC හි හැසිරීම ඉතා සමීපව දැන සිටිය යුතුය.
එකතු කිරීම පිළිබඳ මට ඇති එකම උපදෙස නම්: එය කිසි විටෙකත් නොකරන්න.
GC හි සංකීර්ණ තොරතුරු ඔබ සැබවින්ම දන්නේ නම්, ඔබට මගේ උපදෙස් අවශ්ය නොවන බැවින් එය වැදගත් නොවේ. ඔබ දැනටමත් 100% විශ්වාසයෙන් නොදන්නේ නම් එය උපකාරී වනු ඇති අතර, සබැඳිව බලා මෙවැනි පිළිතුරක් සොයා ගත යුතුය : ඔබ GC.Collect අමතන්න එපා , හෝ විකල්පයක් ලෙස: GC ක්රියා කරන ආකාරය පිළිබඳ විස්තර ඉගෙන ගැනීමට ඔබ යා යුතුය ඇතුළත සහ පිටත, එවිට පමණක් ඔබ පිළිතුර දැන ගනු ඇත .
GC . භාවිතා කිරීම අර්ථවත් කරන එක් ආරක්ෂිත ස්ථානයක් තිබේ .
GC.Collect යනු ඔබට දේවල් පැතිකඩ කිරීම සඳහා භාවිතා කළ හැකි API එකකි. ප්රති al ල මඟ හැරෙන විට ඔබේ දෙවන ඇල්ගොරිතමයේ ජී.සී.
මේ ආකාරයේ පැතිකඩ යනු ඕනෑම කෙනෙකුට අතින් එකතු කිරීමට මා යෝජනා කරන එකම අවස්ථාවයි.
කෙසේ වෙතත් විවාදාත්මක උදාහරණය
භාවිතා කළ හැකි එක් අවස්ථාවක් නම්, ඔබ සැබවින්ම විශාල දේ පටවනවා නම්, ඒවා විශාල වස්තු ගොඩක කෙලින්ම Gen 2 වෙතට යනු ඇත, නමුත් නැවත Gen 2 දිගුකාලීන වස්තූන් සඳහා වන අතර එය අඩුවෙන් එකතු වේ. කිසියම් හේතුවක් නිසා ඔබ කෙටිකාලීන වස්තූන් Gen 2 වෙත පටවන බව ඔබ දන්නේ නම් , ඔබේ Gen 2 කුඩා කර තබා ගැනීම සඳහා ඔබට ඒවා ඉක්මණින් ඉවත් කළ හැකි අතර එය එකතු කිරීම වේගවත් වේ.
මට ඉදිරිපත් කළ හැකි හොඳම උදාහරණය මෙය වන අතර එය හොඳ නැත - ඔබ මෙහි ගොඩනඟන LOH පීඩනය වැඩි වාර ගණනක් එකතු කිරීමට හේතු වනු ඇත, සහ එකතු කිරීම් නිතර නිතර සිදු වේ - එය LOH ඉවත් කිරීමට ඉඩ ඇති අවස්ථා ඔබ තාවකාලික වස්තූන් සමඟ එය පුපුරවා හරින විට වේගයෙන්. GC ට වඩා හොඳ එකතු කිරීමේ සංඛ්යාතයක් ඇතැයි මම විශ්වාස නොකරමි - මට වඩා බොහෝ දක්ෂ පුද්ගලයින් විසින් සුසර කර ඇත .
එබැවින් .NET GC හි සමහර අර්ථකථන හා යාන්ත්රණ ගැන කතා කරමු ... හෝ ..
.NET GC ගැන මම දන්නවා යැයි සිතන සෑම දෙයක්ම
කරුණාකර, මෙහි වැරදි සොයා ගන්නා ඕනෑම අයෙක් - මාව නිවැරදි කරන්න. ග්රාම නිලධාරියාගෙන් බොහෝ දෙනෙක් කළු මැජික් බව ප්රකට ය. මා අවිනිශ්චිත තොරතුරු පිට කිරීමට උත්සාහ කරන අතරේ, සමහර විට මට සමහර දේවල් වැරදී ඇත.
පහත දැක්වෙන්නේ මා නොදන්නා බොහෝ තොරතුරු මෙන්ම මා නොදන්නා වඩා විශාල තොරතුරු සමූහයකි. ඔබේම අවදානමකින් මෙම තොරතුරු භාවිතා කරන්න.
GC සංකල්ප
.NET GC නොගැලපෙන වේලාවන්හිදී සිදු වේ, එබැවින් එය "නිර්ණායක නොවන" ලෙස හැඳින්වේ, මෙයින් අදහස් කරන්නේ ඔබට නිශ්චිත වේලාවක එය සිදුවීමට විශ්වාසය තැබිය නොහැකි බවයි. එය පරම්පරාගත කසළ එකතු කරන්නෙකු ද වන අතර එයින් අදහස් කරන්නේ ඔබේ වස්තූන් ඔවුන් ජීවත්වූ GC පාස් ගණනට කොටස් කරන බවයි.
Gen 0 ගොඩවල ඇති වස්තු එකතු 0 ක් හරහා ජීවත් වී ඇති අතර මේවා අලුතින් සාදන ලද අතර මෑතකදී ඒවා ස්ථාපනය කිරීමෙන් පසු කිසිදු එකතුවක් සිදුවී නොමැත. ඔබේ Gen 1 සංචයේ ඇති වස්තූන් එක් එකතු කිරීමේ මුරපදයක් හරහා ජීවත් වී ඇති අතර, ඒ හා සමානව ඔබේ Gen 2 ගොඩවල ඇති වස්තු එකතු කිරීමේ පාස් 2 ක් හරහා ජීවත් වී ඇත.
දැන් එය මෙම නිශ්චිත පරම්පරාවන් සහ කොටස් ඒ අනුව සුදුසුකම් ලැබීමට හේතුව සඳහන් කිරීම වටී. .NET GC විසින් හඳුනාගනු ලබන්නේ මෙම පරම්පරා තුන පමණි, මන්ද මෙම ගොඩවල් තුන ඉක්මවා යන එකතුකිරීම් සියල්ලම තරමක් වෙනස් ය. සමහර වස්තූන් එකතු කිරීම දහස් වාරයක් නොනැසී පැවතිය හැකිය. GC හුදෙක් මේවා Gen 2 ගොඩවල් කොටසේ අනෙක් පැත්තේ තබයි, ඒවා ඇත්ත වශයෙන්ම Gen 44 වන බැවින් ඒවා තවදුරටත් කොතැනක හෝ බෙදා හැරීමේ තේරුමක් නැත; ඒවා මත එකතු කිරීමේ අවසරය Gen 2 ගොඩවල ඇති සියල්ලටම සමාන වේ.
මෙම විශේෂිත පරම්පරාවන්ට අර්ථකථන අරමුණු මෙන්ම මේවාට ගරු කරන ක්රියාත්මක කරන ලද යාන්ත්රණ ද ඇත, මම මොහොතකට ඒවා ලබා ගනිමි.
එකතුවක ඇති දේ
GC එකතු කිරීමේ මුරපදයක මූලික සංකල්පය නම්, මෙම වස්තූන් සඳහා සජීවී යොමු කිරීම් (GC මූලයන්) තවමත් තිබේදැයි බැලීමට එය එක් එක් වස්තුව ගොඩවල් අවකාශයක පරීක්ෂා කිරීමයි. වස්තුවක් සඳහා GC root සොයාගත හොත්, එයින් අදහස් කරන්නේ දැනට ක්රියාත්මක වන කේතය තවමත් එම වස්තුව වෙත ළඟා වී භාවිතා කළ හැකි බැවින් එය මකා දැමිය නොහැකි බවයි. කෙසේ වෙතත්, වස්තුවක් සඳහා GC මූලයක් සොයාගත නොහැකි නම්, එයින් අදහස් වන්නේ ධාවන ක්රියාවලියට තවදුරටත් වස්තුව අවශ්ය නොවන බැවින් නව වස්තු සඳහා මතකය නිදහස් කිරීම සඳහා එය ඉවත් කළ හැකි බවයි.
දැන් එය අවසන් වූ පසු වස්තු පොකුරක් පිරිසිදු කර සමහරක් තනිවම තැබීමෙන් අවාසනාවන්ත අතුරු ආබාධයක් ඇති වනු ඇත: මියගිය අය ඉවත් කරන ලද සජීවී වස්තූන් අතර නිදහස් අවකාශ පරතරයන්. මෙම මතක ඛණ්ඩනය හුදකලා වුවහොත් හුදෙක් මතකය නාස්ති වනු ඇත, එබැවින් එකතු කිරීම් සාමාන්යයෙන් "සම්පීඩනය" යනුවෙන් හැඳින්වෙන දේ කරනු ඇත, එහිදී ඔවුන් ඉතිරිව ඇති සියලුම සජීවී වස්තූන් ගෙන ඒවා ගොඩවල් එකට මිරිකා ගනී. 0.
දැන් මතක ගොඩවල් 3 ක් පිළිබඳ අදහස ලබා දී ඇති අතර, ඒවා සියල්ලම ඔවුන් ජීවත් වී ඇති එකතු කිරීමේ පාස් ගණන අනුව කොටස් කර ඇත, මෙම කොටස් පවතින්නේ මන්ද යන්න ගැන කතා කරමු.
Gen 0 එකතුව
Gen 0 නිරපේක්ෂ නවතම වස්තූන් වීම ඉතා කුඩා වේ - එබැවින් ඔබට එය ආරක්ෂිතව නිතර එකතු කර ගත හැකිය . සංඛ්යාතය සංචය කුඩා බව සහතික කරන අතර එකතු කිරීම් ඉතා වේගවත් බැවින් ඒවා කුඩා ගොඩකට වඩා එකතු වේ. මෙය වැඩි වැඩියෙන් හෝ අඩුවෙන් පදනම් වී ඇත්තේ: ඔබ විසින් නිර්මාණය කරන ලද තාවකාලික වස්තූන්ගෙන් බහුතරයක් ඉතා තාවකාලික ය, එබැවින් තාවකාලික ඒවා තවදුරටත් භාවිතයට ගැනෙන්නේ නැත.
Gen 1 එකතුව
එබී නැති බව ජෙනරාල් 1 ආම්පන්න ඉතා වස්තූන් තාවකාලික ප්රවර්ගය තවමත් තරමක් කෙටි ජීවත් විය හැක, ම still- විශාල කොටසක් නිර්මාණය කිරීමට සඳහා භාවිතා නොවන විරුද්ධ නිසා. එම නිසා Gen 1 නිතර නිතර එකතු කරයි, නැවතත් එය ගොඩවල් කුඩා ලෙස තබා ගනිමින් එකතු කිරීම වේගවත් වේ. කෙසේ වෙතත් උපකල්පනය අඩු එය අඩු නිතර ජෙනරාල් වඩා එකතු එය ගේ වස්තු, ජෙනරාල්, 0 ට වඩා තාවකාලික 0
ඔවුන් එකතු කරන සංඛ්යාතය හැර වෙනත් කිසිවක් තිබේ නම්, ජෙනරල් 0 හි එකතු කිරීමේ අවසර පත්රය සහ ජෙනරල් 1 අතර වෙනස් වන තාක්ෂණික යාන්ත්රණ මම නොදනිමි.
Gen 2 එකතුව
ජෙනරල් 2 දැන් සියලු ගොඩවල් වල මව විය යුතුයි නේද? හොඳයි, ඔව්, එය අඩු හෝ වැඩි වශයෙන් නිවැරදි ය. ඔබගේ ස්ථිර වස්තූන් සියල්ලම වාසය කරන්නේ එයයි - Main()
නිදසුනක් ලෙස ඔබේ ජීවිත වස්තුව , සහ සඳහන් කරන සෑම දෙයක්ම ඔබේ ක්රියාවලිය අවසානයේදී නැවත පැමිණෙන Main()
තෙක් මුල් බැස ඇති බැවිනි Main()
.
Gen 2 යනු අනෙකුත් පරම්පරාවන්ට එකතු කර ගත නොහැකි සෑම දෙයක් සඳහාම බාල්දියක් බැවින්, එහි වස්තූන් බොහෝ දුරට ස්ථීර හෝ අවම වශයෙන් දිගු කලක් ජීවත් වේ. එබැවින් Gen 2 හි ඇති දේවලින් ඉතා සුළු ප්රමාණයක් හඳුනා ගැනීම ඇත්ත වශයෙන්ම එකතු කළ හැකි දෙයක් වනු ඇත, එයට නිතර එකතු කිරීමට අවශ්ය නොවේ. මෙමඟින් එය එකතු කිරීම මන්දගාමී වීමට ඉඩ සලසයි. එබැවින් මෙය මූලික වශයෙන් ඔවුන් අමුතු අවස්ථා සඳහා වන සියලු අමතර හැසිරීම් වලට සම්බන්ධ වී ඇත, මන්ද ඒවා ක්රියාත්මක කිරීමට ඔවුන්ට කාලය තිබේ.
විශාල වස්තු ගොඩවල්
Gen 2 හි අමතර හැසිරීම් වලට එක් උදාහරණයක් නම්, එය විශාල වස්තු සංචය මත එකතු කිරීම ද සිදු කරයි. මේ වන විට මම කුඩා වස්තු සංචය ගැන මුළුමනින්ම කතා කළෙමි, නමුත් .NET ධාවන කාලය නිශ්චිත ප්රමාණයේ දේවල් වෙනම ගොඩකට වෙන් කරයි. කුඩා වස්තු සංචය මත එකතු කිරීම් අවසන් වූ විට සංයුතිය සඳහා වස්තූන් චලනය කිරීම අවශ්ය වේ. Gen 1 හි ජීවමාන 10mb වස්තුවක් තිබේ නම්, එය එකතු කිරීමෙන් පසු සම්පීඩනය සම්පූර්ණ කිරීමට බොහෝ කාලයක් ගතවනු ඇත, එමඟින් Gen 1 හි එකතුව මන්දගාමී වේ. එම නිසා 10mb වස්තුව විශාල වස්තු සංචිතයට වෙන් කර ඇති අතර එය ඉතා කලාතුරකින් ධාවනය වන Gen 2 අතරතුර එකතු කරනු ලැබේ.
අවසන් කිරීම
තවත් උදාහරණයක් වන්නේ අවසන් කරන්නන් සහිත වස්තූන් ය. .NETs GC (කළමනාකරණය නොකළ සම්පත්) විෂය පථයෙන් ඔබ්බට සම්පත් යොමු කරන වස්තුවක් සඳහා ඔබ අවසාන කාරකයක් තබයි. කළමනාකරණය නොකළ සම්පතක් එක්රැස් කිරීම සඳහා GC වෙත ලැබෙන එකම ක්රමය අවසාන කාරකයයි - කළමනාකරණය නොකළ සම්පත ඔබේ ක්රියාවලියෙන් කාන්දු නොවන බවට වග බලා ගැනීම සඳහා අතින් එකතු කිරීම / ඉවත් කිරීම / මුදා හැරීම සිදු කිරීම සඳහා ඔබ ඔබේ අවසන් යන්ත්රය ක්රියාත්මක කරයි. GC විසින් ඔබේ වස්තූන් අවසන් කිරීමේ ක්රියාවලිය සිදු කළ විට, ඔබේ ක්රියාත්මක කිරීම මඟින් කළමනාකරණය නොකළ සම්පත ඉවත් කරනු ඇති අතර, සම්පත් කාන්දු වීමකින් තොරව ඔබේ වස්තුව ඉවත් කිරීමට GC සමත් වේ.
අවසන් කරන්නන් මෙය කරන යාන්ත්රණය වන්නේ අවසන් පෝලිම්වල කෙලින්ම යොමු කිරීමයි. ධාවන කාලය අවසන් වස්තුවක් සමඟ වස්තුවක් වෙන් කළ විට, එය එම වස්තුවට අවසන් පෝලිමට දර්ශකයක් එක් කරන අතර ඔබේ වස්තුව තැනින් තැන අගුලු දමයි (පින් කිරීම ලෙස හැඳින්වේ) එබැවින් සම්පීඩනය එය චලනය නොකරනු ඇත. එකතු කිරීමේ මුරපද සිදු වන විට, අවසානයේදී ඔබේ වස්තුව තවදුරටත් GC මූලයක් නොමැති බව සොයා ගනු ඇත, නමුත් එය එකතු කිරීමට පෙර අවසන් කිරීම ක්රියාත්මක කළ යුතුය. එබැවින් වස්තුව මිය ගිය විට, එකතුව විසින් එහි යොමු කිරීම අවසන් පෝලිමේ සිට ගෙන "ෆ්රීචබල්" පෝලිම් ලෙස හැඳින්වෙන දේ වෙත යොමු කිරීමක් කරනු ඇත. එකතු කිරීම දිගටම කරගෙන යයි. අනාගතයේ තවත් "නිර්ණායක නොවන" වේලාවක, ෆයිනලයිසර් නූල් ලෙස හැඳින්වෙන වෙනම නූලක් ෆ්රීචබල් පෝලිම් හරහා ගොස් යොමු කරන ලද එක් එක් වස්තුව සඳහා අවසාන සැකසුම් ක්රියාත්මක කරයි. එය අවසන් වූ පසු, නිදහස් කළ හැකි පෝලිම් හිස් වන අතර, එය අවසන් කිරීම අවශ්ය නොවන බව පවසන සෑම වස්තුවකම ශීර්ෂකය මත එය ටිකක් පෙරළී ඇත (මෙම බිට් එක අතින් පෙරළා දැමිය හැකියGC.SuppressFinalize
එය Dispose()
ක්රම වල පොදු වේ ), එය වස්තූන් ඉවත් කර ඇති බවට ද මම සැක කරමි , නමුත් ඒ ගැන මා උපුටා දක්වන්න එපා. මෙම වස්තුව ඇති ඕනෑම ගොඩක් මතට එන ඊළඟ එකතුව අවසානයේ එය එකතු කරයි. Gen 0 එකතුකිරීම් මඟින් අවසන් කිරීමට අවශ්ය බිට් ඔන් කර ඇති වස්තූන් කෙරෙහි පවා අවධානය යොමු නොකරයි, එය ස්වයංක්රීයව ඒවා ප්රවර්ධනය කරයි. ජෙනරල් 1 හි අවසන් කිරීම අවශ්ය නොවන වස්තුවක් FReachable
පෝලිමේ විසි කරනු ඇත, නමුත් එකතුව ඒ සමඟ වෙනත් කිසිවක් නොකරයි, එබැවින් එය ජෙනරල් 2 වෙත ජීවත් වේ. මේ ආකාරයෙන්, අවසන්කරණයක් ඇති සියලුම වස්තූන්, සහ එසේ නොකරන්න GC.SuppressFinalize
Gen 2 හි එකතු කරනු ලැබේ.