首页 / 知识
关于c ++:查找由智能指针引起的内存泄漏
2023-04-15 14:52:00

Find memory leaks caused by smart pointers是否有人知道"技术"来发现由智能指针引起的内存泄漏?我目前正在从事一个用C ++编写的大型项目,该项目大量使用带有引用计数的智能指针。显然,我们有一些由智能指针引起的内存泄漏,它们仍在代码中的某处引用,因此它们的内存不会被释放。很难找到带有"不必要"引用的代码行,这将导致相应对象无法释放(尽管不再使用)。 我在网上找到了一些建议,这些建议提议收集参考计数器的递增/递减操作的调用堆栈。这给了我一个很好的提示,即哪段代码导致了参考计数器的增加或减少。 但是我需要的是一种将相应的"增加/减少调用堆栈"分组在一起的算法。删除了这些成对的调用栈之后,我希望剩下(至少)一个"增加调用栈",它向我展示了带有"不必要"引用的那段代码,该代码导致相应的对象不被释放。现在,解决泄漏将无济于事! 但是,有人对进行分组的"算法"有想法吗? 开发在Windows XP下进行。 (我希望有人能理解,我试图解释的是...) EDIt:我说的是循环引用引起的泄漏。 请注意,带有引用计数智能指针的泄漏源之一是具有循环依赖关系的指针。例如,A具有指向B的智能指针,而B具有指向A的智能指针。A和B都不会被破坏。您将必须找到并打破依赖关系。 如果可能,请使用boost智能指针,对应该是数据所有者的指针使用shared_ptr,对不应该调用delete的指针使用weak_ptr。
我这样做的方法很简单: 要检测参考周期,您需要具有所有参考计数对象的图形。这样的图不容易构造,但是可以做到。
创建全局
接下来,提供一些从每个 最后,在有向图中实现您喜欢的循环检测算法。启动程序,创建一些循环并运行循环检测器。请享用! :) 我要做的是将智能指针包装到带有FUNCTION和LINE参数的类中。每次调用构造函数时,对该函数和行的计数都增加,而每次调用析构函数时,计数均减小。然后,编写一个转储函数/行/计数信息的函数。告诉您所有引用的创建位置 如果您可以确定性的方式重现泄漏,那么我经常使用的一种简单技术是按照构造顺序为所有智能指针编号(在构造函数中使用静态计数器),并将此ID与泄漏一起报告。然后再次运行该程序,并在构造具有相同ID的智能指针时触发DebugBreak()。 您还应该考虑使用这个很棒的工具:http://www.codeproject.com/KB/applications/visualleakdetector.aspx 这不是发现泄漏的问题。在使用智能指针的情况下,很可能会将其定向到诸如CreateObject()之类的通用位置,该位置被调用了数千次。这是确定代码中没有在引用计数的对象上调用Release()的地方的问题。 由于您说的是使用Windows,因此您可以利用Microsoft的用户模式转储堆实用程序UMDH,该实用程序随Windows调试工具一起提供。 UMDH为应用程序的内存使用情况制作快照,记录用于每个分配的堆栈,并让您比较多个快照以查看对分配器的哪些调用"泄漏"了内存。它还使用dbghelp.dll将堆栈跟踪转换为符号。 还有另一个名为" LeakDiag"的Microsoft工具,它比UMDH支持更多的内存分配器,但是查找起来有点困难,而且似乎没有得到积极维护。如果我没记错的话,最新版本至少有五年的历史。 为了解决这个问题,我要做的是重写malloc / new和free / delete运算符,以便它们尽可能跟踪您正在执行的操作的数据结构。 例如,当覆盖malloc / new时,您可以创建调用者地址,请求的字节数,返回的指针值和序列ID的记录,以便可以对所有记录进行排序(我不知道您是否处理线程,但您也需要考虑到这一点)。 在编写释放/删除例程时,我还会跟踪调用者的地址和指针信息。然后,我向后看一下列表,并尝试使用指针作为我的键来匹配malloc / new。如果找不到,请举一个红旗。 如果可以负担得起,则可以将序列ID嵌入数据中,以绝对确定何时进行分配调用。这里的关键是尽可能唯一地标识每个交易对。 然后,您将拥有第三个例程,显示您的内存分配/取消分配历史记录以及调用每个事务的功能。 (这可以通过从链接程序中解析符号映射来完成)。您将知道您随时将分配多少内存以及谁分配了内存。 如果没有足够的资源来执行这些事务(我的典型情况是8位微控制器),则可以通过串行或TCP链接将相同的信息输出到具有足够资源的另一台计算机上。 我是Google Heapchecker的忠实拥护者-它不会捕获所有泄漏,但可以吸收大部分泄漏。 (提示:将其链接到所有单元测试中。) 对于Windows,请检出: MFC内存泄漏检测 如果我是您,我将记下日志并编写一个快速脚本来执行以下操作(Ruby是我的):
这基本上会遍历日志,并捕获每个分配/取消分配并为每对存储唯一的值,然后对其进行排序并删除匹配的对,看看还剩下什么。 更新:对所有中间编辑都感到抱歉(我在完成之前不小心发布了)
第一步可能是知道正在泄漏什么类。 |
最新内容
相关内容
linux查找设备号命令?
linux查找设备号命令?,设备,系统,信息,名称,分区,网上,情况,软件,技术,工具,在linux中如何知道自己的IDE设备的代号呢?例如,第一个 IDE 硬盘的linux打包项目命令?
linux打包项目命令?,项目,文件,命令,软件,数字,系统,名称,工具,目录,格式,Linux打包和压缩1、Linux下,常用打包命令有2个,分别是tar和dd;常用的压linux项目更新命令行?
linux项目更新命令行?,工作,地址,系统,数据,信息,项目,标准,电脑,目录,命令,linux常用的命令有哪些1、linux系统常用操作命令linux系统常用操linux查找网卡的命令?
linux查找网卡的命令?,地址,系统,网络,实时,工具,信息,技术指标,电脑,状态,网卡,Linux怎么查询网卡配置1、首先在电脑上打开Linux系统,然后进入字符串查找命令linux?
字符串查找命令linux?,系统,字符串,工具,信息,文件,命令,字符,选项,文本,范本,如何在Linux下查找文件内容包含某个特定字符串的文件在linux中glinux查找帮助的命令?
linux查找帮助的命令?,系统,命令,信息,软件,名称,文件,指令,进程,表示,参数,linux搜索文件名命令(使用find命令在Linux上查找文件和目录)findlinux查找帮助的命令?
linux查找帮助的命令?,系统,命令,信息,软件,名称,文件,指令,进程,表示,参数,linux搜索文件名命令(使用find命令在Linux上查找文件和目录)findlinux查找重复项命令?
linux查找重复项命令?,工具,系统,电脑,百度,文件,命令,情况,名字,标准,通用,linux查找目录下是否有相同文件可以使用ls命令,ls跟dos下的dir命令linux命令查找进程?
linux命令查找进程?,系统,名称,软件,状态,进程,电脑,信息,命令,材料,数据,怎么查看linux进程名称1、linux 下查看进程可以使用的命令:ps命令查linux命令查找日志?
linux命令查找日志?,地址,信息,系统,名称,对比,状态,实时,命令,日志,等级,linux后台自动执行命令nohup与日志查看将一个在后台暂停的命令,变成linux查找php命令?
linux查找php命令?,服务,信息,系统,名称,工具,软件,网络,代码,工作,网站,Linux该怎么查看系统的PHP进程linux服务器查看php信息,用到的工具:雅黑linux命令查找内容?
linux命令查找内容?,命令,文件,网络,名称,信息,工作,标准,系统,管理,位置,linux下按文件名和文件内容查找文件1、按名称查找文件你可以借助正