0

我有 CodeGear C++ Builder XE5。使用 TIdTCPServer 创建的服务器,效果很好。但是服务使用的内存正在增长。我终于设法包含了完整版的 FastMM4 内存管理器,在摆弄选项后,我发现内存泄漏的确认:

13 - 20 bytes: TIdThreadSafeInteger x 1
21 - 36 bytes: TIdCriticalSection x 2, Unknown x 1
53 - 68 bytes: UnicodeString x 1
85 - 100 bytes: Unknown x 21
149 - 164 bytes: Unknown x 21
181 - 212 bytes: Unknown x 2

显然 x1 和 x2 不关心我,但是 x21 泄漏很糟糕,因为这是一个高度使用的服务 - 每个连接流血 100 和 164 字节:

更多详细信息指出:

A memory block has been leaked. The size is: 100

This block was allocated by thread 0xD98, and the stack trace (return addresses) at the time was:
    8D4743 [Unknown function at @@Zip_int@Finalize]
    8D461D [Unknown function at @@Zip_int@Finalize]
    8E0F94 [Unknown function at @@Zip_int@Finalize]
    8E0F59 [Unknown function at @@Zip_int@Finalize]
    8DFADA [Unknown function at @@Zip_int@Finalize]
    8DE722 [Unknown function at @@Zip_int@Finalize]
    8BF045 [Unknown function at @@Searchfilelist@Finalize]
    8C4C90 [Unknown function at @@Searchfilelist@Finalize]
    8D6638 [Unknown function at @@Zip_int@Finalize]
    775D1C77 [Unknown function at RtlNtStatusToDosErrorNoTeb]
    452A45 [@Fastmm4@DebugGetMem$qqri]

The block is currently used for an object of class: Unknown

A memory block has been leaked. The size is: 164

This block was allocated by thread 0x5394, and the stack trace (return addresses) at the time was:
    8D4743 [Unknown function at @@Zip_int@Finalize]
    8D461D [Unknown function at @@Zip_int@Finalize]
    8E0FD9 [Unknown function at @@Zip_int@Finalize]
    8E0F59 [Unknown function at @@Zip_int@Finalize]
    8DFADA [Unknown function at @@Zip_int@Finalize]
    8DE722 [Unknown function at @@Zip_int@Finalize]
    8BF045 [Unknown function at @@Searchfilelist@Finalize]
    8C4C90 [Unknown function at @@Searchfilelist@Finalize]
    8D6638 [Unknown function at @@Zip_int@Finalize]
    775D1C77 [Unknown function at RtlNtStatusToDosErrorNoTeb]
    452A45 [@Fastmm4@DebugGetMem$qqri]

The block is currently used for an object of class: Unknown

The allocation number is: 125893

在这一点上我被卡住了,我不知道这是为了什么,因为我不直接调用 Zip_int。谁能指出我正确的方向?

4

1 回答 1

1

前两个泄漏 -TIdThreadSafeInteger并且TIdCriticalSection- 是 Indy 中众所周知的泄漏,仅在应用程序关闭时发生,因为它们是故意不释放的全局对象。我很惊讶在泄漏报告中看到它们,因为 Indy 用 FastMM 将它们注册为已知泄漏。

其他的不是 Indy 泄漏。你的代码必须分配一些你没有释放的东西。UnicodeString泄漏可能表明了这一点,因为泄漏字符串的最常见方式是它是否是未释放的类实例的成员。如果泄漏与服务器接收的连接数成正比,那么您可能会分配一些东西并将其存储在 中TIdContext,例如在OnConnect事件中,而不是稍后释放,例如在OnDisconnect事件中。但是您没有显示您的代码。

我觉得奇怪的是,泄漏似乎是在单元完成期间分配的,而不是在应用程序的正常运行期间分配的,但Finalize我不知道为什么会有这么多的调用。除非应用程序的堆栈跟踪信息错误。FastMM 无法报告更有意义的信息,因为这些单元可能未在启用调试信息的情况下编译。您是否至少有一个由编译器为您的应用程序生成的 .MAP 文件?这有助于 FastMM 从内存地址解析函数名称。

于 2014-06-26T15:44:32.650 回答