Поверніть своє запитання. Справжнє мотивуючий питання полягає в тому, за яких обставин ми можемо уникнути витрат на вивезення сміття?
Ну, по- перше, те , що є витрати на збір сміття? Є дві основні витрати. По-перше, ви повинні визначити, що живе ; що вимагає потенційно багато роботи. По-друге, ви повинні ущільнити отвори , які утворюються, коли ви звільните щось, що було виділено між двома речами, які ще живі. Ці діри марнотратні. Але ущільнення їх теж дороге.
Як ми можемо уникнути цих витрат?
Зрозуміло, що якщо ви можете знайти схему використання сховища, в якій ніколи не виділяєте щось довготривале, потім виділяєте щось недовговічне, потім виділяєте щось довговічне, ви можете усунути вартість дірок. Якщо ви можете гарантувати, що для деякого підмножини вашої пам’яті кожен наступний розподіл буде коротшим, ніж попередній у цьому сховищі, то в цьому сховищі ніколи не буде жодних дірок.
Але якщо ми вирішили проблему з дірочками, то і ми вирішили проблему з вивезенням сміття . У вас є щось у тому сховищі, яке ще живе? Так. Чи було все виділено до того, як воно довгожило? Так - це припущення - це те, як ми усунули можливість дір. Тому все, що вам потрібно зробити, - сказати, "чи є останнім виділення в живих?" і ти знаєш, що в цьому сховищі все живе.
Чи є у нас набір асигнувань на зберігання, де ми знаємо, що кожне наступне виділення є короткочасним, ніж попереднє? Так! Кадри активації методів завжди руйнуються в тому зворотному порядку, як вони були створені, оскільки вони завжди короткочасні, ніж активація, яка їх створила.
Тому ми можемо зберігати рамки активації на стеку і знати, що їх ніколи не потрібно збирати. Якщо на стеці є якийсь кадр, весь набір фреймів під ним є довговічнішим, тому їх не потрібно збирати. І вони будуть знищені в тому зворотному порядку, як вони були створені. Таким чином, вартість вивезення сміття виключається для кадрів активації.
Ось чому ми маємо тимчасовий пул на стеці в першу чергу: тому що це простий спосіб здійснення активації методу без стягнення штрафу за управління пам'яттю.
(Звичайно, вартість сміття для збору пам'яті , на яку посилаються посилання на кадри активації, все ще є.)
Тепер розглянемо систему потоків управління, в якій кадри активації не руйнуються в передбачуваному порядку. Що станеться, якщо короткотривала активація може призвести до довготривалої активації? Як ви можете собі уявити, у цьому світі ви більше не можете використовувати стек, щоб оптимізувати необхідність збирання активацій. Набір активацій може знову містити отвори.
C # 2.0 має цю функцію у вигляді yield return
. Метод, який робить прибутковість, буде активовано пізніше - наступного разу, коли викликається MoveNext, - і коли це станеться, не передбачувано. Тому інформація, яка зазвичай знаходиться на стеку для активаційного кадру ітераторного блоку, замість цього зберігається на купі, де вона збирається сміттям під час збирання нумератора.
Аналогічно, функція "асинхронізування / очікування", що надходить у наступних версіях C # і VB, дозволить вам створити методи, активації яких "поступаються" та "поновлюються" у чітко визначених точках під час дії методу. Оскільки кадри активації більше не створюються та не руйнуються передбачувано, вся інформація, яка раніше зберігалася в стеку, повинна зберігатися в купі.
Це просто випадковий випадок історії, що ми випадково вирішили на кілька десятиліть, що мови з кадрами активації, які створені та знищені суворо впорядкованим чином, були модними. Оскільки сучасним мовам дедалі більше не вистачає цього властивості, сподівайтеся побачити все більше мов, які спрямовують продовження на збирання сміття, а не на стек.