Delphi 这些内存泄漏是真的吗

Delphi 这些内存泄漏是真的吗,delphi,Delphi,我一直在我的代码上运行FastMM4,看看是否有内存泄漏 当我关闭程序时,报告了大量的类破坏泄漏。这些是真实的吗?我如何解释事件日志:这是一个典型的区块报告: --------------------------------2020/10/21 17:32:01-------------------------------- A memory block has been leaked. The size is: 120 This block was allocated by thread 0

我一直在我的代码上运行FastMM4,看看是否有内存泄漏

当我关闭程序时,报告了大量的类破坏泄漏。这些是真实的吗?我如何解释事件日志:这是一个典型的区块报告:

--------------------------------2020/10/21 17:32:01--------------------------------
A memory block has been leaked. The size is: 120

This block was allocated by thread 0x5648, and the stack trace (return addresses) at the time was:
430547 [FastMM4.pas][FastMM4][_ZN7Fastmm411DebugGetMemEx][8737]
409534 [System.pas][System][_ZN6System7_GetMemEx][4803]
412F8C [System.pas][System][_ZN6System17_NewUnicodeStringEi][25403]
414C3C [System.pas][System][_ZN6System16InternalUStrCatNERNS_13UnicodeStringEiPS0_][29902]
4156CB [System.pas][System][_ZN6System9_UStrCatNERNS_13UnicodeStringEi][30998]
5DD71A [System.IniFiles.pas][System.IniFiles][_ZN6System8Inifiles11TMemIniFile8TSection9SetValuesEiNS_13UnicodeStringE][852]
5DEFA6 [System.IniFiles.pas][System.IniFiles][_ZN6System8Inifiles11TMemIniFile11WriteStringENS_13UnicodeStringES2_S2_][1212]
14F335F [IDEIni.pas][IDEIni][_ZN6Ideini15TIDEIniSettings13UpdateSectionEN6System13UnicodeStringE][1153]
14F26E7 [IDEIni.pas][IDEIni][_ZN6Ideini15TIDEIniSettings13UpdateSectionEi][1087]
14F24FD [IDEIni.pas][IDEIni][_ZN6Ideini15TIDEIniSettings4SaveEiiiiibjPN6System7Classes8TStringsENS1_13UnicodeStringE][1078]
14DE604 [IDEMain.pas][IDEMain][_ZN7Idemain10TfmIDEMain9FormCloseEPN6System7TObjectERNS1_7Uitypes12TCloseActionE][573]

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

The allocation number is: 675683

Current memory dump of 256 bytes starting at pointer address 7FF4FBF7E170:
24 D9 69 01 B0 04 02 00 01 00 00 00 29 00 00 00 50 00 61 00 74 00 68 00 3D 00 43 00 3A 00 5C 00
50 00 72 00 6F 00 67 00 72 00 61 00 6D 00 20 00 46 00 69 00 6C 00 65 00 73 00 20 00 28 00 78 00
38 00 36 00 29 00 5C 00 50 00 72 00 6F 00 74 00 6F 00 6E 00 49 00 44 00 45 00 5C 00 50 00 44 00
53 00 00 00 CA 9A 8A F5 AF D5 F2 FF 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
00 00 00 00 00 00 00 00 81 E3 F7 FB F4 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 37 48 0A 00 47 05 43 00 00 00 00 00 B6 08 43 00 00 00 00 00
9D 95 40 00 00 00 00 00 1C 54 41 00 00 00 00 00 11 55 41 00 00 00 00 00 01 56 45 01 00 00 00 00
63 02 46 01 00 00 00 00 E2 1E 46 01 00 00 00 00 92 9B 68 00 00 00 00 00 A5 04 41 00 00 00 00 00
$  Ù  i  .  °  .  .  .  .  .  .  .  )  .  .  .  P  .  a  .  t  .  h  .  =  .  C  .  :  .  \  .
P  .  r  .  o  .  g  .  r  .  a  .  m  .     .  F  .  i  .  l  .  e  .  s  .     .  (  .  x  .
8  .  6  .  )  .  \  .  P  .  r  .  o  .  t  .  o  .  n  .  I  .  D  .  E  .  \  .  P  .  D  .
S  .  .  .  Ê  š  Š  õ  ¯  Õ  ò  ÿ  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
.  .  .  .  .  .  .  .    ã  ÷  û  ô    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  7  H  .  .  G  .  C  .  .  .  .  .  ¶  .  C  .  .  .  .  .
  •  @  .  .  .  .  .  .  T  A  .  .  .  .  .  .  U  A  .  .  .  .  .  .  V  E  .  .  .  .  .
c  .  F  .  .  .  .  .  â  .  F  .  .  .  .  .  ’  ›  h  .  .  .  .  .  ¥  .  A  .  .  .  .  .
大多数泄漏都很小,不到200字节,但我应该担心它们吗

这些是真的吗

很可能。尤其是你展示的那一个,是的

如何解释事件日志

您显示的泄漏报告表明发生了泄漏
UnicodeString
是一种托管类型。我所见过的唯一一次被泄露的
unicode
是:

  • 它是
    记录
    的成员,并且该类型的动态分配实例本身是泄漏的。泄漏报告应显示此实例也被泄漏

  • 指向已分配的UnicodeString的指针由于被意外覆盖而损坏,通常是由于代码中的某个逻辑错误

  • 它被声明为
    threadvar
    ,并且在线程退出之前不会手动清除。这是:

    通常由编译器管理的动态变量(长字符串、宽字符串、动态数组、变量和接口)可以用
    threadvar
    声明,但编译器不会自动释放每个执行线程创建的堆分配内存。如果在线程变量中使用这些数据类型,则在线程终止之前,您有责任从线程中处置它们的内存

让我们更仔细地看一下您的报告

A memory block has been leaked. The size is: 120 不言自明

The allocation number is: 675683 日志中使用的名称mangling的格式告诉我,您使用的是一个基于Clang的编译器,因此如果我们假设使用64位编译器,则会使StrRec的大小为16个字节,如果我们分解转储的前16个字节,则会得到以下值:

24 D9 69 01 _Padding, ignored B0 04 codePage = 1200, UTF-16 02 00 elemSize = 2, sizeof(WideChar) 01 00 00 00 refCnt = 1 29 00 00 00 length = 41 WideChar elements 并从相应的ASCII转储:

P . a . t . h . = . C . : . \ . P . r . o . g . r . a . m . . F . i . l . e . s . . ( . x . 8 . 6 . ) . \ . P . r . o . t . o . n . I . D . E . \ . P . D . S . . . 其余转储数据只是碰巧在同一内存块中的随机垃圾,因为FastMM在固定大小的块的存储桶中分配内存。在这种情况下,泄漏的
UnicodeString
被分配到一个使用120字节块的bucket中


如果我不得不猜测,您泄漏了
TMemIniFile
对象(应该出现在泄漏报告的其他地方),或者您的Delphi版本中的
TMemIniFile
有一个逻辑错误,泄漏了
t节
对象(应该出现在泄漏报告的其他地方)。现在,您可以在这里开始调试代码,以跟踪泄漏的根本原因。

是的,它们看起来是真实的。是的,你应该担心它们。我同意@DavidHeffernan,但我想澄清一件事:当然,如果你每天泄漏1KB,而你的应用程序通常不会运行很多年,那么浪费的内存量甚至不会被任何用户注意到。然而,经过良好编程的软件不会泄漏,因此如果出现泄漏,则表明您对程序的工作方式没有完全了解,因此可能会怀疑存在更严重的问题。没有检测到内存泄漏是软件高质量的必要条件,但不是充分条件。您使用的是哪个版本的Delphi?您的泄漏报告显示泄漏是
TSection.SetValues()
TMemIniFile.WriteString()中的串联字符串。
TMemIniFile
不太可能泄漏该信息。我的RTL源代码最多只有XE3,并且该版本中的
System.ini文件.pas
中没有
t节,因此这一定是
TMemIniFile
实现中的最新添加,因此
TMemIniFile
中可能但不太可能存在泄漏错误。您确定没有泄漏
TMemIniFile
本身吗?正在报告哪些其他泄漏?Section是一个变量,用于定义存储键值的节名称。UpdateSection是我为更新节而调用的例程的名称。Dude,创建或扩展泄漏报告堆栈跟踪,以便可以跟踪泄漏的分配。猜测毫无意义。我对你的解释感激不尽。我相信很多其他人也会发现这一点非常有用。UnicodeString很容易泄漏的另一种方法是将其声明为threadvar。 Current memory dump of 256 bytes starting at pointer address 7FF4FBF7E170: 24 D9 69 01 B0 04 02 00 01 00 00 00 29 00 00 00 50 00 61 00 74 00 68 00 3D 00 43 00 3A 00 5C 00 50 00 72 00 6F 00 67 00 72 00 61 00 6D 00 20 00 46 00 69 00 6C 00 65 00 73 00 20 00 28 00 78 00 38 00 36 00 29 00 5C 00 50 00 72 00 6F 00 74 00 6F 00 6E 00 49 00 44 00 45 00 5C 00 50 00 44 00 53 00 00 00 CA 9A 8A F5 AF D5 F2 FF 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 00 00 00 00 81 E3 F7 FB F4 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 48 0A 00 47 05 43 00 00 00 00 00 B6 08 43 00 00 00 00 00 9D 95 40 00 00 00 00 00 1C 54 41 00 00 00 00 00 11 55 41 00 00 00 00 00 01 56 45 01 00 00 00 00 63 02 46 01 00 00 00 00 E2 1E 46 01 00 00 00 00 92 9B 68 00 00 00 00 00 A5 04 41 00 00 00 00 00 $ Ù i . ° . . . . . . . ) . . . P . a . t . h . = . C . : . \ . P . r . o . g . r . a . m . . F . i . l . e . s . . ( . x . 8 . 6 . ) . \ . P . r . o . t . o . n . I . D . E . \ . P . D . S . . . Ê š Š õ ¯ Õ ò ÿ € € € € € € € € € € € € € € € € € € € € . . . . . . . . ã ÷ û ô . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 H . . G . C . . . . . ¶ . C . . . . . • @ . . . . . . T A . . . . . . U A . . . . . . V E . . . . . c . F . . . . . â . F . . . . . ’ › h . . . . . ¥ . A . . . . . 24 D9 69 01 _Padding, ignored B0 04 codePage = 1200, UTF-16 02 00 elemSize = 2, sizeof(WideChar) 01 00 00 00 refCnt = 1 29 00 00 00 length = 41 WideChar elements 50 00 61 00 74 00 68 00 3D 00 43 00 3A 00 5C 00 50 00 72 00 6F 00 67 00 72 00 61 00 6D 00 20 00 46 00 69 00 6C 00 65 00 73 00 20 00 28 00 78 00 38 00 36 00 29 00 5C 00 50 00 72 00 6F 00 74 00 6F 00 6E 00 49 00 44 00 45 00 5C 00 50 00 44 00 53 00 00 00 P . a . t . h . = . C . : . \ . P . r . o . g . r . a . m . . F . i . l . e . s . . ( . x . 8 . 6 . ) . \ . P . r . o . t . o . n . I . D . E . \ . P . D . S . . .