Сбор мусора с помощью функции collectQ |
В функции collect о реализована непосредственная операция очистки неиспользуемой памяти. Далее приводится код функции. // Сбор мусора. Возвращает true, если хотя бы // один объект был удален, template <class T, int size> bool GCPtr<T, size>::collect() { bool memfreed = false; #ifdef DISPLAY cout « "Before garbage collection for "; showlistO ; #endif list<GCInfo<T> >::iceracor p; do { // Просматривает gclist для обнаружения указателей, ни на что не // ссылающихся. for(p = gciist.begin(); p != gciist.end(); p++) { // Если используется, то пропускается, if(p->refcount > 0) continue; memfreed = true; // Удаляет неиспользуемый элемент из списка gciist. gciist.remove(*р); // Освобождает память, пока GCPtr не станет равным null, if (p->memPtr) { if(p->isArray) { #ifdef DISPLAY cout « "Deleting array of size " « p->arraySize « endl; #endif delete[] p->memPtr; // удаляет массив } else { #ifdef DISPLAY cout « "Deleting: " « *(T *) p->memPtr « "\n"; #endif delete p->memPtr; // удаляет одиночный элемент } } // Возобновляет поиск, break; } } while(р != gciist.end()); #ifdef DISPLAY cout « "After garbage collection for "; showlistO ; #endif return memfreed; } функция collect о ищет в списке gclist элементы, чье поле ref count равно нулю. Когда такой элемент найден, он удаляется из списка gclist с помощью вызова функции removeo, которая является членом класса list библиотеки STL. Затем память, связанная с этим элементом списка, освобождается. Напоминаю, что в языке С++ одиночные объекты уничтожаются с помощью операции delete, а массивы — с помощью операции delete [ ]. Таким образом, значение поля isArray удаляемого элемента списка определяет, какая из названных операций применяется для очистки памяти. Это одна из причин, по которой вы должны задавать размер массива в любом объекте класса GCPtr, который указывает на массив, при этом поле isArray получает значение true. Если оно не установлено корректно, невозможно должным образом освободить выделенную память. Хотя задача сбора мусора — очистка памяти в автоматическом режиме, вы можете, если необходимо, отчасти управлять этим процессом вручную. Функцию collect о можно вызвать прямо из пользовательского кода, потребовав выполнить сбор мусора. Обратите внимание, она описана в классе GCPtr как статическая функция. Это значит, что для ее вызова не нужна ссылка на какой-либо объект. GCPtr<int>::collect(); //собирает все неиспользуемые указатели типа int Приведенная строка вызовет сбор мусора в списке gclist<int>. Поскольку существуют разные списки gclist для различных типов указателей, следует вызывать функцию collect о для каждого списка, в котором нужно собрать мусор. Откровенно говоря, если вы хотите тщательно контролировать удаление динамически размещенных объектов, лучше воспользоваться системой распределения памяти вручную, реализованной в языке С++. Прямой вызов функции collect о больше всего подходит для особых ситуаций, например, при неожиданном дефиците свободной памяти.
|