3

我在 Delphi 7 中有一个应用程序,我在其中编写了下面的代码,将大型 PDF 文件从 blob 字段加载到内存,然后加载 PDF,它适用于我已经用 1 GB 文件测试过的大文件。但是,某处存在内存泄漏,我不知道在加载 10 个大文件后,它会在哪里显示消息 - 内存不足。

我不确定如何在加载内存后清除内存。

我已经测试了加载几个 pdf 文件,它运行良好,组件没有问题。请注意,我不想在将其加载到组件中后将其保存到文件中,我想直接在内存中进行。

请注意,我不想保存到磁盘上的文件然后加载组件,我想直接在内存中执行。

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;
4

1 回答 1

6

Arquivo := nil;不释放由 分配的内存AllocMem。为此,您需要调用FreeMem.

这包含在文档中(重点是我的):

AllocMem 分配一个内存块并将每个字节初始化为零。

AllocMem 在堆上分配给定大小的块,并返回此内存的地址。分配的缓冲区中的每个字节都设置为零。要处理缓冲区,请使用 FreeMem。如果没有足够的可用内存来分配块,则会引发 EOutOfMemory 异常。

我还更正了您对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;
于 2020-07-27T02:42:07.247 回答