c++ - 在 C++ Builder XE4 中搜索内存泄漏

标签 c++ memory-leaks c++builder c++builder-xe4

我正在尝试查找并修复我的应用程序中存在的内存泄漏。我正在试用的内存分析工具 - C++ 内存验证器 - 显示大约每 5 分钟分配 1,310,706 个字节。这些分配的调用堆栈可以追溯到我认为是用 pascal 编写的 Embarcadero 内存管理器。有问题的功能是:

{Allocates a new sequential feed medium block pool and immediately splits off a
 block of the requested size. The block size must be a multiple of 16 and
 medium blocks must be locked.}
function AllocNewSequentialFeedMediumPool(AFirstBlockSize: Cardinal): Pointer;
var
  LOldFirstMediumBlockPool: PMediumBlockPoolHeader;
  LNewPool: Pointer;
begin
  {Bin the current sequential feed remainder}
  BinMediumSequentialFeedRemainder;
  {Allocate a new sequential feed block pool}
  LNewPool := VirtualAlloc(nil, MediumBlockPoolSize, MEM_COMMIT, PAGE_READWRITE);
  if LNewPool <> nil then
  begin
    {Insert this block pool into the list of block pools}
    LOldFirstMediumBlockPool := MediumBlockPoolsCircularList.NextMediumBlockPoolHeader;
    PMediumBlockPoolHeader(LNewPool).PreviousMediumBlockPoolHeader := @MediumBlockPoolsCircularList;
    MediumBlockPoolsCircularList.NextMediumBlockPoolHeader := LNewPool;
    PMediumBlockPoolHeader(LNewPool).NextMediumBlockPoolHeader := LOldFirstMediumBlockPool;
    LOldFirstMediumBlockPool.PreviousMediumBlockPoolHeader := LNewPool;
    {Store the sequential feed pool trailer}
    PNativeUInt(PByte(LNewPool) + MediumBlockPoolSize - BlockHeaderSize)^ := IsMediumBlockFlag;
    {Get the number of bytes still available}
    MediumSequentialFeedBytesLeft := (MediumBlockPoolSize - MediumBlockPoolHeaderSize) - AFirstBlockSize;
    {Get the result}
    Result := Pointer(PByte(LNewPool) + MediumBlockPoolSize - AFirstBlockSize);
    LastSequentiallyFedMediumBlock := Result;
    {Store the block header}
    PNativeUInt(PByte(Result) - BlockHeaderSize)^ := AFirstBlockSize or IsMediumBlockFlag;
  end
  else
  begin
    {Out of memory}
    MediumSequentialFeedBytesLeft := 0;
    Result := nil;
  end;
end;

请注意,变量 MediumBlockPoolSize 是一个常量,它是泄漏的确切大小。

我认为正在发生的事情是,当我的应用程序泄漏内存时,它会分配一些东西,此时我们从可用内存池中请求一个新的内存块 (1.3MB),我认为这大约每 5 分钟发生一次。但是,这并不能准确告诉我泄漏的来源。有什么方法可以更好地查明泄漏源?

我已经检查了代码并确保所有新闻都有删除,并且没有指针在没有先被删除的情况下被重新分配等。

下面是分配内存块时的调用树。请注意,如果我在代码中注释掉这个调用树,该 block 将出现在我的代码中的不同位置,依此类推。

call tree

谢谢。

最佳答案

Delphi/C++Builder RTL 使用(精简版)FastMM memory manager默认情况下。 FastMM 在桶中分配内存,并为将来的分配重新使用释放的内存,而不是将其返回给操作系统。在应用程序终止之前,内存不会返回给操作系统。

这不是真正的泄漏,但您的验证器不知道这一点,因为它不知道 RTL 的内存管理器在运行时实际如何使用分配的内存(这与为什么您也不能使用 Windows 任务管理器来诊断泄漏)。

如果您想跟踪真实 泄漏,请安装 FastMM 的完整版本并使用它自己的内置泄漏检测器功能。只有在运行时实际使用的内存管理器才知道内存是如何被使用的,并且可以确定什么构成了真正的泄漏。

关于c++ - 在 C++ Builder XE4 中搜索内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49323374/

相关文章:

c++ - MSXML 内存泄漏

c++ - 包括写在不同文件夹中的函数

c++ - 这个字符串的范围是什么?

c++ - 为什么这个用于在 C++11 和 TR1 之间切换的预处理器宏不起作用?

c++ - 谁拥有 QQmlIncubator 返回的对象?

c - 为什么不在这里释放 calloc() 的内存(YOLO)

c - Mac OS 10.7 (Lion) 上类似 Valgrind 的工具

c++builder - XE6 如何检查 UnicodeString 是否为 null?

c++ - Qt 5.3。 QWidget直接用OpenGL绘画

c++ - 是否可以从对象而不是类注册 QML 类型?