powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Утечка памяти на tmemorystream.Create
15 сообщений из 15, страница 1 из 1
Утечка памяти на tmemorystream.Create
    #39559643
SinfuL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Получаю из БД изображение, передаю в 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
Утечка памяти на tmemorystream.Create
    #39559646
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SinfuL,
Ты не освободил помять после использования TMemoryStream.
Т.е., не в функции ошибка. А там, где используются ее результаты.
...
Рейтинг: 0 / 0
Утечка памяти на tmemorystream.Create
    #39559648
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SinfuL
Код: pascal
1.
bst:=TFDBlobStream.Create


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

вот функция(она занимается отправкой изображения на 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
Утечка памяти на tmemorystream.Create
    #39559653
SinfuL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock,

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

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

И в этой ф-ции так же st будет мусорным при любом эскепшене до создания.
Секунду. Компилятор обязан давать соответствующие варнинги. Ты что, их вообще не читаешь или отключил?
...
Рейтинг: 0 / 0
Утечка памяти на tmemorystream.Create
    #39559661
SinfuL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ставка сработала! Спасибо.
Пошел учить мат.часть и читать ворнинги.
Всем спасибо!
...
Рейтинг: 0 / 0
Утечка памяти на tmemorystream.Create
    #39559662
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Говнокод" - ©.
...
Рейтинг: 0 / 0
Утечка памяти на tmemorystream.Create
    #39559712
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давно я не брал в руки шашки
Код: 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
15 сообщений из 15, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Утечка памяти на tmemorystream.Create
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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