Вверх ↑
Ответов: 4621
Рейтинг: 746
#1: 2017-05-12 17:03:04 ЛС | профиль | цитата
Предлагаю подумать на такую тему. Вот в компоненте COMEX есть такой код:


function THICOMEX.CloseCom;
begin
result := false;
if Assigned(thrd) then
begin
thrd.Terminate; // <<<<<<<<<<<<<<<<<<<<<<<
thrd.WaitFor;
free_and_nil(thrd);
end;
...
end;

function THICOMEX.ExecuteRd;
var
Signaled, BytesTrans, Err: DWORD;
BufferRd: string; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
FStat: TComStat1;
begin
while not Sender.Terminated do
begin
......................
if (FStat.cbInQue <> 0) then
begin
SetLength(BufferRd, FStat.cbInQue); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
ReadFile(hFile, BufferRd[1], FStat.cbInQue, BytesTrans, @OvrRd);
if GetOverlappedResult(hFile, OvrRd, BytesTrans, True) then
begin
ReadStr := BufferRd + #0;
SetLength(ReadStr, BytesTrans);
_hi_onEvent(_event_onRead, ReadStr);
if Assigned(_event_onSyncRead.Event) then Sender.Synchronize(SyncExecRd);
end;
end;
.....................
end;
PurgeComm(hFile, PURGE_RXCLEAR);
Result := 0;
end;

Когда порт открывается, создаётся параллельный поток, в котором выполняется метод THICOMEX.ExecuteRd(). В процессе работы этот метод выделяет память для строки (SetLength(BufferRd, FStat.cbInQue)). Если этот метод завершит свое исполнение (до последнего end), то выделенную под эту строку память Delphi удалит автоматически. Но когда мы закрываем порт, мы делаем THICOMEX.CloseCom(), в котором выполняется thrd.Terminate(). Этот метод тупо прекращает исполнение метода THICOMEX.ExecuteRd() и он никогда не дойдёт до end. Куда девается память, выделенная под строку? Аналогичное происходит, если Terminate() произошло в момент вызова событий из этого метода (_hi_onEvent(_event_onRead, ReadStr)), только память остаётся занятой от строк, которые были выделены в компонентах, подключенных к данному событию. И не только строк, а, например, если в обрабатывающем компоненте создаётся объект PStream, который должен быть освобожден после выдачи его в поток, но этого не происходит, так как исполнение создавшего его метода прерывается.

Какое решение должно применяться для избежания этой проблемы?

Отвечать смогу в понедельник. А кто в теме - пообсуждайте, пожалуйста.
карма: 26

0
Редактировалось 2 раз(а), последний 2017-05-12 17:54:28