![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Программа "ест" память, потом сбой
Pcrepair © (2011-06-30 17:58:00)Добрый день
Программа была написана для проверки работоспособности процедур компресии-декомпресии графического файла с использованием 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- и далее мб)
Все Переменные после использования уничтожаются
В чем может быть проблема?
Pcrepair (2011-07-01 20:29:00) [1]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.
но особой разницы в потреблении памяти практически нет
так что до сих пор неясно чем твой метод лучше предыдущего
Игорь Шевченко (2011-07-01 16:57:00) [2]
> а чего - Ega забанили?
а чего, правила читать - не судьба ? :)
Забанили.
antonn (2011-07-01 16:47:00) [3]а чего - Ega забанили? я думал он об авторе говорил :))
Игорь Шевченко (2011-07-01 16:37:00) [4]Ega23 © (01.07.11 10:25) [9]
Небольшая коррекция кода в [9]: строки
Stream.Position := 0;
следует заменить на
Stream.Clear;
(от автора [9])
Pcrepair (2011-07-01 16:05:00) [5]будем пробовать
Dennis I. Komarov (2011-07-01 13:25:00) [6]
> Уверен?
Да ладно, пятницу тяжко переживает поди...
дня на три :)
antonn (2011-07-01 13:18:00) [7]
> не узнаешь свой код?
> это по твоей наводке из файла p_u.pas
тогда по той же наводке попробуй использовать UnPack_Memory(var _in:TMemoryStream);, а не это нагромождение
Anatoly Podgoretsky (2011-07-01 11:41:00) [8]> Ega23 (01.07.2011 10:25:09) [9]
Уверен?
Ega23 (2011-07-01 10:25:00) [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;
Как же мне это всё надоело... Забаньте на месяц, что-ли?
Pcrepair (2011-07-01 08:20:00) [10]не узнаешь свой код?
это по твоей наводке из файла p_u.pas
antonn (2011-07-01 00:02:00) [11]
> procedure TForm1.DCompress;// процедура декомпресии, не
> мое
а чье?
Ega23 (2011-06-30 21:44:00) [12]
> и чем канкретна код ужасен?
Ну например:
1. В событии OnFormCreate пропишиReportMemoryLeaksOnShutdown := True;
2. Переименуй файл s.bmp в _s.bmp.
3. Запусти приложение
4. Нажми на кнопку
5. Прочитай ExceptionMessage
6. Штатно закрой приложение (не через Program Reset)
7. Промедитируй над сообщением, которое вывалится.
Pcrepair (2011-06-30 21:09:00) [13]и чем канкретна код ужасен?
Ega23 (2011-06-30 19:59:00) [14]Несколько советов по улучшению кода:
1. Используй ZCompress и ZDecompress. В стримах под D2010 есть косяк, я уже раньше писал.
2. В данном примере можно обойтись одним стримом, вместо трёх. Просто добавь в свои методы Compress и Decompress параметр Stream: TMemoryStream
3. Используй Stream.ReadBuffer и Stream.WriteBuffer.
4. Пользуйся конструкцией:
obj := TSomeObject.Create;
try
/// Работа с obj
finally
obj.Free;
end;
Ega23 (2011-06-30 19:43:00) [15]Ну вот видишь, всё просто.
З.Ы. Код - ужасен.
Pcrepair (2011-06-30 19:06:00) [16]да че тут искать?
FDecompressedStream.Free;
Ega23 (2011-06-30 18:45:00) [17]
> В чем может быть проблема?
В процедуре DCompress утечка памяти. Это то, что "блондинка" сходу увидел а.
Но подсказывать не буду. Из принципа. :)
Не из вредности, а потому, что ты её должен найти сам.