脚本内存泄漏
Ⅰ 关于win7系统环境下,EXE程序文件损坏问题
错误提示:文件或路径名不正确。选择忽略,又弹出提示:fatal error:exception code=c0000005
先转一个致命错误=C0000005吧。
小聊 "致命错误=C0000005 "
这份帖子主要在讲述“致命错误——C0000005”,它是什么,为什么会出现,何种情况下将出现,以及如何避免之。请根据您的口味选择是否浏览之。
昨夜又见论坛上寻问C0000005的帖子,是关于Visual Foxpro 9.0 版本的,这引起了我的注意。
本以偷懒的态度草草回复之,然而接下来网友的追问使我自知偷懒的后者便是语义表达不到位,便索性连夜写下此主题帖。但仍以简练为主,请大家多担待!
c0000005错误发生的诱因主要分为四大类:
1、自由表存储载体的缺陷(主要体现在VCX、VCT,SCX和SCT上)。
2、第三方监控性质的软件(如:防毒软件在内存即时监控状态下、词霸在全屏拾取模式下等);
3、Visual Foxpro 自身的代码漏洞;
4、硬件因素。
先说第一大类:
同数据表一样,在Visual Foxro 9.0 版本中,自由表也支持了原子事务机制,这并非主要是为了满足客户的需要,而以稳定VFP9自身为主。我们都知道类与表单的代码多以物理形式为自由表的VCX、VCT,SCX和SCT文件格式存储,在IDE设计模式下,代码被VFP后台以独占的、开放式自由表缓冲的模式存取。然而您应该敏感地注意到:自由表是不支持事务机制的(低于9.0版本的Visual Foxro)。也就是说,遇到停电或操作系统异常时,它们同样会面临表头损坏、低级链接错误、记录指针错误偏移的风险。Microsoft Visual Foxpro 开发组没有将VCX、SCX设计为依赖于数据库的数据表的形式,原因不难理解——如果一个表单文件中,包括表单本身在内的任何一个控件都不依赖于用户自定义派生类的话,那么该文件应该可以被独立地拷贝与打开。
如下的常识我们都需要知道:
无论是在设计模式还是在运行模式下,Visual Foxpro的Runtime会随时将客户脚本读取到内存体中,并交由词法分析器、语法分析器和语义分析器来分析、解释、处理这些代码。
(通常情况,在编辑模式下,我们的脚本代码已经被Visual Foxpro词法分析器进行了第一遍的过滤;在编辑完一个prg或表单或类文件后,若按下Ctrl+W组合键将在保存它之前调用语法分析器来试图检查其中的错误(注意“词法”分析器与“语法”分析器的不同),然后程序界面将自动被关闭;而若按下Ctrl+S组合键保存后,再手动退出时,这种情况下将不会调用语法分析程序。)
如果你的脚本保存在自由表形式的SCX、SCT、VCX、VCT文件中,Visual Foxpro会通过表的记录指针提取对应备注文件里的程序脚本(那里或许包含了某些事件或方法的代码)。首先,Visual Foxpro 的底层通过调用C语言的sizeof()来判断字节的长度,根据长度提取字节,将其存放到字符类型的数组中,最后将长度的返回值与该存放实际代码的数组以参数的形式传递给语义分析器来解释执行。然而在一些情况下,会发生sizeof()判断的字节长度与实际的长度不一致的情况。
倘若sizeof()判断的字节长度与实际的长度不一致,将会发生内存的溢出,这个致命错误被Visual Foxpro异常处理器捕获后,将抛出“致命错误-C0000005”的信息。
“致命错误=”是字符常量,“c0000005”是一个变量,c0000005不是VFP的错误编码,而是得到Windows消息环所传递过来的错误消息参数的半加工品。它的原始状态是16进制的0xC0000005,VFP通过相关的转换函数转换成字符串的形式,以便通过界面描述给用户。
那么什么情况下会出现sizeof()判断的字节长度与实际的长度不一致的情况呢?主要有两方面的主导因素。
1、我们前面铺垫过了,VCX、VCT,SCX和SCT文件都是自由表,都有可能在设计时被无意的损坏。
倘若表头被损坏,您会在试图打开它们的时候收到VFP系统的无法打开该表单的信息;但倘若低级链接错误、记录指针错误偏移,您就不会得到任何VFP的提示,因为VFP系统自己也不知道这一点,就像您一样。于是直到程序运行时,才会收到令人惊愕的致命错误信息——语义分析器工作时内存被溢出。
在一些“致命错误-C0000005”的信息框中,您会收到似乎更详细些的信息,指示您程序出错的地方。那通常是包含在SCX、SCT或VCX、VCT里某些行的代码。
千万不要被误导,并不是您的程序代码编写有问题,而是隐藏在标识符之外的、看起来好像是空格、回车的空白段,那里隐藏了低级链接的错误、或Unicode的错位排序(下面马上就会讲述到),用Shift+方向键将整行全选,然后按Delete键删除之,最后老老实实地将原行代码重新书写一遍即可(切记:用Shift+方向键将整行全选,然后将该整行彻底清除)。
2、Unicode
从Windows98升级过来的VFP程序员似乎都曾有过这样的困惑:为什么Windows2000以上版本的VFP程序会如此的不稳定,以至于频繁出现“致命错误——C0000005”?
Visual Foxpro的词法扫描器大概是这样工作的:词法扫描器分析代码脚本的时候,先要判断一下 下一个被扫描的Token是否为空白标记。若是,则看该空白标记是Tab标记还是回车标记,或者是分隔符或其它的占位符;若不是,则判断该Token是单字节还是双字节字符,这种机制在基于Unicode的Windows版本中,有时会遇到标识符号的错位。
您现在上网用的计算机的操作系统是WIN2000或WinXP吗?如果是,不妨亲自做这样一个试验:
打开记事本程序,输入“联通”,然后保存后关闭该文本,再重新开打,看到什么了?标识符号被错位了!
是的,当年WIN2000操作系统的流行时,Visual Foxpro开发组并没有彻底改正语义分析器代码的漏洞。
好的,第一大类我就阐述完了。如何避免它呢?
*--------------
总的应该说很麻烦,有两种途径供您选择:
1、修改VCX、SCX表国际代码页的编码,将简体中文编码改为英文编码;
2、我所推荐的方法是尽量用prg。你可能会认为这样做很麻烦,但作为程序员,您应该更加专业一些。您可以备份可视化的表单或类文件,但在程序正式发布前,最好最大限度地转化为prg程序。倘若以后需要修改程序,通过备份的表单或类文件进行可视化编辑,然后再次转化为prg发布之。
对于已经开发好的项目,就没有必要大兴土木地全部将Vcx、Scx转化为Prg了,但您应该着重关注一下主菜单Mnx文件,及控件(尤其是图片)特别多的表单。或许,您曾遇到过这样令人匪夷所思的问题:在运行exe文件时,为什么有时候一切正常,而有时候却产生致命异常——要知道开发人员根本就没改任何的代码呀?
下面我将剖析上面的问题:
在用菜单编辑器进行菜单定义时,Visual Foxpro系统将产生四个对应文件:一个自由表、前者的备注文件,一个程序文件(mpr)及它的执行格式文件(mpx)。
如果您用 Do Menu XXX.mnx 的方式调用主菜单时,.mnx与.mnt两文件将被包含至工程中去,在exe执行时,以提取自由表记录的形式解释程序。
但mnx模式存在着一个致命的缺欠,就是Visual Foxpro 在申请堆栈时的预定空间量相对prg的程序文件要小许多。通常这没什么问题,但你要知道并不是每次Visual Foxpro 都能如愿地向Windows操作系统申请到预定的空间值,有的时候它所获得的堆栈数目会少一些,甚至恰巧会小于菜单初始化时所需要占用的空间量。这就是为什么有时候exe第一次运行时正常,退出后再次运行时偶尔会出现“致命错误-c0000005”的原因。
请您以 Do XXX.mpr 的形式直接调用程序文件形式的mpr,就能够很好地避免之。因为在默认情况下,Visual Foxpro 为程序文件所申请的堆栈数远远大于mnx,即便是Visual Foxpro没有从Windows操作系统中得到预定数目的空间,然而比起 定义存储prg内脚本的字符型数组的长度来说,也绰绰有余了。
另外,一个存储了大量控件与图片信息的表单,同样会遇到与菜单文件相似的情形——即Visual Foxpro 所获得的堆栈数小于表单初始化时所需要的数目,从而造成内存的溢出。
顺便告诉您一个小窍门:
在IDE设计模式下,我们或许会突然遇到“致命错误-C0000005”袭击,因为表单是以独占的、开放式自由表缓冲的模式交互的,所以此前未经保存的信息都将被丢失,这您是知道的,通过刚才的讲述,您还知道了这或许会面临表被损坏的风险,从而进入了一个“致命错误-C0000005”潜在引发今后“致命错误-C0000005”故障的恶性循环。
小窍门就是,您千万不要条件反射地去触击那个“确定”按钮!那不过只是Visual Foxpro系统所捕获的异常罢了,它不是真“致命”的,Visual Foxpro系统仍在运转中,也就是说,它还在正常地接收着Windows操作系统不断发送来的消息。这时,请您点开Windows桌面最左下角的“开始”按钮,选择“重新启动计算机”或“关闭计算机”,Windows在试图关闭电脑前,会先检查是否有尚在运行中的应用程序,它会发现一个叫Fox的先生尚未退场,于是便发送清场的消息给Foxpro,Visual Foxpro其实还在正常的运转中,它接收到这条消息后,会调用自身的退出机制试图退出,而自身的退出机制会发现尚有正在编辑的表单,便会发出“需要保存修改吗?”的询问消息,这时候,您选择保存,就可以了!
千万注意了!这段过程大概只有5秒钟的时间!因为为了防止死循环的情况出现,Windows会在等待几秒钟对方不应答的情况下强行终止程序,那时候,就真正退出整个Windows系统了。所以您一定要眼疾手快!
第二大类是第三方监控性质的软件。如:防毒软件在内存即时监控状态下、词霸软件在全屏拾取模式下等。其实防毒软件本身并不与VFP产生冲突,但有一个例外,就是内存即时监控(请注意:防毒有许多即时监控,唯有内存即时监控才会与有时候与VFP发生冲突)。
所谓内存即时监控并不是去读取内存条中的数据,谁也没这么大的本事,它的原理就是专门关注于Windows系统目录下的system32子目录中的程序文件在运行中的状态。
我们知道,在Visual Foxpro 8.0 版本以前,其运行时刻文件是安装在system32目录中的;而向最终客户发布你的应用程序时,默认情况下,无论是VFP什么版本,其运行时刻文件均会被拷贝到system32目录中去。
防毒软件的内存即时监控的工作原理是这样的(这是瑞星公司首创的,瑞星软件也是狐友受害最深的):1、它会在Windows后台运行一个类似于Windows的模拟机(这有点像任天堂游戏模拟机和一些手机模拟机,还有现在时髦的linux下的Windows模拟机);2、它运行一个循环,挨个监视system32目录下的exe及dll文件是否被调用;3、倘若被调用,就拷贝一份到瑞星自己创建的隐含、系统目录中去,然后在那个模拟机中运行之,以便模拟其在Windows实际运行中的状态;4、在模拟运行中,看它是否有病毒发作的特征;5、如果有,就查找病毒特征码数据库;6、若在数据库中,找到了对应的特征码,便确定特征码所对应的病毒名称,否则,就按未知名的新病毒处理(这就是为什么有的VFP加密软件会被防毒软件误报病毒)。
由于VFP应用程序与运行时刻DLL库交互的太频繁了,使防毒软件的那个循环程序不断捕捉到VFP运行时刻库在进行新的数据响应,防毒软件便不断地试图拷贝它,以便进行新一轮的模拟。但你知道,无论是DBF还是SCX等等,只要是独占方式打开的(SCX与VCX总是被独占的,而DBF取决于你的设计),就不能被其它的程序所访问。但在Windows操作系统中,防毒软件所调用拷贝程序的系统优先级要高于你的程序的优先级,所以有时你的VFP程序会最终产生致命错误。
如何避免呢?你可以简单地关闭防毒软件,但如果让客户也像你这样做的话,就有霸道之嫌了。
聪明的你恐怕现在已经想到了:只要在发布你的应用程序时,将那些运行时刻库放到应用程序目录下就可以了!
同样,词霸软件本身也不会与你的程序发生冲突,只是在全屏取词的模式下才会如此。不过你的用户几乎不会遇到,因为你的程序几乎不会让他们在程序界面状态下直接打开某个数据表——仅在词霸的全屏取词程序试图通过独占模式下的数据表的窗口句柄,来访问里面的文本属性时,才会与其独占模式发生冲突。
第三大类是Visual Foxpro 自身的代码漏洞。比如VFP6.0版本的Textbox控件等等。现在版本的VFP,这样的错误少多了。关于Visual Foxpro 自身的代码漏洞导致c0000005异常的话题,早已被论坛上诸多的高手反复总结过了,我们的话题就不再展开了。
第四大类是硬件因素。
有些细节问题是最不被人所注意的。但其足以铸成大过。
“致命错误C0000005”是内存泄漏的症状,而不仅仅是内存溢出、除零(这就是Visual Foxpro 自身的代码Bug所导致的结果),还有一个原因就是申请到的堆栈意外不足。
在用电高峰期(例如夏季、或晚间的黄金时段),电压的突然不稳定,或许会非常微小,不至于迫使计算机意外重启,但或许会导致VFP系统在通过Windows消息机制向内存体申请堆栈时,得到Windows意外的反馈。
除了说服您的客户使用UPS外,您应该检查用电的负荷情况,比如检查打印机或台灯是否与计算机电源线一起接在一个多功能插座上,应该尽量避免这样,一些老式的打印机,在打印作业时会消耗很大的电流。
------------------------------------------
C000005排除一例
问题:
在使用菜单项呼叫这个表单的时候,出现 C000005 错误。
但在表单里呼叫这个表单的时候,一切正常。
接下来的菜单项里的呼叫全部正常。也就是说,一定要先由表单呼叫一次这个表单,否则不管什么时候都发引发 C000005 错误。
原本以为小问题,结果,动用人力物力都无法排除。
排错第 1 步:菜单生成器有缺陷,自己动手写一个代替它。解决了吗?没有
排错第 2 步:生成的菜单其实也是过程文件,改为用过程呼叫。解决再现了吗?是的。
*-- 重新确定问题源:在使用过程呼叫这个表单的时候,出现 C000005 错误。
排错第 3 步:重建项目,重新编译类库。解决了吗?没有。
排错第 4 步:更改表单名,更改控件名,注释所有事件,方法,过程。解决了吗?没有。
排错第 5 步:更改控件在表单的加载顺序,全部颠倒过来。解决了吗?没有。
排错第 6 步:移去数据环境。解决了吗?没有。
排错第 7 步:逐一从表单上移去控件,问题解决了吗?全部控件移除,问题解决。·¥#%#¥
排错第 8 步:新建空表单,从备份的表单上逐一复印控件,问题再出了吗?是的。
排错第 9 步:删除所有控件,仅留下最后那个复制过来的控件,问题再现了吗?是的!
重新确定问题源:类库内部出问题。
排错第 10 步:NODEFAULT 阻止所有事件与方法。问题解决了吗?没有!
重新确定问题源:不是方法或事件引发的这个错误。因为根本没有执行任何代码。
排错第 11 步:更改部份有意义的内部私用属性名称,问题解决了吗?没有!
排错第 12 步:决定要更改外部公用属性名与方法名……慢,你先杀了我吧!不可能,整个程序嵌入的事件设定与引用会全部消失,程序将崩溃。不如不排除这个错误。
排错第 13 步:苦思……为什么以前不会呢?
排错第 14 步:解开旧程序的类,逐一比较。正常。除了某些属性为了慎重,隐藏了起来。
排错第 15 步:那旧的类来代替它吗?这是不可能的。只会向上升级那有向下降级的。
排错第 16 步:无奈,顺手将隐藏的属性恢复为公共。
排错最后一步:奇迹出现,C00005 错误被处理!总耗时:16 小时。
复制备份的完整表单,编译,,,,一切正常。
将属性仍设为私有。正常。不信邪,再次设为隐藏。问题再见!!
活见鬼!!哪位兄弟能告诉我这是为什么?是 VFP 的问题还是程序的问题?
为什么类的部份属性设为隐藏并且一行代码也未进行操作,在使用过程呼叫会出 C000005 错误,在表单对象中的呼叫就不会?看来我们只有一个选择,慎用属性与方法隐藏。
唉,一天就这么过去了……好困。
[hunter__fox ]
从排除过程看来,出现这个C000000005错误的原因是这样的:
当隐藏了系统默订的属性与方法(以后统称内容)后,在过程中调用时,因为系统环境中没有同样的基类存在,第一次建立这些对象的实例须要访问一些被隐藏的内容,因此出现了C000000005错误------访问的内存被禁止。
而在通过表单调用时,那些被隐藏的内容在已有的表单及其控件中已经存在,系统中已经存在关于这些类的这些方法,因此,资源已经存在,就不会出现C000000005错误。
验证这一点,可以这样来试一下:
建立一个表单,其中仅有一个控件:Command1用于打开表单2。
表单2中使用一个自定义类Grid,它的属性 "RowSource "和 "RowSourceType "设为隐藏。
菜单就不用建了,因为一定会产生C000000005错误。
如果通过表单1调用表单2时产生了C000000005错误,则完全是因为隐藏属性的原因引起这一错误的。若没有产生这一错误,则表明,隐藏的内容并不是这灯C000000005错误的根源。
因为在表单1没有任何控件具有RowSource和RowSourceType属性,因此,在建立表单2的实体时,Grid控件的这两个属性无论如何都没有资源可供参考,如果仅是因为隐藏属性的问题,这里必然会产生同样的错误。
VFP报表中使用图形时常出现这样的问题,如果能够确定是因为隐藏属性还是其它的根本原因,对于从根本上解决这类问题将是大有作用的。
[coolyylu]
我认为问题的根本:对于属性隐藏,私有,公共的设置
对于老的类的某些属性你设置隐藏
1。这些隐藏属性是系统的还是你自己定义的?
在vfp里面,正常情况下,你设置一个属性为隐藏,那么系统一般会提示你“该属性找不到”。有些特殊的情况,当在你的系统(已经打开的窗口)占用了很多内存,这些找不到属性会引起系统崩溃(c00005的错误)。这种情况不多见。那么即使你设置的系统的属性为隐藏,那么也只会提示找不到。对于recordsource,rowsource等属性,很有可能引起c00005的错误,这个我不是太清楚。
2。你的vfp升级到pack5没有(如果是vfp6),如果是vfp7请升级到pack1。
Ⅱ 怎样发现内存泄露
一、内存泄漏的检查方法:
1.ccmalloc-Linux和Solaris下对C和C++程序的简单的使用内存泄漏和malloc调试库。
2.Dmalloc-Debug Malloc Library.
3.Electric Fence-Linux分发版中由Bruce Perens编写的malloc()调试库。
4.Leaky-Linux下检测内存泄漏的程序。
5.LeakTracer-Linux、Solaris和HP-UX下跟踪和分析C++程序中的内存泄漏。
6.MEMWATCH-由Johan Lindh编写,是一个开放源代码C语言内存错误检测工具,主要是通过gcc的precessor来进行。
7.Valgrind-Debugging and profiling Linux programs, aiming at programs written in C and C++.
8.KCachegrind-A visualization tool for the profiling data generated by Cachegrind and Calltree.
9.IBM Rational PurifyPlus-帮助开发人员查明C/C++、托管.NET、java和VB6代码中的性能和可靠性错误。PurifyPlus 将内存错误和泄漏检测、应用程序性能描述、代码覆盖分析等功能组合在一个单一、完整的工具包中。
二、内存泄漏的简单介绍:
内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。
内存泄漏形象的比喻是“操作系统可提供给所有进程的存储空间正在被某个进程榨干”,最终结果是程序运行时间越长,占用存储空间越来越多,最终用尽全部存储空间,整个系统崩溃。所以“内存泄漏”是从操作系统的角度来看的。这里的存储空间并不是指物理内存,而是指虚拟内存大小,这个虚拟内存大小取决于磁盘交换区设定的大小。由程序申请的一块内存,如果没有任何一个指针指向它,那么这块内存就泄漏了。
Ⅲ 求教为什么写关于Socket的脚本Unity3D就卡死
我说一下我的想法,看看对你是不是用。
第一,如果你的客户端socket在连接服务器的时候是在主线程做的,那么在报告连接服务器之前,下层会有多次尝试的情况,这就是会卡死的原因。我自己遇到这个问题的时候有关连接服务器的部分开了一个专门的线程来处理,没有出现卡死的情况。
第二,就是有关资源的问题。例如你的程序不小心在主线程弄了个死循环、其他资源或者脚本导致的内存泄漏等等原因都会使你的程序卡死,你看一下是不是这些东西间接导致的你的soclet卡死了。
第三,不知道你的服务器使用什么做的,服务器程序并发性怎么样,还有硬件能不能支持都需要考虑,是不是这一块卡死的。
如果不麻烦,你可以多说一点关于这个卡死的具体情况,我看看我知不知道。
Ⅳ loadrunner录制的脚本会导致内存泄漏吗
内存泄漏是待测系统的问题
loadrunner 只不过是通过施压 让该问题暴露出来
Ⅳ 怎么排查这些内存泄漏
最原始的内存泄露测试
重复多次操作关键的可疑的路径,从内存监控工具中观察内存曲线,是否存在不断上升的趋势且不会在程序返回时明显回落。
这种方式可以发现最基本,也是最明显的内存泄露问题,对用户价值最大,操作难度小,性价比极高。
MAT内存分析工具
2.1 MAT分析heap的总内存占用大小来初步判断是否存在泄露
在Devices 中,点击要监控的程序。
点击Devices视图界面中最上方一排图标中的“Update Heap”
点击Heap视图
点击Heap视图中的“Cause GC”按钮
到此为止需检测的进程就可以被监视。Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,一般情况下,这个值的大小决定了是否会有内存泄漏。可以这样判断:
进入某应用,不断的操作该应用,同时注意观察data object的Total Size值,正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况。
所以说虽然我们不断的操作会不断的生成很多对象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平;反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落。随着操作次数的增多Total Size的值会越来越大,直到到达一个上限后导致进程被杀掉。
2.2 MAT分析hprof来定位内存泄露的原因所在。
这是出现内存泄露后使用MAT进行问题定位的有效手段。
A)Dump出内存泄露当时的内存镜像hprof,分析怀疑泄露的类:
B)分析持有此类对象引用的外部对象
C)分析这些持有引用的对象的GC路径
D)逐个分析每个对象的GC路径是否正常
从这个路径可以看出是一个antiRadiationUtil工具类对象持有了MainActivity的引用导致MainActivity无法释放。此时就要进入代码分析此时antiRadiationUtil的引用持有是否合理(如果antiRadiationUtil持有了MainActivity的context导致节目退出后MainActivity无法销毁,那一般都属于内存泄露了)。
2.3 MAT对比操作前后的hprof来定位内存泄露的根因所在。
为查找内存泄漏,通常需要两个 Dump结果作对比,打开 Navigator History面板,将两个表的 Histogram结果都添加到 Compare Basket中去
A) 第一个HPROF 文件(usingFile > Open Heap Dump ).
B)打开Histogram view.
C)在NavigationHistory view里 (如果看不到就从Window >show view>MAT- Navigation History ), 右击histogram然后选择Add to Compare Basket .
D)打开第二个HPROF 文件然后重做步骤2和3.
E)切换到Compare Basket view, 然后点击Compare the Results (视图右上角的红色”!”图标)。
F)分析对比结果
可以看出两个hprof的数据对象对比结果。
通过这种方式可以快速定位到操作前后所持有的对象增量,从而进一步定位出当前操作导致内存泄露的具体原因是泄露了什么数据对象。
注意:
如果是用 MAT Eclipse 插件获取的 Dump文件,不需要经过转换则可在MAT中打开,Adt会自动进行转换。
而手机SDk Dump 出的文件要经过转换才能被 MAT识别,Android SDK提供了这个工具 hprof-conv (位于 sdk/tools下)
首先,要通过控制台进入到你的 android sdk tools 目录下执行以下命令:
./hprof-conv xxx-a.hprof xxx-b.hprof
例如 hprof-conv input.hprof out.hprof
此时才能将out.hprof放在eclipse的MAT中打开。
手机管家内存泄露每日监控方案
目前手机管家的内存泄露每日监控会自动运行并输出是否存在疑似泄露的报告邮件,不论泄露对象的大小。这其中涉及的核心技术主要是AspectJ,MLD自研工具(原理是虚引用)和UIAutomator。
3.1 AspectJ插桩监控代码
手机管家目前使用一个ant脚本加入MLD的监控代码,并通过AspectJ的语法实现插桩。
使用AspectJ的原因是可以灵活分离出项目源码与监控代码,通过不同的编译脚本打包出不同用途的安装测试包:如果测试包是经过Aspect插桩了MLD监控代码的话,那么运行完毕后会输出指定格式的日志文件,作为后续分析工作的数据基础。
3.2 MLD实现监控核心逻辑
这是手机管家内的一个工具工程,正式打包不会打入,BVT等每日监控测试包可以打入。打入后可以通过诸如addObject接口(通过反射去检查是否含有该工具并调用)来加入需要监控的检测对象,这个工具会自动在指定时机(如退出管家)去检测该对象是否发生泄漏。
这个内存泄露检测的基本原理是:
虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用必须和引用队列(ReferenceQueue)联合使用(在虚引用函数就必须关联指定)。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,自动把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。
基于以上原理,MLD工具在调用接口addObject加入监控类型时,会为该类型对象增加一个虚引用,注意虚引用并不会影响该对象被正常回收。因此可以在ReferenceQueue引用队列中统计未被回收的监控对象是否超过指定阀值。
利用PhantomReferences(虚引用)和ReferenceQueue(引用队列),当PhantomReferences被加入到相关联的ReferenceQueue时,则视该对象已经或处于垃圾回收器回收阶段了。
MLD监控原理核心
目前手机管家已对大部分类完成内存泄露的监控,包括各种activity,service和view页面等,务求在技术上能带给用户最顺滑的产品体验。
接下来简单介绍下这个工具的判断核心。根据虚引用监控到的内存状态,需要通过多种策略来判断是否存在内存泄露。
(1)最简单的方式就是直接在加入监控时就为该类型设定最大存在个数,举个例子,各个DAO对象理论上只能存在最多一个,因此一旦出现两个相同的DAO,那一般都是泄露了;
(2)第二种情况是在页面退出程序退出时,检索gc后无法释放的对象列表,这些对象类型也会成为内存泄露的怀疑对象;
(3)最后一种情况比较复杂,基本原理是根据历史操作判断对象数量的增长幅度。根据对象的增长通过最小二乘法拟合出该对象类型的增长速度,如果超过经验值则会列入疑似泄露的对象列表。
3.3 UIAutomator完成重复操作的自动化
最后一步就很简单了。这么多反复的UI操作,让人工来点就太浪费人力了。我们使用UIAutomator来进行自动化操作测试。
目前手机管家的每日自动化测试已覆盖各个功能的主路径,并通过配置文件的方式来灵活驱动用例的增删改查,最大限度保证了随着版本推移用例的复用价值。
至此手机管家的内存泄露测试方案介绍完毕,也欢迎各路牛人交流沟通更多更强的内存泄露工具盒方案!
腾讯Bugly简介
Bugly是腾讯内部产品质量监控平台的外发版本,其主要功能是App发布以后,对用户侧发生的Crash以及卡顿现象进行监控并上报,让开发同学可以第一时间了解到App的质量情况,及时机型修改。目前腾讯内部所有的产品,均在使用其进行线上产品的崩溃监控。
Ⅵ javascript setTimeout递归会造成内存泄漏吗
前端开发,热爱生活
var call = function(x) {
console.log(x++);
setTimeout(function() { call(x); }, 1);
};
call(0);
以这段代码为例,的确x这个变量会一直存在在内存之中,但这么一个变量还不至于让内存达到溢
出。并且可以在chrome Dev Tool中模拟一次垃圾回收结果:
可以看到js heap一直在增加可以看到js heap一直在增加
但是console 依然在跑,其实这已经算是内存泄露了。但是console 依然在跑,其实这已经算是内存泄露了。
如果内存会周期性地按时增长,泄露最终将导致浏览器变慢或者停止执行脚本。从性能优化角度来讲已经是不得不做的事情了。是想如果循环执行的代码中包含了一个大数组new Array(1000000).join('*'),那是非常危险的。
一般setTimeout递归是在做轮询,这会需要给一个结束条件,执行clearTimeout。
Ⅶ 内存泄露监控脚本,怎么写
LR模拟大量user运行比较长的时间 监控待测服务器的内存占用 正常情况下应该是有申请有释放 不构成泄漏 如果内存占用一直在增加 没有下降的区段 就是存在内存泄漏无疑了 斜率越大 泄漏越快
Ⅷ 嵌入式linux怎么检内存泄漏雨
1. 在需要内存泄漏检查的代码的开始调用void mtrace(void) (在mcheck.h中? 有声明). mtrace为malloc等函数安装hook, 用于记录内存分配信息.在需要内存泄漏检查的代码的结束调用void muntrace(void).
注意: 一般情况下不要调用muntrace, 而让程序自然结束. 因为可能有些释放内存代码要到muntrace之后才运行.
2. 用debug模式编译被检查代码(-g或-ggdb)
3. 设置环境变量MALLOC_TRACE为一文件名, 这一文件将存有内存分配信息.
4. 运行被检查程序, 直至结束或muntrace被调用.
5. 用mtrace命令解析内存分配Log文件($MALLOC_TRACE)
(mtrace foo $MALLOC_TRACE, where foo is the executible name)
如果有内存泄漏, mtrace会输出分配泄漏
内存的代码位置,以及分配数量.
附加说明
1. 可以将mtrace, muntrace放入信号处理函数(USR1, USR2), 以动态地进行内存泄漏检查控制.
2. mtrace是个perl代码, 如果你对符号地址与代码文本的转换感兴趣, 可以读一下.
3. again, 尽量不要用muntrace()
For C++ Leak:
检查内存泄漏的方法除glibc提供外;还可以试试一些专用的程序。
很奇怪,redhat 9 居然不带mtrace perl脚本,只好下载gcc源码编译了
wget --passive-ftp ftp://rpmfind.net/linux/redhat/9 ... -2.3.2-11.9.src.rpm
rpm -ivh glibc*.src.rpm
cd /usr/src/redhat/SPECS/
rpmbuild -ba glibc-9.spec
cd /var/tmp/glibc-2.3.2-root/usr/bin/
cp mtrace /usr/bin/
调试方法如下:
vi a.c
1 #include
2
3 int main()
4 {
5 mtrace();
6 malloc(10);
7 malloc(16);
8 return 0;
9 }
$gcc -g a.c #记得编译带-g调试选项
$export MALLOC_TRACE=a.log
$./a.out
$unset MALLOC_TRACE #记得执行完后unset变量,否则可能运行其他命令可能覆盖log
$mtrace a.out a.log
Memory not freed:
-----------------
Address Size Caller
0x09b08378 0xa at /XXX/a.c:6
0x09b08388 0x10 at /XXX/a.c:7
可以看到,会显示未释放动态空间的代码具体位置。
Ⅸ 如何使用JProfiler查找内存泄漏
先运行的java程序,然后打开jprofiler,绑定正在运行的程序,就可以在界面看到内存的使用情况。