如何调试如何防止内存泄露露

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
技术咨询:&关注我们的微信关注下面公众号后快捷进入。可直接访问我们官网,通过客服找到我。请点击:
阅读(4352)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'如何检测内存泄漏',
blogAbstract:'编者按:&这几天在调试课本上关于二叉树的有关代码,发现严的这本数据结构教程喜欢把简单问题复杂化,当然这是从学生角度出发,从个人角度出发,这本书注重代码的可读性、重用等,更侧重于与软件工程、软件组织结合,当然是不错的教材。比如,其栈和队列的顺序实现,也都用指针来代替数组,让学生是很难理解。我在实现过程中,也有点拿不稳,特别是用队列或栈来存储树的结点(也是指针)时,为了确保没问题,特别是内存的分配,我搜索并安装了Virtual Leak Detector,一个开源的内存泄漏检测工具。',
blogTag:'visual,leak,detector,内存泄露检查工具,内存泄露',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:3,
publishTime:3,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:true,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}如何利用Instruments来调试和解决内存泄露问题 - 简书
下载简书移动应用
写了15205字,被40人关注,获得了36个喜欢
如何利用Instruments来调试和解决内存泄露问题
自从苹果从IOS 5.0 加入了Automatic Reference Counting (ARC)机制之后就不再需要手动去释放内存,确实是方便了不少。如果想了解更多详细关于ARC内容的话,请参考文章
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:mrlbz 的BLOG
用户名:mrlbz
文章数:23
访问量:25703
注册日期:
阅读量:5863
阅读量:12276
阅读量:336267
阅读量:1040246
51CTO推荐博文
简单说明了一下没有工具的情况如何运用VC库中的工具来检查代码的内存泄漏问题。一: 内存泄漏& & & & 内存泄漏是编程中常常见到的一个问题,内存泄漏往往会一种奇怪的方式来表现出来,基本上每个程序都表现出不同的方式。 但是一般最后的结果只有两个,一个是程序当掉,一个是系统内存不足。 还有一种就是比较介于中间的结果程序不会当,但是系统的反映时间明显降低,需要定时的Reboot才会正常。& & & & 有 一个很简单的办法来检查一个程序是否有内存泄漏。就是是用Windows的任务管理器(Task Manager)。运行程序,然后在任务管理器里面查看 “内存使用”和”虚拟内存大小”两项,当程序请求了它所需要的内存之后,如果虚拟内存还是持续的增长的话,就说明了这个程序有内存泄漏问题。 当然如果内存泄漏的数目非常的小,用这种方法可能要过很长时间才能看的出来。& & & & 当然最简单的办法大概就是用CompuWare的BoundChecker 之类的工具来检测了,不过这些工具的价格对于个人来讲稍微有点奢侈了。& & & & 如果是已经发布的程序,检查是否有内存泄漏是又费时又费力。所以内存泄漏应该在Code的生成过程就要时刻进行检查。二: 原因& & & &内存泄漏产生的原因一般是三种情况:分配完内存之后忘了回收;程序Code有问题,造成没有办法回收;某些API函数操作不正确,造成内存泄漏。& & 1. 内存忘记回收,这个是不应该的事情。但是也是在代码种很常见的问题。分配内存之后,用完之后,就一定要回收。如果不回收,那就造成了内存的泄漏,造成内存泄漏的Code如果被经常调用的话,那内存泄漏的数目就会越来越多的。从而影响整个系统的运行。比如下面的代码:for (int =0;I&100;I++){& & Temp = new BYTE[100];}就会产生 100*100Byte的内存泄漏。& & 2. 在某些时候,因为代码上写的有问题,会导致某些内存想回收都收不回来,比如下面的代码:Temp1 = new BYTE[100];Temp2 = new BYTE[100];Temp2 = Temp1;这样,Temp2的内存地址就丢掉了,而且永远都找不回了,这个时候Temp2的内存空间想回收都没有办法。& & 3. API函 数应用不当,在Windows提供API函数里面有一些特殊的API,比如FormatMessage。 如果你给它参数中有FORMAT_MESSAGE_ALLOCATE_BUFFER,它会在函数内部New一块内存Buffer出来。但是这个 buffer需要你调用LocalFree来释放。 如果你忘了,那就会产生内存泄漏。三: 检查方法& & & & 一 般的内存泄漏检查的确是很困难,但是也不是完全没有办法。如果你用VC的库来写东西的话,那么很幸运的是,你已经有了很多检查内存泄漏的工具,只是你想不 想用的问题了。Visual C++的Debug版本的C运行库(C Runtime Library)。它已经提供好些函数来帮助你诊断你的代码和跟踪内存泄漏。 而且最方便的地方是这些函数在Release版本中完全不起任何作用,这样就不会影响你的Release版本程序的运行效率。& & & & 比如下面的例子里面,有一个明细的内存泄漏。当然如果只有这么几行代码的话,是很容易看出有内存泄漏的。但是想在成千上万行代码里面检查内存泄漏问题就不是那么容易了。char * pstr = new char[5];lstrcpy(pstr,"Memory leak");& & & & 如 果我们在Debug版本的Code里面对堆(Heap)进行了操作,包括malloc, free, calloc, realloc, new 和 delete可以利用VC Debug运行时库中堆Debug函数来做堆的完整性和安全性检查。比如上面的代码,lstrcpy的操作明显破坏了pstr的堆结构。使其溢出,并破坏 了临近的数据。那我们可以在调用lstrcpy之后的代码里面加入 _CrtCheckMemory函数。_CrtCheckMemory函数发现前面的lstrcpy使得pstr的堆结构被破坏,会输出这样的报告:emory check error at 0x00372FA5 = 0x79, should be 0xFD.memory check error at 0x00372FA6 = 0x20, should be 0xFD.memory check error at 0x00372FA7 = 0x6C, should be 0xFD.memory check error at 0x00372FA8 = 0x65, should be 0xFD.DAMAGE: after Normal block (#41) at 0x00372FA0.Normal located at 0x00372FA0 is 5 bytes long.& & & &它 告诉说 pstr的长度应该时5个Bytes,但是在5Bytes后面的几个Bytes也被非法改写了。提醒你产生了越界操作。_CrtCheckMemory 的返回值只有TRUE和FALSE,那么你可以用_ASSERTE()来报告出错信息。 上面的语句可以换成 _ASSERTE(_CrtCheckMemory()); 这样Debug版本的程序在运行的时候就会弹出一个警告对话框,这样就不用在运行时候一直盯着Output窗口看了。这个时候按Retry,就可以进入源 代码调试了。看看问题到底出在哪里。& & & 其他类似的函数还有 _CrtDbgReport, _CrtDoForAllClientObjects, _CrtDumpMemoryLeaks,_CrtIsValidHeapPointer, _CrtIsMemoryBlock, _CrtIsValidPointer,_CrtMemCheckpoint, _CrtMemDifference, _CrtMemDumpAllObjectsSince, _CrtMemDumpStatistics, _CrtSetAllocHook, _CrtSetBreakAlloc, _CrtSetDbgFlag,_CrtSetDumpClient, _CrtSetReportFile, _CrtSetReportHook, _CrtSetReportMode& & & & 这 些函数全部都可以用来在Debug版本中检查内存的使用情况。具体怎么使用这些函数就不在这里说明了,各位可以去查查MSDN。在这些函数中用处比较大 的,或者说使用率会比较高的函数是_CrtMemCheckpoint, 设置一个内存检查点。这个函数会取得当前内存的运行状态。 _CrtMemDifference 检查两种内存状态的异同。 _CrtMemDumpAllObjectsSince 从程序运行开始,或者从某个内存检查点开始Dump出堆中对象的信息。还有就是_CrtDumpMemoryLeaks当发生内存溢出的时候Dump出堆 中的内存信息。 _CrtDumpMemoryLeaks一般都在有怀疑是内存泄漏的代码后面调用。比如下面的例子:#include &windows.h&#include &crtdbg.h&void main(){char *pstr = new char[5];_CrtDumpMemoryLeaks();}输出:Detected memory leaks! à提醒你,代码有内存泄漏.Dumping objects -&{44} normal block at 0x0 bytes long.Data: & & CD CD CD CD CDObject dump complete.& & & & 如 果你双击包含行文件名的输出行,指针将会跳到源文件中内存被分配地方的行。当无法确定那些代码产生了内存泄漏的时候,我们就需要进行内存状态比较。在可疑 的代码段的前后设置内存检查点,比较内存使用是否有可疑的变化。以确定内存是否有泄漏。为此要先定义三个_CrtMemState 对象来保存要比较的内存状态。两个是用来比较,一个用了保存前面两个之间的区别。_CrtMemState Sh1,Sh2,Sh_Dchar *pstr1 = new char[100];_CrtMemCheckPoint(&Sh1); -&设置第一个内存检查点char *pstr2 = new char[100];_CrtMemCheckPoint(&Sh2); -&设置第二个内存检查点_CrtMemDifference(&Sh_Diff, &Sh1, &Sh2); -&检查变化_CrtMemDumpAllObjectsSince(&Sh_Diff); -&Dump变化& & & & 如 果你的程序中使用了MFC类库,那么内存泄漏的检查方法就相当的简单了。因为Debug版本的MFC本身就提供一部分的内存泄漏检查。 大部分的new 和delete没有配对使用而产生的内存泄漏,MFC都会产生报告。这个主要是因为MFC重载了Debug版本的new 和delete操作符, 并且对前面提到的API函数重新进行了包装。在MFC类库中检查内存泄漏的Class就叫 CMemoryState,它重新包装了了_CrtMemState,_CrtMemCheckPoint, _CrtMemDifference, _CrtMemDumpAllObjectsSince这些函数。并对于其他的函数提供了Afx开头的函数,供MFC程序使用。比如 AfxCheckMemory, AfxDumpMemoryLeaks 这些函数的基本用法同上面提到的差不多。 CMemoryState和相关的函数的定义都在Afx.h这个头文件中。 有个简单的办法可以跟踪到这些函数的声明。在VC中找到MFC程序代码中下面的代码, 一般都在X.cpp的开头部分#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif& & & & 把 光标移到DEBUG_NEW上面 按F12,就可以进入Afx.h中定义这些Class和函数的代码部分。 VC中内存泄漏的常规检查办法主要是上面的两种。当然这两种方法只是针对于Debug版本的Heap的检查。如果Release版本中还有内存泄漏,那么 检查起来就麻烦很多了。4 .总结:& & & & 实际上Heap的内存泄漏问题是相当的好查的。VC的提供的检查工具也不太少,但是如果是栈出了什么问题,恐怕就麻烦很多了。栈出问题,一般不会产生内存泄漏,但是你的代码的逻辑上很有可能会有影响。这个是最最痛苦的事情。 编程,就是小心,小心再小心而已。
了这篇文章
类别:┆阅读(0)┆评论(0)【原创】内核内存泄露检查 - 看雪安全论坛
『软件调试逆向』 [综合性论坛]本版讨论的主题包括:调试逆向、系统底层、商业保护、虚拟机保护、.NET平台等安全相关的话题。
该主题: "【原创】内核内存泄露检查" 因在一定的时间里没有任何回复而自动关闭。如果您还对该主题感兴趣或者想参与对此主题的讨论,请您重新发表一篇相关的新主题。
本站声明:看雪论坛文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者信息及本声明!
注册日期: Feb 2008
现金: 468 Kx
获感谢文章数:4获会员感谢数:6
【原创】内核内存泄露检查
标 题: 【原创】内核内存泄露检查 作 者: correy
时 间: ,11:33:30 链 接: /showthread.php?t=154015
前言:内核内存泄露,对高手来说是小事一桩,轻而易举就能查到的,
&&&&&&但是对于没有接触过这的,要熟悉它,可能需要一段时间,比如我。
&&&&&&写的不好的地方,请多多指正。
内核内存的影响是很大的,特别是在服务器上,具体的看下面的案例。
检查内核内存池泄露的工具有:
poolmon.exe微软的命令行工具,在wdk里面。
Pooltag.exe,osr的图形界面工具。
Gflags.exe,windbg里面有。另一种办法是修改注册表。
Pooltag.txt,windbg里面的。//这个很有用。
Verifier.exe,这个是系统自带的。//这个暂时我没有用到。
步骤如下:
首先确保poolmon工具可以使用:winddows&2003及以后的好像不用设置。
方法一:使用Gflags.exe,具体的步骤如下:
1.单击开始,单击运行,键入gflags.exe,然后单击确定
2.选择启用池标记
3.单击应用,然后单击确定
4.重新启动计算机。
方法二:或者使用注册表修改,修改办法如下:
1.运行注册表编辑器。
2.在注册表中找到以下项:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session&Manager
3.记下的值的GlobalFlag,或保存Session&Manager键。
4.双击右窗格中的GlobalFlag值。
5.将值更改为0x的十六进制。
注意当您添加全局标志值&0x&时,它只显示为正在&0x400&后它将被添加。一定要添加前导零的所有或某些&Poolmon&信息将不会显示在输出屏幕。
重新启动计算机。
Poolmon.exe是命令行的,功能强大,不易使用。简要的说明几个使用办法:
P-排序标记列表中的通过分页,非分页,或混合。
B-标记按最大字节使用情况。M-标记按最大字节分配。
T&按标记名称的字母顺序排序-标记。
E-显示分页,跨底部未分页的总数。循环。
A-标记按分配大小。
F-按标记&释放&。
S-按标记的&allocs&的差异,并释放。
E-显示分页,跨底部未分页的总数。循环。
L-加亮或者不加亮,显示变化的行。
一些说明:
Type。此列显示&Nonp&或&Paged,分别表示非分页或分页内存使用方式。非分页内存使用方式更有可能导致问题。
Diff。此列显示该组件已执行的尚未得到释放的内存分配次数。
&&&&&&Diff&列中的值是&Allocs&和&Frees&列中相应的值之差。
&&&&&&如果一个组件在&Diff&列中的值随着时间而增长,则可能表明此组件存在内存泄漏。
Bytes。此值指示当前分配的内存量。如果一个组件在&Bytes&列中的值随着时间而增长,则可能表明此组件存在内存泄漏。
Mapped_Driver。此列仅在使用&g&参数时出现。它显示对标记的易于理解的描述,而且往往指示驱动程序的源文件。
Pooltag.exe的Mapped_Driver列可以显示驱动所在的目录。但信息很少,没有poolmon显示的信息多。
&&&&&操作办法是pooltags-&parse&all&drivers&in&driver&directory
界面的显示设置我就不说了:
使用办法:
例如:poolmon&-g&&C:\Program&Files\Debugging&Tools&for&Windows\triage\pooltag.txt&
每隔10-30分钟观看,d或者b命令的行列的变化,如果不停的变化(增加),就是泄露。
按d&显示的是没有释放的,按b显示的是申请的。
关于内核内存池的tag,
我以前收集的有3中办法,现在只记得一种了,
就是使用带有申请标记内存的函数。申请内存的时候一定要加标记。标记在c/c++中要用单引号,不超过4个字节。
如:ExAllocatePoolWithTag、ExallocatePoolWithTagPriority&和ExAllocatePoolWithQuotaTag,ExInitializeNPagedLookasideList&等。
如何找到池标记所使用的驱动程序,这时候大多是分析别人的驱动。
findstr&/m&/l&“xxxx”&c:\*.sys
有的时候会一个都搜索不出,这时我也不知所措,好像也应该没有这种情况。也许是你搜索的已经在,或者是已知的。
有的时候会搜索出多个,再根据每个驱动的版本和公司等做筛选。直到确定有问题的那一个。
参考资料:
如何使用内存池监视器&(Poolmon.exe)&来排查内核模式内存泄漏
/kb/177415/zh-cn
如何找到池标记所使用的第三方驱动程序&
/?kbid=298102
谁在使用池?
/zh-cn/library/windows/hardware/gg463213.aspx
PoolMon&Run-time&Commands
/en-us/library/ff550476.aspx
PoolMon&Startup&Command
/en-us/library/ff550482.aspx
PoolMon&Examples
/ddkx/ddtools/poolmon_37n7.htm
/en-us/library/ff550458.aspx
360的驱动(qutmdrv.sys)分页内存泄露案例
/ahuo/archive//1838439.html
瑞星的驱动(basetdi.sys)的非分页内存泄露案例
http://space.itpub.net/4670/viewspace-351828
等等。*转载请注明来自看雪论坛@
被 correy 最后编辑
共 3 位会员感谢 correy 发表的文章:
&(), &(), &()
注册日期: Nov 2011
现金: 172 Kx
获感谢文章数:0获会员感谢数:0
, 20:58:09
第一次做沙发...
注册日期: Dec 2010
现金: 25 Kx
获感谢文章数:9获会员感谢数:9
, 22:12:34
板凳,还不错哦。
注册日期: Feb 2009
现金: 371 Kx
致谢数: 23
获感谢文章数:3获会员感谢数:3
, 09:00:26
thx&for&share&it~~~good&article~~~
注册日期: Dec 2008
现金: 205 Kx
获感谢文章数:1获会员感谢数:1
, 10:08:26
不错&&感谢楼主分享
注册日期: Nov 2011
现金: 100 Kx
获感谢文章数:0获会员感谢数:0
, 10:10:00
保留标记!!
注册日期: Jun 2009
现金: 67 Kx
获感谢文章数:0获会员感谢数:0
, 04:40:58
Verifier.exe,这个是系统自带的。//这个暂时我没有用到。
It's&a&very&useful&tool.
注册日期: Jan 2011
现金: 564 Kx
获感谢文章数:0获会员感谢数:0
, 07:29:19
谢楼主,&学习了、
注册日期: Nov 2009
现金: 42 Kx
获感谢文章数:0获会员感谢数:0
, 11:30:31
很好,内核和表层微软都自带很强的工具查泄露
注册日期: Jun 2008
现金: 213 Kx
获感谢文章数:0获会员感谢数:0
, 23:40:58
谢谢楼主的分享。
该主题: "【原创】内核内存泄露检查" 因在一定的时间里没有任何回复而自动关闭。如果您还对该主题感兴趣或者想参与对此主题的讨论,请您重新发表一篇相关的新主题。
您不可以发表主题
您不可以回复帖子
您不可以上传附件
您不可以编辑自己的帖子
论坛论坛启用
用户控制面板
会员在线状态
『看雪众测/众包』
『Android 安全』
『Android 开发』
『iOS安全』
『求助问答』
『经典问答』
『资料导航』
『软件调试逆向』
『密码学』
『编程技术』
『C32Asm』
『MDebug』
『安全工具开发』
『加壳与脱壳』
『CrackMe&ReverseMe』
『资源下载』
『WEB安全』
『漏洞分析』
『外文翻译』
『招聘专区』
『职业生涯』
『15PB培训』
『麦洛克菲培训』
『茶余饭后』
『安全资讯』
『论坛活动』
6)PEDIY Crackme竞赛2009
7)看雪十周年专版
8)腾讯公司2010软件安全竞赛
9)2011 Exploit Me竞赛
『图书项目版』
《加密与解密(第三版)》
《C++反汇编与逆向分析技术揭秘》
《Android软件安全与逆向分析》
『论坛版务』
所有时间均为北京时间, 现在的时间是 .
&&& 看雪学院()
| 提供带宽资源
|&微信公众帐号:内存泄露都有什么调试方法,下面是我的代码,不知道如何调试,哪里有错
[问题点数:40分]
内存泄露都有什么调试方法,下面是我的代码,不知道如何调试,哪里有错
[问题点数:40分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2015年9月 C/C++大版内专家分月排行榜第三
2015年9月 C/C++大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。

我要回帖

更多关于 ios如何检测内存泄露 的文章

 

随机推荐