Въведение
Най-простата стратегия за събиране на боклука е преброяването на препратки. Преброяването на препратките е много просто, но е важно да отговаря на нуждите на компилатора и увеличава функцията за разпределяне на разходите (мутатор) на (този термин е за потребителската програма, от гледна точка на събирача на отпадъци). Всеки обект има свързан брой препратки - броят на активните препратки към обекта. Ако референтният брой на обекта е нула, тогава той е боклук (потребителската програма не може да го достигне) и може да бъде рециклиран. Модифициране на указатели при всяка препратка по време (като например чрез оператор за присвояване) или когато препратка е извън диапазона, компилаторът трябва да генерира код, за да актуализира броя на препратките на референтния обект. Ако броят на референтните обекти стане нула, той може да се стартира незабавно за възстановяване на този блок (броят на референтните данни на всички блокове и блокът се възстановява, за да се намали референцията) или да се събере при забавяне на опашката.
com компонентът ще поддържа стойност за препратка, към която се отнася. Когато клиентът придобие от интерфейсен компонент, това ще увеличи броя на препратките. Когато приключите с използването на клиентския интерфейс, модулът за преброяване на препратки Запазване 1. Когато стойността на броя на препратките е 0, компонентът може да бъде изтрит от собствената памет.
използване на преброяване на препратки
Защопричина
Да изберете да поддържате отделна препратка към всеки преброител на интерфейса, а не броя препратки за целия сбор, за да го поддържате?
Има две основни причини: Първо, улеснете отстраняването на грешки; Друга причина е изискването за достъп до ресурси за поддръжка.
1 отстраняване на грешки:
предположенията забравят извикване на Release интерфейси (всъщност много хора правят тази грешка) в програмата. Такива компоненти никога няма да бъдат премахнати, тъй като това е само при броене на препратки 0:00 ще бъде извикано изтриване. След това трябва да разберете кога и къде интерфейсът трябва да бъде пуснат. Разбира се, много е трудно да се намери. В случай на само един интерфейс за поддържане на целия монтаж за такъв резултат е по-трудно да се намери. По това време всички интерфейси трябва да бъдат проверени с помощта на код, предоставен от този компонент. Въпреки това, ако компонентите се поддържат за всеки интерфейс, поддържа брой на препратки, можете да намерите набор от ограничения за конкретен интерфейс. В някои случаи това може да спести много време.
2. Снабдете се с необходимите ресурси
може да изисква много памет или други ресурси при внедряване на интерфейс. За този случай можете да завършите разпределението на ресурси, когато клиентът поиска този интерфейс при изпълнението на QueryInterface. Въпреки това, ако броят на препратките поддържа само целия сбор, компонентите не могат да определят кога е безопасно да се освободи част от тази памет, свързана с интерфейса. Но базовият преброен брой, поддържан отделно за всеки интерфейс, можете да решите кога да освободите тази памет ще бъде много по-лесно.
Guize
справка за правилно използване, отчитаща три прости правила
1. Tiaoyong AddRef преди връщане. За тези функции, които изграждат по-добре, връщат интерфейсен указател, преди да върнат съответния указател, трябва да извикат AddRef. Тези функции включват QueryInterface и CreateInstance. Така че, когато клиентът получи от такава интерфейсна функция. Няма да има нужда да извиква AddRef.
2. След използване на интерфейса след извикване на Release. След използване на интерфейс трябва да се нарича нещо Release функция интерфейс.
3. Извикайте AddRef след присвояването. Когато интерфейсен указател, присвоен на друг интерфейсен указател, трябва да извика AddRef. С други думи, след установяване на препратка извън интерфейса не трябва да се увеличава броят на препратките на съответния компонент.
Интерфейс
в клиентския изглед броят на препратките е на ниво интерфейс, а не на ниво компонент. Но от гледна точка на изпълнението, чийто брой на препратките се записва практически без връзка. Клиентите могат да повярват, че директният компонент ще записва всеки интерфейс сам по себе си, поддържайки брой референти. Но клиентът не може да приеме, че целият монтаж поддържа един брой препратки.
За клиентите всеки интерфейс е отделно поддържан брой препратки, което означава, че клиентите трябва да извикат AddRef, за да се използва указателят вместо всеки друг указател. За показалец над клиентите трябва да се обадят на своя Release.
изберете да поддържате отделна препратка към всеки брой на интерфейса, а не препратка към причините за поддръжката на целия сбор:
улесняват отстраняването на грешки; поискайте достъп до ресурси за поддръжка; < / p>
въвеждане в експлоатация
може да се постигне чрез увеличаване и намаляване на стойността на число.
Също така имайте предвид, че AddRef и Release връщаната стойност няма смисъл, но може да е полезно при отстраняване на грешки в програмата. Клиентите не трябва да използват тази стойност, тъй като това е точната препратка към номера на компонента или интерфейса.
правила
клиентските интерфейси трябва да се обработват като референтен брой за всеки интерфейс има отделен. Следователно клиентите трябва да препращат към броя поотделно за различните интерфейси, въпреки че тяхната продължителност на живота е вложена.
a, правилото за изходен параметър
означава, че изходните параметри към извикващия функцията връщат стойност на параметър на функция. От един час по отношение на ефекта, върнатата стойност на изходния параметър е подобна на същата функция. Всички изходни параметри, върнати като върната стойност или указател към новия интерфейс на някаква функция, трябва да бъдат интерфейсни указатели AddRer.
Второ, входните параметри на правилото
интерфейсен указател, предаван на функцията, без извикване на AddRef и Release, това е така, защото животът на вложената функция е в живота на повикващия.
Трето, правилото за входно-изходни параметри
Вход – Изходни параметри както входни параметри, така и изходни параметри на функцията. Функцията може да се използва в останалата част от входно-изходните стойности на параметрите, след което тези стойности могат да бъдат модифицирани и да ги връщат на повикващия.
във функцията за входно-изходни параметри, предадени в интерфейсния указател, трябва да извика Release, преди да го присвои на друга стойност на интерфейсния указател. Преди функцията да се върне, трябва да извикате изходните параметри на AddRef, съхранени в указателя на интерфейса.
Четвърто, правила за локални променливи
За актуален указател на домашен интерфейс, но само поради присъствието им в живота на неговата функция и следователно няма нужда да се обаждате на AddRef и Release. Това правило всъщност е пряк резултат от входните параметри на правилото. В следващия пример, pIX2 само във функцията foo lifetime, като по този начин се гарантира, че нейният живот ще бъде вложен в рамките на живота на входящия pIX указател, няма нужда да извиквате AddRef и Release на pIX2.
пет правила за глобални променливи
към интерфейсния указател, съхранен в глобалната променлива, преди да бъде предаден на друга функция, той трябва да извика AddRef. Тъй като тази променлива е глобална, всяка функция може да се използва за прекратяване на живота им чрез извикване на Release. За указателя на интерфейса, съхранен в членската променлива, той също трябва да се третира по този начин. Тъй като всички функции-членове на този клас са, състоянието на указателя на интерфейса може да бъде променено.
Шест правила
Когато не може да се определи за някаква несигурна ситуация, трябва да се извика AddRef и Release right.
Освен това, когато се определя да бъде оптимизиран, не трябва да има указатели към тези на броя на препратките със съответните коментари или други програмисти при модифициране на кода, това може да увеличи живота на указателя на интерфейса, като по този начин затваря оптимизацията на броя на препратките унищожени.
Грешка, забравете да извикате Release, причината може да доведе до по-трудно откриване, отколкото ако не извикате AddRef. Основното предимство в сравнение с проследяването на събирането на отпадъци
предимства и дефекти
, референтният брой на обекта вече не се използва, може да бъде възстановен възможно най-скоро, в същото време не води до дълга пауза в процеса на възстановяване, също така ясно маркиран жизнения цикъл на всеки обект.
в приложения в реално време или системи с ограничена памет, отзивчивостта в реално време е важен показател, а броячът на референтните данни е един от най-лесните за прилагане събиране на боклук, подходящ е за случая. Броят на препратките може също да се използва за управление на други ресурси, различни от паметта, като например обекта на операционната система (често по-оскъден от ресурсите на паметта). Технология за проследяване на събиране на отпадъци за справяне с такава цел с терминатор, но забавеното възстановяване може да доведе до други проблеми. Претеглянето се прилага към разпределени системи за изкуство, получени от референтния брой.
на наличната памет е запълнена с активна целева платформа, проследяването на събирането на отпадъци ще се задейства често, като по този начин ще се намали производителността. Референтният брой дори в случай на памет на ръба на изчерпването, производителността все още е защитена. Броят на препратките също и за други техники за оптимизация за предоставяне на референтна информация по време на изпълнение, например много системи за неизменен обект (напр. функционален език за програмиране), голям брой дублиращи се обекти може да доведе до сериозно нарушение на производителността; в такава система типичните мерки за оптимизация са: бъдещето, ако даден обект е създаден само веднъж и друг подобен обект е създаден в същото време, когато вече не се препраща към него (като оператор за присвояване на конкатенация на низове в Javascript), можете да изтриете оригиналният обект създава поведението на нов обект, променя оригиналния обект, като по този начин подобрява ефективността. Броят на препратките може да предостави достатъчно референтна информация за такава оптимизация.
оптимизиран брой препратки без проследяване в сравнение Събирането на боклука има два основни недостатъка, трябва да въведем допълнителни механизми за поправка:
-
често актуализиран брой препратки Това ще намали ефективността на работа.
-
проблемът с кръговия брой препратки не може да бъде разрешен. Пространствена локалност
Освен това, ако има свободно разпределение на паметта за списък, броят на препратките е много слаб. Използвайки само кеш паметта на процесора за преброяване на препратките, за да подобри производителността чрез преместване на обекти, високопроизводителният разпределител на памет ще приложи както проследяващ събирач на боклука, така че да подобри производителността. Много референтни реализации (като PHP и Objective-C) са с лоша производителност, защото не са реализирали копиране на паметта.