当前位置:首页 > 内存 > 正文

c内存泄露怎么排查(jvm内存泄露怎么排查)

  • 内存
  • 2024-06-09 07:42:48
  • 5717

一、如何检查内存泄露问题1.如何检查内存泄漏:
oc-Linux和Solaris下用于C和C++程序的简单内存泄漏库和malloc调试库。
 -一个检测Linux内存泄漏的程序。
CHbyJohanLindh,是一个开源的C内存错误检测工具,主要通过pre-gcc版本。
程序的Valgrind调试和分析,针对用C和C++编写的程序。
grind-可视化工具,用于分析Cachegrind和Calltree生成的数据。NET、Java和VB6。PurifyPlus将内存错误和泄漏检测、应用程序性能分析、代码覆盖率分析等整合到一个完整的工具集中。
2、内存泄漏简介:
内存泄漏也称为“存储泄漏”。动态存储分配函数动态开辟的空间在使用后并没有释放,导致内存一直被占用。直到节目结束。(其实说白了,这就是说内存空间在使用后没有被回收),这就是所谓的内存泄漏。
内存泄漏的比喻是“操作系统可以为所有进程提供的存储空间正在被特定进程耗尽”。最终的结果就是程序运行的时间越长,花费的时间就越多,存储空间也就越多,最终所有的存储空间都被耗尽,整个系统崩溃。所以“内存泄漏”是从操作系统的角度来看的。这里的存储空间不是指物理内存,而是指虚拟内存的大小,而这个虚拟内存的大小取决于磁盘交换区的大小。如果程序申请的这块内存没有任何指针指向它,就会导致内存泄漏。


二、如何测试软件的内存泄露呢,是有什么工具吗我很高兴回答您的问题。
如何检测内存泄漏:
检测内存泄漏的关键是能够拦截对分配内存和释放内存的函数的调用。通过重写这两个函数,我们可以跟踪每块内存的生命周期,比如每分配一块内存成功,它的指针就会被添加到全局链表中,每次释放一块内存,它就会被添加到全局链表中。到全局列表的指针被从列表中删除。这样,当程序结束时,链表中剩余的指针都指向未释放的内存。这里简单介绍一下内存泄漏检测的基本原理,详细算法请参考SteveMaguire的《WritingSolidCode》。
如果想要检测堆内存泄漏,需要绕过malloc/realloc/free和new/delete(实际上new/delete最后也使用了malloc/free,所以只需要绕过前)组)。对于其他泄漏,可以使用类似的方法来绕过相应的分配和释放函数。例如,检测BSTR泄漏,需要绕过SysAllocString/SysFreeString;检测HMENU泄漏,需要绕过CreateMenu/DestroyMenu;(有些资源有多个分配函数,但只有一个输出函数。例如,SysAllocStringLen也可以用来分配BSTR。这种情况下,需要绕过多个分配函数)
在Windows平台上,检测一般常用的内存泄漏工具有3种,插件检测工具内置检测功能,如Purify、BoundsChecker等。以及WindowsNT附带的PerformanceMonitor的使用;这三个工具各有优缺点,虽然MSC-RuntimeLibrary的功能比插件工具弱,但它是免费的,虽然PerformanceMonitor无法标记出现问题的代码,但它可以检测隐式内存泄漏。这是其他两类工具无能为力的地方。


三、C语言中的内存泄露怎样避免与检测堆经常出现两类问题:1.释放或覆盖仍在使用的内存(称为:“内存损坏”)。2.不再使用的内存不会被释放(称为:“内存泄漏”)。这是调试时最难发现的问题之一
某些程序不需要管理其动态内存使用。当需要内存时,他们只需分配它,而不必担心如何释放它。此类程序包括编译器和其他运行一定(或有限)时间然后终止的程序。当此类程序结束时,所有内存都会自动恢复。仔细检查每块内存是否需要回收是浪费时间,因为它永远不会被再次使用。
其他程序的生存时间较长。一些工具(例如日历管理器、邮件工具和操作系统技术)通常需要连续运行数天甚至数周,并且必须管理动态内存分配和回收。由于C语言一般不使用垃圾收集器(它自动识别并回收不再使用的内存块),因此这些C程序在使用malloc()和free()时必须非常小心。
堆经常出现两类问题:
1释放或覆盖仍在使用的内存(称为:“内存损坏”)。
2不再使用的内存不会被释放(称为:“内存泄漏”)。
这是调试时最难发现的问题之一。如果程序在不再使用分配的内存块时不释放它们,则进程将分配越来越多的内存,而不会释放不再使用的部分内存。
避免内存泄漏
每当调用malloc分配内存时,注意稍后再调用相应的free释放。
如果你不知道如何调用free来对应之前的malloc,那么很可能就发生了内存泄漏
一个简单的方法是在可能的情况下使用alloca()动态分配内存来避免上述情况。当退出调用alloca的函数时,它分配的内存将被自动释放。
显然,这不适用于在创建它们的函数之后仍然存在的结构。但是,如果对象的生命周期在函数完成之前到期,则堆栈上的动态内存分配是一个低成本选项。有些人不鼓励使用alloca,因为它在将来并不总是可移植的。如果处理器不支持硬件中的堆栈,则alloca()很难有效实现。
我们使用术语“内存泄漏”是因为稀缺资源正在被进程清空。内存泄漏的主要明显症状是罪魁祸首进程的速度变慢。原因是大进程更有可能被系统切换以允许其他进程运行,并且大进程切换进出需要更长的时间。即使泄漏的内存没有被引用,它仍然可以存在于页面中(内容当然是垃圾),这会增加程的工作页面数量并降低性能。另一点需要注意的是,内存泄漏通常比忘记释放的数据结构更难处理,因为malloc()分配的内存通常会舍入到大于请求量的下一个2的整数次方。(就像申请212B一样,会四舍五入到256B)。在资源有限的情况下,即使引起内存泄漏的进程没有运行,整个系统也会变慢。理论上,进程的大小存在上限,该上限因操作系统而异。在当前版本的SunOS中,进程的最大地址空间可达4GB。事实上,当进程泄漏的内存远未达到这个数量时,磁盘交换区就已经耗尽了。
如何检测内存泄漏
监视内存泄漏是一个两步过程。首先使用swap命令观察有多少交换空间可用:
/usr/sbin/swap-s
total:17228Kbytesallocated+5396Kreserved=22626Kused,29548Kavailable。
一会儿就写这个或2运行此命令三到四次以查看可用交换空间是否正在减少。您还可以使用其他/usr/bin/*stat工具,例如netstat、vmstat等。如果发现带中的内存已分配但从未释放,一种可能的解释是进程存在内存泄漏。