FastMM сообщает об утечке памяти для переменной потока записи

FastMM сообщает об утечке памяти (UnicodeString) для следующего фрагмента кода, который использует переменную потока записи со строкой:

program Project10;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  FastMM4,
  System.SysUtils;

type
  TContext = record
    Value : String;
  end;

threadvar
  Context : TContext;

begin
Context.Value := 'asdfsdfasfdsa';
end.

Это настоящая утечка памяти или просто происходит очистка переменных потока после того, как FastMM проверит утечки памяти?

Еще более важно: как я могу подавить эти "утечки памяти", о которых сообщают, поскольку они загромождают любые другие утечки памяти, которые могут быть найдены?

2 ответа

Решение

Это настоящая утечка. Локальные переменные потока не завершаются, когда они выходят из области видимости. Поскольку ваша запись содержит управляемое поле, строковое поле, выделенная память кучи, связанная с этой строкой, просачивается, если запись не завершена.

В документации это явно выражено:

Динамические переменные, которыми обычно управляет компилятор (длинные строки, широкие строки, динамические массивы, варианты и интерфейсы), могут быть объявлены с помощью threadvar, но компилятор не освобождает автоматически выделенную память, создаваемую каждым потоком выполнения. Если вы используете эти типы данных в переменных потока, вы обязаны распоряжаться их памятью внутри потока до его завершения.

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

Finalize(Context);

Обратите внимание, что вы должны выполнить этот код из потока, которому принадлежит переменная, поскольку, очевидно, только тот поток имеет к нему доступ.

Если вы хотите подавить сообщение об этих утечках, тогда вызовите RegisterExpectedMemoryLeak.

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

Может показаться странным, что вы утверждаете, что не можете выполнять код при завершении потоков. Если вы не можете сделать это, как вы можете выполнить любой код в контексте этих потоков. Другими словами, чтобы произошла утечка, вы, должно быть, выполнили свой код в этих потоках.

Создайте глобальный массив TContext, а затем сохраните индекс элемента, принадлежащего вашему потоку, в потоке переменных.

Другие вопросы по тегам