Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];

Вниз

Программа "ест" память, потом сбой   Найти похожие ветки 

 
Pcrepair ©   (2011-06-30 17:58) [0]

Добрый день
Программа была написана для проверки работоспособности процедур компресии-декомпресии графического файла с использованием Zlib в Делфи2010

unit main;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, StdCtrls, Zlib;
type
 TForm1 = class(TForm)
   Button1: TButton;
   Image1: TImage;
   procedure Button1Click(Sender: TObject);
   procedure Compress;
   procedure DCompress;
 private
   { Private declarations }
 public
   { Public declarations }
 end;
var
 Form1: TForm1;
 pic1: TMemoryStream;
 pic2: TMemoryStream;
 pic3: TMemoryStream;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject); //при нажатии на кнопку
begin
 if FileExists(ExtractFilePath(Application.ExeName)+"\"+"s1.bmp") then
         DeleteFile(ExtractFilePath(Application.ExeName)+"\"+"s1.bmp");//удаляется файл
 pic1 := TMemoryStream.create;//создаются потоки
 pic2 := TMemoryStream.create;
 pic3 := TMemoryStream.create;
 pic1.LoadFromFile(ExtractFilePath(Application.ExeName)+"\"+"s.bmp");//в поток загружается файл с диска
 Compress;//файл сжимается  и передается в ПЕРЕМ pic2
 DCompress;//файл декомпрессируется и передается в pic3
 pic3.SaveToFile(ExtractFilePath(Application.ExeName)+"\"+"s1.bmp");//файл сохраняется на диск
 Image1.Picture.bitmap.LoadFromFile(ExtractFilePath(Application.ExeName)+"\"+"s1.bmp");//файл отображается в окне, для контроля

 pic1.Free;//уничтожение ПЕРЕМ
 pic2.Free;
 pic3.Free;

 end;

procedure TForm1.Compress;//процедура сжатия, не мое
var
 TmpStream : TMemoryStream;
 CmpStream : TCompressionStream;
begin
 TmpStream := TMemoryStream.Create;
 CmpStream := TCompressionStream.Create (clMax, TmpStream);
// application.ProcessMessages;
 pic1.Seek (0, 0);
 CmpStream.CopyFrom (pic1, pic1.Size);
 CmpStream.Free;
//  FCompressionRate := 100 - TmpStream.Size / _in.Size * 100;
 TmpStream.Position:=0;
 pic2.Position:=0;
 pic2.SetSize(TmpStream.Size);
 pic2.CopyFrom (TmpStream, TmpStream.Size);
 TmpStream.Free;
end;

procedure TForm1.DCompress;// процедура декомпресии, не мое
const
 BufSize = 1024;
var
 Buf : pointer;
 Readed : Integer;
 FDecompressedStream:TMemoryStream;
 DecompStream : TDecompressionStream;
begin
     pic2.Seek (0, 0);
       DecompStream := TDecompressionStream.Create(pic2);
       try
           FDecompressedStream := TMemoryStream.Create;
           GetMem (Buf, BufSize);
           try
             repeat
               Readed := DecompStream.read (Buf^, BufSize);
               if Readed > 0
                 then FDecompressedStream.Write (Buf^, Readed);
             until Readed <= 0;
           finally
             FreeMem (Buf, BufSize);
           end;
       finally
         DecompStream.Free;
       end;
       FDecompressedStream.Seek (0, 0);
       pic3.Seek (0, 0);
       pic3.CopyFrom(FDecompressedStream, FDecompressedStream.Size);
end;
end.


В общем программа работает, но при каждом нажатии на кнопку отбирает все больше памяти(4-12-20- и далее мб)
Все Переменные после использования уничтожаются
В чем может быть проблема?


 
Ega23 ©   (2011-06-30 18:45) [1]


> В чем может быть проблема?


В процедуре DCompress утечка памяти. Это то, что "блондинка" сходу увидела.
Но подсказывать не буду. Из принципа. :)
Не из вредности, а потому, что ты её должен найти сам.


 
Pcrepair ©   (2011-06-30 19:06) [2]

да че тут искать?
       FDecompressedStream.Free;


 
Ega23 ©   (2011-06-30 19:43) [3]

Ну вот видишь, всё просто.

З.Ы. Код - ужасен.


 
Ega23 ©   (2011-06-30 19:59) [4]

Несколько советов по улучшению кода:
1. Используй ZCompress и ZDecompress. В стримах под D2010 есть косяк, я уже раньше писал.
2. В данном примере можно обойтись одним стримом, вместо трёх. Просто добавь в свои методы Compress и Decompress параметр Stream: TMemoryStream
3. Используй Stream.ReadBuffer и Stream.WriteBuffer.
4. Пользуйся конструкцией:
 obj := TSomeObject.Create;
 try
   /// Работа с obj
 finally
   obj.Free;
 end;


 
Pcrepair ©   (2011-06-30 21:09) [5]

и чем канкретна код ужасен?


 
Ega23 ©   (2011-06-30 21:44) [6]


> и чем канкретна код ужасен?


Ну например:
1. В событии OnFormCreate пропиши ReportMemoryLeaksOnShutdown := True;
2. Переименуй файл s.bmp в _s.bmp.
3. Запусти приложение
4. Нажми на кнопку
5. Прочитай ExceptionMessage
6. Штатно закрой приложение (не через Program Reset)
7. Промедитируй над сообщением, которое вывалится.


 
antonn ©   (2011-07-01 00:02) [7]


> procedure TForm1.DCompress;// процедура декомпресии, не
> мое

а чье?


 
Pcrepair ©   (2011-07-01 08:20) [8]

не узнаешь свой код?
это по твоей наводке из файла p_u.pas


 
Ega23 ©   (2011-07-01 10:25) [9]


procedure CompressStream(Stream: TMemoryStream);
var
 pOut: Pointer;
 outSize: Integer;
begin
 ZCompress(Stream.Memory, Stream.Size, pOut, outSize, zcMax);
 try
   Stream.Position := 0;
   Stream.WriteBuffer(pOut^, outSize);
 finally
   FreeMem(pOut);
 end;
end;

procedure DecompressStream(Stream: TMemoryStream);
var
 pOut: Pointer;
 outSize: Integer;
begin
 ZDecompress(Stream.Memory, Stream.Size, pOut, outSize);
 try
   Stream.Position := 0;
   Stream.WriteBuffer(pOut^, outSize);
 finally
   FreeMem(pOut);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 ms: TMemoryStream;
 appDir: string;
begin
 ms := TMemoryStream.Create;
 try
   appDir := ExtractFilePath(ParamStr(0));
   ms.LoadFromFile(appDir+"s.bmp");
   CompressStream(ms);
   DecompressStream(ms);
   ms.Position := 0;
   Image1.Picture.bitmap.LoadfromStream(ms);
 finally
   ms.Free;
 end;
end;


Как же мне это всё надоело... Забаньте на месяц, что-ли?


 
Anatoly Podgoretsky ©   (2011-07-01 11:41) [10]

> Ega23  (01.07.2011 10:25:09)  [9]

Уверен?


 
antonn ©   (2011-07-01 13:18) [11]


> не узнаешь свой код?
> это по твоей наводке из файла p_u.pas

тогда по той же наводке попробуй использовать UnPack_Memory(var _in:TMemoryStream);, а не это нагромождение


 
Dennis I. Komarov ©   (2011-07-01 13:25) [12]


> Уверен?

Да ладно, пятницу тяжко переживает поди...
дня на три :)


 
Pcrepair ©   (2011-07-01 16:05) [13]

будем пробовать


 
Игорь Шевченко ©   (2011-07-01 16:37) [14]

Ega23 ©   (01.07.11 10:25) [9]

Небольшая коррекция кода в [9]: строки

  Stream.Position := 0;

следует заменить на

  Stream.Clear;

(от автора [9])


 
antonn ©   (2011-07-01 16:47) [15]

а чего - Ega забанили? я думал он об авторе говорил :))


 
Игорь Шевченко ©   (2011-07-01 16:57) [16]


> а чего - Ega забанили?


а чего, правила читать - не судьба ? :)
Забанили.


 
Pcrepair ©   (2011-07-01 20:29) [17]

Ega23, на самом деле работает это:

var
 Form1: TForm1;
 Stream: TMemoryStream;

implementation

{$R *.dfm}

procedure TForm1.CompressStream();
var
pOut: Pointer;
outSize: Integer;
begin
ZCompress(Stream.Memory, Stream.Size, pOut, outSize, zcMax);
try
 Stream.Clear;
 Stream.WriteBuffer(pOut^, outSize);
 finally
  FreeMem(pOut);
end;
end;

procedure TForm1.DecompressStream;
var
pOut: Pointer;
outSize: Integer;
begin
ZDecompress(Stream.Memory, Stream.Size, pOut, outSize);
try
    Stream.Clear;
  Stream.WriteBuffer(pOut^, outSize);
finally
  FreeMem(pOut);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
appDir: string;
begin
Stream := TMemoryStream.Create;
try
  appDir := ExtractFilePath(ParamStr(0));
  Stream.LoadFromFile(appDir+"s.bmp");
  CompressStream;
  DecompressStream;
  Stream.Position := 0;
  Image1.Picture.bitmap.LoadfromStream(Stream);
finally
  Stream.Free;
end;
end;

end.

но особой разницы в потреблении памяти практически нет
так что до сих пор неясно чем твой метод лучше предыдущего



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.003 c
15-1308747354
И. Павел
2011-06-22 16:55
2011.10.16
Вызов OLE из DelphiXE


2-1309024072
eXAAAXe
2011-06-25 21:47
2011.10.16
Максимальное разрешение экрана.


8-1217186194
Алекс
2008-07-27 23:16
2011.10.16
Проблема с отрисовкой Image.


15-1308930395
Оверклокер
2011-06-24 19:46
2011.10.16
А какой у вас куллер стоит?


15-1308953060
Kerk
2011-06-25 02:04
2011.10.16
Quake2 to Delphi conversion





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский