我通过Valgring发现某些GTK +程序会泄漏内存。修复这些泄漏有多重要?我的意思是,这些程序通常运行良好,但另一方面,人们永远无法确定是否要将部分泄漏的代码复制到其他程序中。而且我不确定GTK +程序的构想是否可以快速运行,是否存在泄漏。
因此,如果有时在开放源代码程序中发现内存泄漏,是否应该修复它或存在效率问题,因此程序员的初衷是编写一些小的泄漏代码?
我通过Valgring发现某些GTK +程序会泄漏内存。修复这些泄漏有多重要?我的意思是,这些程序通常运行良好,但另一方面,人们永远无法确定是否要将部分泄漏的代码复制到其他程序中。而且我不确定GTK +程序的构想是否可以快速运行,是否存在泄漏。
因此,如果有时在开放源代码程序中发现内存泄漏,是否应该修复它或存在效率问题,因此程序员的初衷是编写一些小的泄漏代码?
Answers:
修复内存泄漏的重要性取决于问题的严重性,并且您还必须执行其他重要操作。我的经验是,对于大多数应用程序而言,较小的内存泄漏往往是无害的。桌面应用程序会话的生命周期通常不够长,以至于看不到任何小内存泄漏导致的性能下降。
如果您要编写运行24/7的服务器,则随着时间的流逝,较小的内存泄漏可能会加起来,并成为主要问题。但这就是为什么许多公司计划将服务器每天或每周重新启动。相对于可能获得的结果,查找内存泄漏的工作通常要花很多功夫,因此定期重新启动服务器并转移到更重要的事情上比较容易。
对于短期运行的程序,内存泄漏并不重要。操作系统将在终止时回收所有内容,但是它们可能导致其他资源无法释放。
但是,短期运行是相对的,泄漏可能在几小时内失控或堆积数周而未被注意到。
我的建议是,如果潜在客户希望他修复该错误,请在跟踪器中提出一个建议的修复程序。
泄漏的类型也很重要。泄漏的分配很可能是一次性分配,开发人员故意依赖OS进行清理。这些将对valgrind产生误报。
grep
通过一个非常大的文件,并且您的程序为每个输入行泄漏了几个字节,则可能会耗尽内存。
在我对此主题的公认教条观点中,至少在旨在广泛应用的任何图书馆中,都没有借口为物理泄漏。因此,在他们自己修复GTK +开发人员之前,我将寻求他们的帮助。
对于一个库来说,注册atexit
回调以释放至少在卸载时分配的所有内存是微不足道的。如果要避免花费大量资金进行分配,那么就不应该首先进行分配。
即使是最懒惰的程序,它只想一次分配一大堆内存,也可以使用简单的顺序分配器,该分配器仅在关闭时清除所有内存。如果分配器甚至不想处理对齐方式,则只需将其合并的每个单个块填充到最大对齐边界即可。如果它能够通过不单独释放所有那些很小的内存块而受益于更快的关闭时间,那么它同样可以通过使用这样的顺序分配器以对称的顺序分配池来显着受益,以换取琐碎的工作:分配比malloc
以及更具缓存友好性的内存模式,只有在完成库后才释放分配器池中所有连续内存的大块。所有图书馆必须做的就是更换他们的malloc
呼吁,他们也懒得去free
喜欢的东西seq_malloc
,并呼吁seq_purge
在atexit
回调以释放在被卸载分配的所有内存。
否则,您将得到这个令人讨厌的库,使您的内存泄漏检测工具中的消息混乱不堪,现在必须将其过滤掉。更糟糕的是,如果您不系统地过滤掉它们,它们可能会掩盖您自己的应用程序中的泄漏,而您的同事可能会养成忽略它们的习惯,从而首先降低了泄漏检测工具的有效性,从而阻止了您自己的团队推送泄漏的代码。考虑到使用上面的解决方案是多么琐碎的事情,我总觉得没有理由支持故意进行此操作,这是总的和丑陋的。
逻辑泄漏(即使是垃圾收集也无法防御的更复杂的泄漏)是一个更复杂的问题,只要能清除短期分配的程序在内存上分配的所有内存,我就可以找到一些合理的理由关机,因为它需要大量有关资源管理的思想来避免逻辑泄漏(可以说在使用GC的语言中可能更多)。但是我没有找到任何合理的借口来避免物理泄漏,因为即使在最懒惰的情况下也要避免琐碎的事情。
无论如何,至少我会过滤掉valgrind中的漏洞,以使它们至少不会干扰您的团队发现您自己的漏洞的能力。