медленное освобождение памяти (пересчитанная структура) - хороший ли способ обхода? - PullRequest
3 голосов
/ 19 октября 2011

в моей программе я могу загрузить каталог: ICatalog

Каталог здесь содержит множество пересчитанных структур (коллекции IItems, IElements, IRules и др.)

когда я хочу перейти в другой каталог, Я загружаю новый каталог но автоматическое освобождение предыдущего экземпляра ICatalog требует времени, замораживая мое приложение на 2 секунды или более.

мой вопрос:

Я хочу отложить выпуск старого (и более не использованного) экземпляра ICatalog в другой поток.

Я еще не проверял это, но я намереваюсь создать новую тему с:

ErazerThread.OldCatalog := Catalog; // old catalog refcount jumps to 2
Catalog := LoadNewCatalog(...);     // old catalog refcount =1
ErazerThread.Execute;               //just set OldCatalog to nil.

таким образом, я ожидаю, что релиз произойдет в потоке, а мое приложение не быть замороженным больше.

Это безопасно (и хорошая практика)?
У вас есть примеры существующего кода, уже выполняющего выпуск аналогичным методом?

Ответы [ 2 ]

2 голосов
/ 19 октября 2011

Я бы позволил такому потоку заблокироваться в какой-нибудь поточно-безопасной очереди (*) и выдвинул интерфейсы для выпуска в эту очередь как iunknowns.

Обратите внимание, однако, что если освобождение касается блокировки, которую использует ваш менеджер памяти (например, глобальная блокировка heapmanager), то это бесполезно, поскольку ваша основная тема блокируется при первом доступе к heapmanager.

С помощью heapmanager с пулами для каждого потока выделение множества элементов в одном потоке и освобождение его в другом потоке может помешать объединению и повторному использованию (небольших) блоков алгоритмов.

Я все еще думаю, что описанный вами способ, как правило, звучит правильно при правильной реализации. Но это с теоретической точки зрения, чтобы показать, что может быть ссылка из 2-го потока на основную тему через heapmanager.

(*) Самый простой способ - добавить его в список тем и использовать tevent, чтобы указать, что элемент был добавлен.

2 голосов
/ 19 октября 2011

Это выглядит нормально, но не вызывайте метод потока Execute напрямую; он будет запускать код объекта потока в потоке current вместо того, который создается объектом потока. Звоните Start или Resume вместо.

...