Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Утечка памяти на tmemorystream.Create / 15 сообщений из 15, страница 1 из 1
26.11.2017, 17:28:55
    #39559643
SinfuL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
Добрый день!
Получаю из БД изображение, передаю в jpeg и отдаю наружу из функции через MemoryStream.
При анализе EurekaLog, получаю сообщение об утечке памяти на строке с tmemorystream.Create

Коллеги, подскажите, пожалуйста, почему может быть утечка.
Заранее всем спасибо.

Вот код функции:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
function get_photo(db_host,db_name,db_user,db_pass,db_port:string):tmemorystream;
var
 FDC:TFDConnection;
 FDQ:TFDQuery;
 bst:TFDBlobStream;
 jpeg: TJPEGImage;
begin
  FDC:=TFDConnection.Create(nil);
  FDQ:=TFDQuery.Create(nil);
  FDC.LoginPrompt:=False;

  jpeg:=TJPEGImage.Create;

  with FDC do
    begin
      Connected:=False;
      Params.Clear;
      Params.Append('DriverID=MySQL');
      Params.Append('Server='+db_host);
      Params.Append('Port='+db_port);
      Params.Append('Database='+db_name);
      Params.Append('User_Name='+db_user);
      Params.Append('Password='+db_pass);
      Params.Append('CharacterSet=utf8');

      try
        try
          Connected:=True;

          FDQ.SQL.Clear;
            FDQ.SQL.Add('Тут запрос в БД');
          FDQ.Connection:=FDC;
          FDQ.Active:=True;

          //получаем фото из БД
          bst:=TFDBlobStream.Create(TBlobField(FDQ.Fields[0]),bmRead);
          //передаем в jpeg 
          jpeg.LoadFromStream(bst);
          
          //отдаем наружу
          Result:=tmemorystream.Create; //EurekaLog говорит, что утечка здесь
          jpeg.SaveToStream(Result); 
        finally
          Connected:=False;
          bst.Free;
          jpeg.Free;
          FDC.Free;
          FDQ.Free;
        end;
      except
        on e: Exception do
          Writeln(f_log,TimeToStr(Now())+' Ошибка при получении фото из БД! '+
          'EMessage: '+E.Message);
      end;
  end;
end;
...
Рейтинг: 0 / 0
26.11.2017, 17:36:51
    #39559646
чччД
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
SinfuL,
Ты не освободил помять после использования TMemoryStream.
Т.е., не в функции ошибка. А там, где используются ее результаты.
...
Рейтинг: 0 / 0
26.11.2017, 17:38:15
    #39559648
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
SinfuL
Код: pascal
1.
bst:=TFDBlobStream.Create


1. До сюда может и не дойти, зато потом в finally ты будешь пытаться освободить мусорный объект bst. Заnilи его перед try.
2. Это не утечка, а выделение. Ты где-то потом не освобождаешь возвращенных этой функцией объект.
...
Рейтинг: 0 / 0
26.11.2017, 17:40:46
    #39559649
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
тут все надо переписать... обработка исключений - на уровне нуба. зачем сохранять jpeg, если он, уже сохраненный, лежит в соседнем потоке? функцию подключения вообще вынести отдельно - наверняка, она не 1 раз используется в жизни
...
Рейтинг: 0 / 0
26.11.2017, 17:45:07
    #39559652
SinfuL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
чччД,

вот функция(она занимается отправкой изображения на ftp-сервер), в которую я отправляю результат предыдущей и освобождаю память.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
function put_files_ftp(ftp_host,ftp_user,ftp_pass,ftp_port,ch_directory:string):boolean;
var
  ftp:TIdFTP;
  name_file:string;
  st:tmemorystream;
begin
Result:=False;

  ftp:=TIdFtp.Create(nil);

  with ftp do
  begin
    Host:=ftp_host;
    Port:=StrToInt(ftp_port);
    Username:=ftp_user;
    Password:=ftp_pass;
    Passive:=true;
  end;

  try
    try
      ftp.Connect;
      ftp.TransferType := ftBinary;

      if ch_directory<>'' then ftp.ChangeDir(ch_directory);

      //получаем поток для отправки
      st:=get_photo(host_db,name_db,user_db,pass_db,port_db);
      st:=foto_resize(st);

      //отправляем сформированный поток
      ftp.Put(st,name_file,False);

      Result:=True;
    finally
      ftp.Disconnect;
      ftp.Free;
      FreeAndNil(st);   //<<Здесь я освобождаю память
    end;
  except
    on E: EIdException do
      begin
        Writeln(f_log,TimeToStr(Now())+' Ошибка Indy при отправке файла '+name_file+' на FTP-сервер! '+
        'EIdMessage: '+E.Message);
      end;
    on E: Exception do
      begin
        Writeln(f_log,TimeToStr(Now())+' Ошибка VCL при отправке файла '+name_file+' на FTP-сервер! '+
        'EMessage: '+E.Message);
      end;
  end;
end;
...
Рейтинг: 0 / 0
26.11.2017, 17:48:23
    #39559653
SinfuL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
YuRock,

привел функцию, в которой освобождаю память. Поэтому и не понимаю, где собака порылась(
По пн.1 спасибо, учту.
...
Рейтинг: 0 / 0
26.11.2017, 17:48:55
    #39559654
SinfuL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
fd00ch,

а по существу вопроса есть предложения?
...
Рейтинг: 0 / 0
26.11.2017, 17:49:18
    #39559655
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
SinfuLПоэтому и не понимаю, где собака порылась(вангую, что тут))SinfuL
Код: pascal
1.
st:=foto_resize(st);
...
Рейтинг: 0 / 0
26.11.2017, 17:49:32
    #39559656
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
Ставлю на
SinfuL
Код: pascal
1.
st:=foto_resize(st);
...
Рейтинг: 0 / 0
26.11.2017, 17:49:50
    #39559657
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
SinfuL, и with еще выкинуть из стартовой функции
...
Рейтинг: 0 / 0
26.11.2017, 17:51:38
    #39559658
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
ну и возвращать из той же стартовой функции, наверняка, можно bst
...
Рейтинг: 0 / 0
26.11.2017, 17:52:34
    #39559659
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
SinfuL,

И в этой ф-ции так же st будет мусорным при любом эскепшене до создания.
Секунду. Компилятор обязан давать соответствующие варнинги. Ты что, их вообще не читаешь или отключил?
...
Рейтинг: 0 / 0
26.11.2017, 17:54:48
    #39559661
SinfuL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
Ставка сработала! Спасибо.
Пошел учить мат.часть и читать ворнинги.
Всем спасибо!
...
Рейтинг: 0 / 0
26.11.2017, 17:55:57
    #39559662
чччД
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
"Говнокод" - ©.
...
Рейтинг: 0 / 0
26.11.2017, 20:10:58
    #39559712
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Утечка памяти на tmemorystream.Create
Давно я не брал в руки шашки
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
function CreateConnect(const db_host, db_name, db_user, db_pass, db_port: String): TFDConnection;
begin
  Result := TFDConnection.Create(nil);
  try
    Result.LoginPrompt:=False;
    Result.Params.Clear;
    Result.Params.Append('DriverID=MySQL');
    Result.Params.Append('Server='+db_host);
    Result.Params.Append('Port='+db_port);
    Result.Params.Append('Database='+db_name);
    Result.Params.Append('User_Name='+db_user);
    Result.Params.Append('Password='+db_pass);
    Result.Params.Append('CharacterSet=utf8');
    Result.Connected:=True;
  except
    Result.Free;
    raise;
  end;
end;

procedure get_photo(AConnect: TFDConnection; AStrm: TStream);
var
   FDQ:TFDQuery;
   bst:TStream;
begin
  try
    FDQ := TFDQuery.Create(nil);
    try
      FDQ.Connection := AConnect;
      FDQ.SQL.Text := 'Тут запрос в БД';
      FDQ.Active:=True;
      //получаем фото из БД
      bst := FDQ.CreateBlobStream(FDQ.Fields[0], bmRead);
      try
        AStrm.CopyFrom(bst, 0);
      finally
        bst.Free;
      en d;
    finally
      FDQ.Free;
    end;
  except
    on E: Exception do
      raise Exception.Create('Ошибка при получении фото из БД! '+
          'EMessage: '+E.Message);
  end;
end;

function put_files_ftp(ftp_host,ftp_user,ftp_pass,ftp_port,ch_directory:string):boolean;
var
  ftp: TIdFTP;
  name_file: string;
  FDC: 
  st: TStream;
begin
  try
    ftp:=TIdFtp.Create(nil);
    try
      ftp.Host := ftp_host;
      ftp.Port := StrToInt(ftp_port);
      ftp.Username := ftp_user;
      ftp.Password := ftp_pass;
      ftp.Passive := True;
      ftp.Connect;
      ftp.TransferType := ftBinary;
      if ch_directory<>'' then ftp.ChangeDir(ch_directory);

      FDC := CreateConnect();
      try
        //получаем поток для отправки
        st  := TMemoryStream.Create;
        try
          get_photo(FDC, st);
           foto_resize(st);
          //отправляем сформированный поток
          st.Position := 0;
          ftp.Put(st, name_file, False);
          Result:=True;
        finally
          st.Free;
        end;
      finally
        FDC.Free;
      end;
    finally
      ftp.Free;
    end;
  except
    on E: EIdException do
      begin
        Writeln(f_log,TimeToStr(Now())+' Ошибка Indy при отправке файла '+name_file+' на FTP-сервер! '+
        'EIdMessage: '+E.Message);
        Result := False;
      end;
    on E: Exception do
      begin
        Writeln(f_log,TimeToStr(Now())+' Ошибка VCL при отправке файла '+name_file+' на FTP-сервер! '+
        'EMessage: '+E.Message);
        Result := False;
      end;
  end;
end;

...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Утечка памяти на tmemorystream.Create / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]