小内存泄漏是否重要?

时间:2009-11-12 01:23:35

标签: memory-leaks

现在所有PC上的RAM通常都在千兆字节,我是否应该花时间寻找可能在我的程序中的所有小的(不增长的)内存泄漏?我说的是那些可能小于64字节的漏洞,甚至是一堆只有4个字节的漏洞。

其中一些很难识别,因为它们不在我自己的代码中,但可能在第三方代码中或在开发工具的代码中,我甚至可能无法直接访问源代码。在这些情况下,它将涉及与这些产品的供应商进行长时间的沟通。

我在SO上看到了第一个内存泄漏问题:Are memory leaks ever ok?并且排名第一,现在已经投了85次,是:否。

但在这里,我说的是小泄漏,可能需要进行大量的调试,研究和沟通才能追踪。

我只谈论一个简单的桌面应用程序。我知道在服务器上运行的应用程序必须尽可能紧密。

所以我真正要问的问题是,如果我知道我有一个泄漏的程序,每次运行时说40个字节,那有关系吗?

A Single Drip
(来源:beholdgenealogy.com


另请参阅我的后续问题:What Operating Systems Will Free The Memory Leaks?


后记:我刚刚为我的程序开发购买了EurekaLog

我找到了an excellent article by Alexander,EurekaLog的作者(应该知道这些事情),关于捕获内存泄漏。在那篇文章中,亚历山大非常简洁地陈述了我的问题的答案:

  

虽然应用程序中的任何错误总是很糟糕,但是存在一些错误类型,这些错误在某些环境中是不可见的。例如,memory or resources leaks错误在客户端计算机和can be deadly on servers上相对无害。

17 个答案:

答案 0 :(得分:47)

这完全是个人决定。

但是,如果:

  

所以我真正要问的问题是,如果我知道我有一个泄漏的程序,每次运行时说40个字节,那有关系吗?

在这种情况下,我会说不。当程序终止时,内存将被回收,因此如果它在可执行文件的操作期间只泄漏了40个字节一次,那实际上是毫无意义的。

但是,如果重复泄漏40个字节,每次进行某些操作时,这可能更有意义。应用程序运行时间越长,就越重要。

我会说,修复内存泄漏通常是值得的,即使泄漏是“无意义”的泄漏。内存泄漏通常是一些潜在问题的指标,因此理解和纠正泄漏通常会使您的程序随着时间的推移更加可靠。

答案 1 :(得分:30)

泄漏是错误。

你可能还有其他错误。

运送产品时,请使用已知错误发货。当您选择哪个(已知的)错误“修复”而不是“随附”时,您可以根据修复的成本和风险与客户利益进行比较。

泄漏也不例外。如果这是在非服务器应用程序中不频繁操作期间发生的小泄漏(例如,运行几分钟或几小时然后关闭的应用程序),它可能是“正常”,就像任何其他错误一样。< / p>

实际上,泄漏在一个重要方面可能有所不同,即如果您要运送库/ API,您真的应该修复它们,因为客户利益是巨大的(否则您的所有客户'继承'您的泄漏,并且正在打电话给你,就像你现在要与第三方供应商交谈一样。)

答案 2 :(得分:19)

虽然我同意每一个小漏洞都会增加,但我不同意它始终是解决它的最佳业务决定。

如果您拥有无状态遗留系统并且没有理解它的编码人怎么办?现在你在一个必须扩展的情况下使用它......并且在内存过载之前生成一个新实例并将它们交换出来要便宜100倍。

或者假设您有一个24x7全天候运行的批处理系统,但没有真正的用户。如果监视内存并告诉系统定期重启自己更便宜,为什么还要追捕泄漏?

我认为你应该努力尝试,但要对决策的商业后果务实。

答案 3 :(得分:10)

不,但是,只有当您指出内存泄漏 重复时,才会无关紧要。内存泄漏不会随着程序的进展而增长通常是可以的。当进程终止时,最终将解决不增长的内存泄漏。

然而,很难证明观察到的内存泄漏没有增长;你有足够的经验数据。实际上,许多大型程序(甚至用Java / C#编写)都有内存泄漏,但大多数都是不增长的泄漏。

说真的,我们不能没有内存泄漏,死锁,数据竞争。有这些错误本身是好的。只有当它杀死你的程序时才重要。

但是,我不同意你的观点:“记忆很便宜”。这无法证明内存泄漏的合理性。那是非常危险的。

答案 4 :(得分:5)

是。泄漏很重要。如果您的应用程序以24x7x365运行并且每秒处理几千个事务,则几个字节会快速转换为千兆字节。

答案 5 :(得分:5)

  

内存泄漏是否正常?

当然,如果这是一个短暂的过程。

如85分的答案所暗示的,长时间内存泄漏是有问题的。拿一个简单的桌面应用程序,例如 - 在版本3.x之前,你有没有注意到你需要它一段时间后重新启动Firefox以从缓慢恢复它?

至于短期,不,没关系。以CGI或PHP脚本为例,或者在~/bin目录中使用小的Perl三线程。如果你在C中用5行malloc()编写一个30行非循环应用程序并且没有一次调用free(),那么没有人打电话给记忆警察。

答案 6 :(得分:5)

内存泄漏实际上取决于几个方面:

  • 泄漏发生的频率
  • 每次丢失多少内存
  • 该计划将运行多长时间

例如,如果每次任务发生时丢失40个字节,并且该任务在程序启动时发生,则无人问津。如果每次程序启动时丢失40Mb,则应对其进行调查。如果你在视频或游戏引擎中每帧丢失40个字节,那么你应该研究一下,因为你每秒会损失1.2kB,一小时后你会丢失大约4Mb。

这还取决于该计划将持续多久。例如,我有一个小型计算器应用程序,我打开,运行计算,然后再次关闭。如果该应用程序在运行中丢失4Mb,那么它并不重要,因为一旦我关闭它,操作系统将回收丢失的内存。如果前面提到的假设视频/游戏引擎每小时损失4Mb,并且它在一个大会的展位上运行一个演示单元,每天几个小时,那么我会调查它。

一个着名的内存泄漏示例是Firefox,它在早期版本中丢失了大量内存。如果您的浏览器在10年前泄露了内存,那么您可能根本不在乎。您每天都关闭计算机,而在运行浏览器时,您一次只能打开一个页面。今天我只是让我的笔记本电脑进入待机状态,我从不关闭Firefox。它一次打开几个星期,我在任何给定时间至少打开10个标签。如果每次关闭选项卡时内存泄漏,那么现在比10年前更大的泄漏,所以它更重要。

答案 7 :(得分:4)

我和你在同一条船上。我有小内存泄漏,永远不会增长。大多数泄漏是由于不正确地拆除COM对象引起的。我已经研究了泄漏并且意识到修复它们的时间和金钱与泄漏造成的损害是不成比例的。 Windows大部分时间都会清理,因此只有用户在不重新启动的情况下运行计算机多年才能实现真正的损坏。

我认为在漏洞中离开是可以接受的。这听起来很禁忌,但是如果泄漏永远不会增长而且它们很小,那么在更大的方案中这是非常微不足道的。

答案 8 :(得分:3)

我同意之前的反应,即泄漏确实很重要。

人们可能拥有大量的内存,但他们也在运行越来越多的程序,除非你的应用程序完全占用了处理器,否则它需要与其他程序一起运行,这也意味着不会占用资源。需要。

因此,这个小内存泄漏会加起来意味着用户会遇到其他问题,如果他们认为他们有内存问题,如果他们认为运行你的应用程序会导致问题,那么他们就会停止运行它。 / p>

此外,正如已经指出的,如果你不知道是什么导致了泄漏,那么你可能还有其他你不知道的问题。这可能是一个臭虫冰山的一角。

答案 9 :(得分:2)

这取决于您的应用程序的性质。我主要从事网站和Web应用程序。因此,根据大多数定义,我的应用程序每次请求“运行”一次。在高容量站点上每个请求泄漏几个字节的代码可能是灾难性的。根据经验,我们有一些代码,每个请求泄漏几kb。加起来,这导致我们的Web服务器工作进程重新启动,因此经常导致全天长时间停机。

但是Web应用程序(以及许多其他类型)具有无限期的生命周期 - 它们会持续不断地运行。您的应用程序寿命越短越好。如果您的应用程序的每个会话都有一个有限且可合理预测的终点,那么您当然可以容忍合理的泄漏量。这完全取决于投资回报率。

答案 10 :(得分:2)

一切都取决于。不用担心的原因:进程是短暂的,泄漏很小和/或不常见,内存不足异常的成本很低(例如,群集中的Web服务器实例需要重新启动而一些提取需要重试) 。所以我同意一些漏洞在实际上并不重要。

但另一方面,如果你确实有理由担心,或者甚至感到一种唠叨的怀疑,即你可能没有认真对待质量,那么运行你的软件是一件小事(在大多数情况下)内存泄漏检测器并解决问题。那里有很多好的检漏仪。并且您可能会发现泄漏是更严重问题的一部分,例如不释放其他资源(如打开文件)。您甚至可能会发现,在您尚未测试的使用场景中,无害泄漏会变得非常危险。

答案 11 :(得分:1)

是的,这很重要。每一个小漏洞都会增加。

首先,如果在重复使用的上下文中使用泄漏代码,并且每次泄漏一点点,那么这些小位就会加起来。即使泄漏很小,也很少发生,这些东西在很长一段时间内都会增加很多。

其次......如果您正在编写具有内存泄漏的代码,则该代码存在问题。我不是说好的代码不会不时出现内存泄漏,但它们存在的事实意味着存在一些严重的问题。许多安全漏洞都是由于这种疏忽造成的(无限制的字符串副本,任何人?)。

如果您了解它,那么最重要的是,并没有尽力去追踪它并修复它,那么就会造成问题。

答案 12 :(得分:0)

任何程序中的内存泄漏都无法正常运行,无论它多么小。 慢慢地,他们会加起来填满你的整个记忆。假设你有一个调用系统,每次调用它会处理大约4个字节的内存。你可以处理说,每秒100次呼叫(这是一个非常小的数字),所以你最终每秒泄漏400个字节或每小时400x60x60(1440000B)。因此,即使是小漏也是不可接受的。 如果你不知道泄漏的来源,那么它可能是一个真正的大问题,你最终有错误的软件。 但是,基本上归结为诸如程序运行的时间和泄漏发生的次数之类的问题。因此,它可能是泄漏非常少量并且不会重复但是泄漏可能是更大问题的一小部分。 所以,我觉得内存泄漏永远不会好。

答案 13 :(得分:0)

这就像询问大坝是否有裂缝是否可以?没有!决不!避免内存泄漏,就好像你的生活依赖于它一样,因为当你的应用程序增长并得到更多使用时,泄漏将变成洪水,迟早会有人或某些东西淹没在其中。仅仅因为你可以拥有大量内存并不意味着你可以使用你的代码获取快捷方式。一旦发现泄漏,你可以尽力解决它,如果你无法解决它,请确保在修复之前不断回复它。

如果您无法解决泄漏问题,请尝试查看是否可以清除泄漏。当泄漏重复时,问题就出现了。

最后注意:如果您曾将软件交给其他人并且泄漏仍然存在,那么在其他人找到并/或修复它之前可能需要很长时间。

答案 14 :(得分:0)

我不会那么担心你泄漏的内存的数量,但是如果你经常泄漏几个字节,你的malloc的数据结构会增长,并且可能会使它越来越慢,分配新内存和免费。除非你遇到泄漏超过RAM的一小部分的边界,否则主要是你的程序会遇到这些性能问题,而不是整个系统。甚至不适用于基于dlmalloc的远程系统(FreeBSD,Linux等),它只是不关心,你所有松散的内存(可能是你认为的数量的几倍)而不是性能。

您的程序无法回收的单个分配根本不是泄漏。如果你编写一个小命令行实用程序,需要一秒钟才能完成,你甚至不需要在那里回收任何内存。一旦终止,操作系统回收RAM,文件句柄,基本上应该适用于任何类型的系统资源,但你不能像其他操作系统那样依赖某些操作系统,但只要它只是内存,即使Windows 95也能正确管理它

哦,另外还有一件事,如果你泄漏内存,不要在程序结束时或经过很长的执行时间后打扰清理,否则你只会浪费更多的CPU时间。始终将泄漏修复为尽可能靠近创建它们的时间点。其他原因:malloc实现更喜欢保留从操作系统获取的RAM以供将来分配而不是将其返回。此外,您可能会遇到地址空间碎片。

答案 15 :(得分:0)

如果有人说内存泄漏是少量的,只要它不会使应用程序崩溃,就像说,如果少量并且只要你没有被抓住就可以偷窃:)

答案 16 :(得分:0)

内存泄漏 在32位应用程序中非常重要 ,因为应用程序限制为2 ^ 32字节的内存,大约为4 GB。一旦32位应用程序尝试分配超过2 ^ 32字节的内存,应用程序可能会崩溃或挂起。

内存泄漏 在64位应用程序 中并不重要,因为应用程序仅限于2 ^ 64字节的内存,约为16 EB;因此,对于64位应用程序,您更受硬件限制,但操作系统仍可能在某个时候施加一个人为限制。

底线是你的代码中存在内存泄漏是错误的编程;所以解决它并成为一个更好的程序员。