Некоторые особенности при работе с BSTRING и ASTRING

Думаю всем будет полезно узнать, что при использовании типа BSTRING в группах/очередях/классах надо запомнить следующее правило:

  • если группа/очередь/класс объявлены в глобальных данных, то в конце программы надо ОБЯЗАТЕЛЬНО ставить Clear(GROUP/CLASS). В случае использования очереди надо ОБЯЗАТЕЛЬНО пройтись по каждой записи и или очистить ее всю или сделать Clear() полям BSTRING.
  • если группа/очередь/класс объявлены как локальные для процедуры, то в конце процедуры надо выполнить аналогичные действия как и для глобальной.

В случае использования BSTRING в очередях, ОБЯЗАТЕЛЬНО надо чистить всю запись или поля BSTRING перед удалением записи из очереди.

Невыполнение данных рекомендаций повлечет за собой потерю памяти, выделенной для полей BSTRING. Накопление потерянной памяти будет происходить каждый раз при входе/выходе в/из процедуры, где используется локальная группа/класс/очередь с полями BSTRING.

Все дело в том, что разработчики допустили небольшую оплошность. При описании поля BSTRING как одиночной переменной, в конце программной секции, где объявлена такая переменная, компилятор обязательно автоматом ставит код для освобождения памяти, занятой полями BSTRING. Но, при вставке полей BSTRING в группу/класс/очередь, компилятор очевидно теряет такие переменные из поля своего зрения и не генерит для них код автоматического освобождения занятой ими памяти!

Таких предосторожностей не требует использование переменных типа ASTRING, так как RTL сама ведет учет всей памяти, выделенной при использовании таких переменных.

Но и здесь есть своя тонкость!
Специфика ASTRING заключается в том, что при присвоении таким переменным нового значения, прежнее ее значение не уничтожается а остается в памяти! Все указатели на такие кусочки памяти записываются во внутреннюю таблицу RTL. При присвоении полю ASTRING нового значения, сначала выполняется поиск в этой таблице. Если найдена строка, совпадающая с новым значением поля, данному полю просто присваивается указатель на уже имеющуюся строку. При завершении программы, RTL сама чистить всю эту память.

Отсюда видно, что бесконтрольное и частое изменение значений таких переменных (особенно — неповторяющимися) может привести к большому расходу памяти, а то и к ее нехватке!