Размещенные и потерянные объекты |
Важно понять, что область памяти становится предметом для сбора мусора, как только ее счетчик ссылок становится равным нулю (это означает, что ни один объект типа GCPtr не указывает на эту область). Совсем необязательно объекту типа GCPtr, который первоначально на нее указывал, выходить за пределы области видимости. Вы можете использовать один объект типа GCPtr для указания на любое число динамически размещенных объектов с помощью последовательных присваиваний ему новых значений. Потерянная или забытая память (discarded memory) будет периодически очищаться сборшиком мусора. В листинге 2.4 приведен пример подобного распределения памяти. |^^^инг 2.4. Размещение и потеря объектов #include <iostream> #include <new> . #include "gc.h" using namespace std; intmainO { try { // Распределяет и теряет объекты. GCPtr<int> р = new int(l); p = new int(2); p = new int(3); p = new int(4); // Для демонстрационных целей вручную собираются // неиспользуемые объекты. GCPtr<int>::collect(); cout « "*р: " « *р « endl; } catch(bad_alloc exc) { cout « "Allocation failure!\n"; return 1; } return 0; } Далее приведен вывод программы при включенном режиме отображения. Constructing GCPtr. before garbage collection for gclist<int, 0>: lneniJ>tr refcount value 1002F1310] 1 4 66__Глава 2 [002F1300] О 3 [002F12D0] О 2 [002F12A0] О 1 Deleting: 3 Deleting: 2 Deleting: 1 After garbage collection for gclist<int, 0>: memPtr refcount value [002F1310] 1 4 *p: 4 GCPtr going out of scope. Before garbage collection for gclist<int, 0>: memPtr refcount value [002F1310] 0 4 Deleting: 4 After garbage collection for gclist<int, 0>: memPtr refcount value — Empty — В программе объекту p типа GCPtr<int> по очереди присваивается указатель на 4 отдельных участка динамической памяти, инициализированных с разными значениями. Далее вызывается функция collect (), которая запускает сбор мусора. Обратите внимание на содержимое списка gciist: три его элемента помечены как неактивные, и только элемент, указывающий на память, выделенную последней, до сих пор используется. Далее неактивные элементы списка удаляются. В конце концов, программа завершается, объект р выходит за пределы области видимости и последний элемент списка уничтожается. Обратите внимание на то, что у первых трех фрагментов динамической памяти, на которые указывает объект р, нулевые счетчики ссылок. Это результат работы перегруженной операции присваивания. Когда объекту GCPtr присваивается новый адрес, счетчик ссылок для его текущего значения уменьшается. Еще одно замечание: так как объект р инициализируется при объявлении, в списке gclisc не формируется ни одного элемента с пустым адресом. Напоминаю, что подобный элемент создается, только если объект GCPtr объявляется без начального значения.
|