2014-01-20 3 views
0

У меня есть эта процедура:Утечка памяти с помощью Delphi

procedure TMainForm.ExtractActor(const actor_id : string); 
var 
    mystream : TStringStream; 
    js : TlkJSONobject; 
begin 
    mystream:= TStringStream.Create(''); 
    idHTTP1.Get(TIdURI.URLEncode('some dynamic url'),mystream);            
    js := TlkJSON.ParseText(mystream.DataString) as TlkJsonObject; 
    //insert 
    if UniConnection1.Connected then 
    begin 
     UniQuery3.Params[0].Value:= StrToInt(js.getString('id')); 
     UniQuery3.Open; 
     if (UniQuery3.RecordCount = 0) then 
     begin 
     Uniquery2.Params[0].Value:= StrToInt(js.getString('id')); 
     Uniquery2.Params[1].Text:= js.getString('name'); 
     Uniquery2.Params[2].Text:= js.getString('locale'); 
     Uniquery2.Params[3].Text:= js.getString('gender'); 
     Uniquery2.Params[4].Text:= js.getString('username'); 
     Uniquery2.Execute; 
     end; 
     UniQuery3.Close; 
    end; 
    mystream.Free; 
end; 

мониторинга диспетчера задач Windows я вижу, что память процесс продолжает расти. Через день или около того я получу ошибку из памяти, и приложение выйдет из строя. Что я делаю не так? Я предполагаю, что ни библиотеки JSON, ни Devart UniDAC не протекают.

ответ

6

Существует несколько очевидных причин утечки.

Тот, который, несомненно, является утечкой, является объектом, который вы создаете, но не уничтожаете. Защитить свою жизнь с блоком try/finally:

js := TlkJSON.ParseText(mystream.DataString) as TlkJsonObject; 
try 
    ... 
finally 
    js.Free; 
end; 

Более деликатным является незащищенным mystream. Если исключение возникает после того, как назначено mystream, и до его уничтожения вы пропустите этот объект. Снова вы должны защитить это с помощью блока try/finally, используя ту же самую идиому, как показано выше. Проблема с mystream будет только проблемой для вас, если ваша функция создает исключения. Хотя это может быть не так, вы должны всегда защищать объекты таким образом, как показано выше.

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

  1. Измените свой код, чтобы он использовал полную версию FastMM.
  2. Настройте файл конфигурации FastMM для полной отладки. Это может потребовать редактирования файла .inc, и если вы найдете это слишком сложным, вы можете использовать утилиту GUI здесь: http://jed-software.com/blog/?p=606
  3. Запустите свою программу на некоторое время, а затем закройте ее. Если у вас есть утечки, об этом следует сообщить в этот момент.
  4. Исправить все утечки.

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

+2

Спасибо. Но если исключение произошло без блока try, это приведет к сбою приложения, и это будет видно. Он работает нормально хотя бы на день. В конце концов он остановится, и я получу окно с сообщением «Out of memory» после его закрытия. –

+2

@MiguelE Прочитайте часть о 'js'. Кроме того, пожалуйста, не просто исправить это, а затем забыть о утечках. Добавьте полную отладку FastMM и исправьте их все. Утечки подобны Покемону. –

+0

@MiguelE "_Но если исключение произошло без блока try, это приведет к сбою приложения, и оно будет видимым. _" ... Если вы не сделали что-то специально, чтобы приложение врезалось, это неверно. При обработке исключений по умолчанию текущая операция будет остановлена, и пользователь увидит сообщение об ошибке; приложение продолжит работу. Фактически, пользователь даже не увидит сообщение об ошибке, если исключение ** является ** класса EAbort. –

Смежные вопросы