I have an application in Delphi 7, where I made the code below to load large PDF files from a blob field to memory and then I load the PDF, it works perfect with large files I have already tested with 1 gigabyte files. However, somewhere there is a memory leak and I don't know where, after loading 10 large files, it presents the Message - Out of Memory.
I am not sure how to clear the memory after loading the memory.
I already tested loading several pdf files and it works perfectly, the component has no problem. Note guys, I don't want to save it to file after loading it in the component, I want to do it directly in memory.
Note guys, I don't want to save to file on disk and then load the component, I want to do it directly in memory.
procedure TForm1.btnAbrirClick(Sender: TObject);
var
BlobStream: TStream;
Arquivo: Pointer;
begin
pdf2.Active := False;
Screen.Cursor := crHourGlass;
try
BlobStream := absqry1.CreateBlobStream(absqry1.FieldByName('binario'),bmRead);
Arquivo := AllocMem(BlobStream.Size);
BlobStream.Position := 0;
BlobStream.ReadBuffer(Arquivo^, BlobStream.Size);
pdf2.LoadDocument(Arquivo);
pdfvw1.Active := True;
finally
Screen.Cursor := crDefault;
BlobStream.Free;
Arquivo := nil;
end;
end;
Arquivo := nil;
does not free memory allocated by AllocMem
. For that, you need a call to FreeMem
.
This is covered in the documentation (emphasis mine):
AllocMem allocates a memory block and initializes each byte to zero.
AllocMem allocates a block of the given Size on the heap, and returns the address of this memory. Each byte in the allocated buffer is set to zero. To dispose of the buffer, use FreeMem. If there is not enough memory available to allocate the block, an EOutOfMemory exception is raised.
I've also corrected your use of try..finally
.
procedure TForm1.btnAbrirClick(Sender: TObject);
var
BlobStream: TStream;
Arquivo: Pointer;
begin
pdf2.Active := False;
Screen.Cursor := crHourGlass;
BlobStream := absqry1.CreateBlobStream(absqry1.FieldByName('binario'),bmRead);
try
Arquivo := AllocMem(BlobStream.Size);
try
BlobStream.Position := 0;
BlobStream.ReadBuffer(Arquivo^, BlobStream.Size);
pdf2.LoadDocument(Arquivo);
pdfvw1.Active := True;
finally
FreeMem(Arquivo);
end;
finally
Screen.Cursor := crDefault;
BlobStream.Free;
end;
end;