55

我觉得开发人员在谈论内存泄漏,但是当你问他们这意味着什么时,很多人都不知道。为了防止这些情况,让我们决定一个。

请不要维基百科定义...

您对 内存泄漏的最佳定义是什么 ?防止它们的最佳方法是什么?

4

11 回答 11

55

有两个定义(至少对我来说):

朴素定义:无法释放无法访问的内存,在分配过程执行过程中,任何进程都不能再重新分配。这主要可以通过使用 GC(垃圾收集)技术或通过自动化工具检测到来解决。

微妙的定义:未能释放程序正常运行不再需要的可达内存。使用自动化工具或不熟悉代码的程序员几乎不可能检测到这一点。虽然从技术上讲它不是泄漏,但它与天真的泄漏具有相同的含义。这不仅仅是我自己的想法。您可能会遇到用垃圾收集语言编写的项目,但仍会在其变更日志中提到修复内存泄漏。

于 2008-11-23T04:19:21.903 回答
31

由于对它的引用已丢失而无法使用的分配内存。

于 2008-11-23T03:30:45.683 回答
14

定义:分配后未能释放内存。

于 2008-11-23T03:15:51.970 回答
6

分配内存资源并且一旦不再需要就没有正确释放的过程,通常是通过糟糕的编码实践引入的。

一些语言有内置的方法来帮助防止它们,尽管避免它们的最好方法是通过仔细观察代码执行路径和代码审查。保持方法简短且目的明确有助于保持资源使用范围狭窄,并且不太容易在洗牌中迷失方向。

于 2008-11-23T03:22:10.630 回答
2

有两种方法可以定义内存泄漏。

首先,如果数据在不再有任何引用时没有被释放,则该数据是不可访问的(除非您有一些损坏的指针或读取缓冲区中的数据或其他东西)。基本上,如果您不释放/删除在堆上分配的数据,它就会变得不可用并且只会浪费内存。

可能存在指针丢失但数据仍可访问的情况。例如,如果您将指针存储在 int 中,或者存储指针的偏移量(使用指针算法),您仍然可以取回原始指针。

在第一个定义中,数据由垃圾收集器处理,垃圾收集器跟踪对数据的引用次数。

其次,如果在最后一次使用时没有释放/删除内存,则内存基本上是泄漏的。它可能会被引用,并且可以立即释放,但错误的是不这样做。可能有一个正当的理由(例如,在析构函数有一些奇怪的副作用的情况下),但这表明程序设计不好(在我看来)。

第二种类型的内存泄漏经常发生在编写使用文件 IO 的小程序时。您打开文件,写入数据,但完成后不要关闭它。FILE* 可能仍在范围内,并且可以轻松关闭。同样,这样做可能有一些原因(例如锁定其他程序的写访问权限),但对我来说,这是一个糟糕设计的标志。

在第二个定义中,垃圾收集器不处理数据,除非编译器/解释器足够聪明(或愚蠢),知道它不会再被使用,并且释放数据不会造成任何副作用。

于 2008-11-23T03:22:33.640 回答
2

w:

在计算机科学中,内存泄漏是一种特殊类型的计算机程序无意的内存消耗,其中程序在不再需要时无法释放内存。这种情况通常是由于程序中的错误导致无法释放不再需要的内存。

于 2008-11-23T05:37:40.467 回答
1

不再需要时未释放且不再“可访问”的内存。例如,在非托管代码中,如果我使用“new”来实例化一个对象,但是当我完成它时我不使用“delete”(并且我的指针已经超出范围或其他东西)。

防止它们的最佳方法可能取决于您询问的对象以及您使用的语言。当然,垃圾回收是一个很好的解决方案,但可能会有一些相关的开销,这没什么大不了的,除非你的主要关注点是性能。同样,垃圾收集可能并不总是可用,这取决于您使用的语言。

或者,您可以确保有适当的删除和/或析构函数。还有很多方法和工具可以检测内存泄漏,但这取决于您使用的语言和/或 IDE。

于 2008-11-23T03:22:27.323 回答
1

内存泄漏:未能释放您之前不再需要的内存:

  • 程序终止
  • 分配了额外的内存

防止内存泄漏的最佳方法:在不再需要内存时立即释放内存。

于 2008-11-23T03:34:12.103 回答
1

这里给出的所有定义(在我写这篇文章的时候,我们已经得到了更好的答案)未能解决一个临界案例:

您有一个单例,它在创建时分配内存,并且只要程序正在运行,即使当前使用已经完成,并且不知道将来是否会进行任何使用,该内存通常也会保留。这通常是因为重新创建它的开销。

根据“完成后无法释放”标准,这将被视为泄漏,我已经看到泄漏报告工具称此类事情为泄漏,因为内存仍在使用中。(事实上​​,代码可能不包含能够清理对象的代码。)

但是,即使重新创建对象的成本并不是那么高,我也曾在编译器库中遇到过这种性质的代码。

泄漏与否?

于 2008-11-23T05:30:37.390 回答
1

以下是一些防止/检测内存泄漏的技术:

  1. 在内存消耗方面考虑您的算法。其他受访者提到了这样一个事实,即您不必丢失指向已分配项目的指针以泄漏内存。即使您的实现包含零指针错误,如果您在实际需要分配的项目后很长时间仍持有分配的项目,您仍然可以有效地泄漏内存。

  2. 分析您的应用程序。您可以使用 Valgrind 或 Purify 等内存调试器工具来查找泄漏。

  3. 黑盒测试。观察你的编译代码在你输入大数据集后会发生什么,或者让它运行很长时间。看看它的内存占用是否有无限增长的趋势。

于 2008-11-23T07:02:40.387 回答
-5

编辑:这个答案是错误的。我把它作为一个例子来说明你认为自己非常了解的事情是多么容易被误解。感谢所有指出我错误的人。

内存泄漏是: 编程错误。您的软件从系统中借用一些内存,使用它,然后在完成后无法将其返回给系统。这意味着在系统重新启动之前,任何其他程序都不能使用该特定内存块。许多此类泄漏可能会耗尽所有可用内存,从而导致系统完全无用。

为防止内存泄漏,请练习 RIIA,并始终测试您的软件。有很多工具可用于此任务。

于 2008-11-23T03:31:56.990 回答