⑴ 在linux中运行的C程序出现内存泄漏现象,怎么解决
内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
可以使用相应的软件测试工具对软件进行检测。
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. Leak
Monitor-一个Firefox扩展,能找出跟Firefox相关的泄漏类型。
10. IE Leak Detector
(Drip/IE Sieve)-Drip和IE Sieve leak
detectors帮助网页开发员提升动态网页性能通过报告可避免的因为IE局限的内存泄漏。
11. Windows Leaks
Detector-探测任何Win32应用程序中的任何资源泄漏(内存,句柄等),基于Win API调用钩子。
12. SAP Memory
Analyzer-是一款开源的JAVA内存分析软件,可用于辅助查找JAVA程序的内存泄漏,能容易找到大块内存并验证谁在一直占用它,它是基于Eclipse
RCP(Rich Client Platform),可以下载RCP的独立版本或者Eclipse的插件。
13. DTrace-即动态跟踪Dynamic
Tracing,是一款开源软件,能在Unix类似平台运行,用户能够动态检测操作系统内核和用户进程,以更精确地掌握系统的资源使用状况,提高系统性能,减少支持成本,并进行有效的调节。
14. IBM Rational PurifyPlus-帮助开发人员查明C/C++、托管.NET、Java和VB6代码中的性能和可靠性错误。PurifyPlus
将内存错误和泄漏检测、应用程序性能描述、代码覆盖分析等功能组合在一个单一、完整的工具包中。
15. Parasoft Insure++-针对C/C++应用的运行时错误自动检测工具,它能够自动监测C/C++程序,发现其中存在着的内存破坏、内存泄漏、指针错误和I/O等错误。并通过使用一系列独特的技术(SCI技术和变异测试等),彻底的检查和测试我们的代码,精确定位错误的准确位置并给出详细的诊断信息。能作为Microsoft
Visual C++的一个插件运行。
16. Compuware DevPartner for Visual C++ BoundsChecker
Suite-为C++开发者设计的运行错误检测和调试工具软件。作为Microsoft Visual Studio和C++ 6.0的一个插件运行。
17. Electric Software GlowCode-包括内存泄漏检查,code
profiler,函数调用跟踪等功能。给C++和.Net开发者提供完整的错误诊断,和运行时性能分析工具包。
18. Compuware DevPartner Java
Edition-包含Java内存检测,代码覆盖率测试,代码性能测试,线程死锁,分布式应用等几大功能模块。
19. Quest JProbe-分析Java的内存泄漏。
20. ej-technologies JProfiler-一个全功能的Java剖析工具,专用于分析J2SE和J2EE应用程序。它把CPU、执行绪和内存的剖析组合在一个强大的应用中。JProfiler可提供许多IDE整合和应用服务器整合用途。JProfiler直觉式的GUI让你可以找到效能瓶颈、抓出内存泄漏、并解决执行绪的问题。4.3.2注册码:A-G666#76114F-1olm9mv1i5uuly#0126
21. BEA JRockit-用来诊断Java内存泄漏并指出根本原因,专门针对Intel平台并得到优化,能在Intel硬件上获得最高的性能。
22. SciTech Software AB .NET Memory
Profiler-找到内存泄漏并优化内存使用针对C#,VB.Net,或其它.Net程序。
23. YourKit .NET & Java Profiler-业界领先的Java和.NET程序性能分析工具。
24. AutomatedQA AQTime-AutomatedQA的获奖产品performance profiling和memory
debugging工具集的下一代替换产品,支持Microsoft, Borland, Intel, Compaq 和
GNU编译器。可以为.NET和Windows程序生成全面细致的报告,从而帮助您轻松隔离并排除代码中含有的性能问题和内存/资源泄露问题。支持.Net
1.0,1.1,2.0,3.0和Windows 32/64位应用程序。
25. JavaScript Memory Leak Detector-微软全球产品开发欧洲团队(Global Proct
Development- Europe team, GPDE)
发布的一款调试工具,用来探测JavaScript代码中的内存泄漏,运行为IE系列的一个插件。
⑵ 在linux写的C语言程序,使用top查看内存的使用率不断的增加,直到程序死机
根据你的描述,我判断很有可能是你的程序中有死循环造成的,是不是内存泄露还需要进一步判断。 linux的内存管理和windows不同,linux的内存分配原则是优先使用物理内存,只有在物理内存满足不了需要时,才进行物理内存和虚拟内存的交换;windows则是根据一定的比例进行虚拟内存和物理内存的交换;因此,linux系统的物理内存使用量是不断增减,指导95%以上才会稳定,其实是linux为提高系统性内进行的物理内存使用优化,这样能够提高物理内存使用率,提高性能。 如果你的进程关闭,linux系统也不会马上释放内存,等到其他进程请求内存而且物理内存不足时才去释放。 这里linux的内存管理机制。
⑶ linux系统,c语言,内存溢出问题。
那是因为你接受到的数据大于分配的内存了,可以设置一个计数器记录接受到的数据的总的大小,如果大于缓冲区的大小,就存到开始的地方。
⑷ Linux下使用能否使用C共享内存存放指针
共享内存指在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存 (shared memory)是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
共享内存的创建
共享内存是存在于内核级别的一种资源,在shell中可以使用ipcs命令来查看当前系统IPC中的状态,在文件系统/proc目录下有对其描述的相应文件。函数shmget可以创建或打开一块共享内存区。函数原型如下: #include <sys/shm.h> int shmget( key_t key, size_t size, int flag ); 函数中参数key用来变换成一个标识符,而且每一个IPC对象与一个key相对应。当新建一个共享内存段时,size参数为要请求的内存长度(以字节为单位)。 注意:内核是以页为单位分配内存,当size参数的值不是系统内存页长的整数倍时,系统会分配给进程最小的可以满足size长的页数,但是最后一页的剩余部分内存是不可用的。 当打开一个内存段时,参数size的值为0。参数flag中的相应权限位初始化ipc_perm结构体中的mode域。同时参数flag是函数行为参数,它指定一些当函数遇到阻塞或其他情况时应做出的反应。shmid_ds结构初始化如表14-4所示。
编辑本段初始化
shmid_ds结构数据 初 值 shmid_ds结构数据 初 值
shm_lpid 0 shm_dtime 0
shm_nattach 0 shm_ctime 系统当前值
shm_atime 0 shm_segsz 参数 size
下面实例演示了使用shmget函数创建一块共享内存。程序中在调用shmget函数时指定key参数值为IPC_PRIVATE,这个参数的意义是创建一个新的共享内存区,当创建成功后使用shell命令ipcs来显示目前系统下共享内存的状态。命令参数-m为只显示共享内存的状态。 (1)在vi编辑器中编辑该程序如下: 程序清单14-8 create_shm.c 使用shmget函数创建共享内存 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdlib.h> #include <stdio.h> #define BUFSZ 4096 int main ( void ) printf ( "successfully created segment : %d \n", shm_id ) ; system( "ipcs -m"); /*调用ipcs命令查看IPC*/ exit( 0 ); } (2)在shell中编译该程序如下: $gcc create_shm.c–o create_shm (3)在shell中运行该程序如下: $./ create_shm successfully created segment : 2752516 ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 65536 root 600 393216 2 dest 0x00000000 2654209 root 666 4096 0 0x0056a4d5 2686978 root 600 488 1 0x0056a4d6 2719747 root 600 131072 1 0x00000000 2752516 root 666 4096 0 上述程序中使用shmget函数来创建一段共享内存,并在结束前调用了系统shell命令ipcs –m来查看当前系统IPC状态。
编辑本段共享内存的操作
由于共享内存这一特殊的资源类型,使它不同于普通的文件,因此,系统需要为其提供专有的操作函数,而这无疑增加了程序员开发的难度(需要记忆额外的专有函数)。使用函数shmctl可以对共享内存段进行多种操作,其函数原型如下: #include <sys/shm.h> int shmctl( int shm_id, int cmd, struct shmid_ds *buf ); 函数中参数shm_id为所要操作的共享内存段的标识符,struct shmid_ds型指针参数buf的作用与参数cmd的值相关,参数cmd指明了所要进行的操作,其解释如表14-5所示。
编辑本段cmd参数详解
cmd的值 意 义
IPC_STAT 取shm_id所指向内存共享段的shmid_ds结构,对参数buf指向的结构赋值
IPC_SET 使用buf指向的结构对sh_mid段的相关结构赋值,只对以下几个域有作用,shm_perm. uid shm_perm.gid以及shm_perm.mode 注意此命令只有具备以下条件的进程才可以请求: 1.进程的用户ID等于shm_perm.cuid或者等于shm_perm.uid 2.超级用户特权进程
IPC_RMID 删除shm_id所指向的共享内存段,只有当shmid_ds结构的shm_nattch域为零时,才会真正执行删除命令,否则不会删除该段 注意此命令的请求规则与IPC_SET命令相同
SHM_LOCK 锁定共享内存段在内存,此命令只能由超级用户请求
SHM_UNLOCK 对共享内存段解锁,此命令只能由超级用户请求
使用函数shmat将一个存在的共享内存段连接到本进程空间,其函数原型如下: #include <sys/shm.h> void *shmat( int shm_id, const void *addr, int flag ); 函数中参数shm_id指定要引入的共享内存,参数addr与flag组合说明要引入的地址值,通常只有2种用法,addr为0,表明让内核来决定第1个可以引入的位置。addr非零,并且flag中指定SHM_RND,则此段引入到addr所指向的位置(此操作不推荐使用,因为不会只对一种硬件上运行应用程序,为了程序的通用性推荐使用第1种方法),在flag参数中可以指定要引入的方式(读写方式指定)。 %说明:函数成功执行返回值为实际引入的地址,失败返回–1。shmat函数成功执行会将shm_id段的shmid_ds结构的shm_nattch计数器的值加1。 当对共享内存段操作结束时,应调用shmdt函数,作用是将指定的共享内存段从当前进程空间中脱离出去。函数原型如下: #include <sys/shm.h> int shmdt( void *addr); 参数addr是调用shmat函数的返回值,函数执行成功返回0,并将该共享内存的shmid_ds结构的shm_nattch计数器减1,失败返回–1。 下面实例演示了操作共享内存段的流程。程序的开始部分先检测用户是否有输入,如出错则打印该命令的使用帮助。接下来从命令行读取将要引入的共享内存ID,使用shmat函数引入该共享内存,并在分离该内存之前睡眠3秒以方便查看系统IPC状态。 (1)在vi编辑器中编辑该程序如下: 程序清单14-9 opr_shm.c 操作共享内存段 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdlib.h> #include <stdio.h> int main ( int argc, char *argv[] ) shm_id = atoi(argv[1]); /*得到要引入的共享内存段*/ /*引入共享内存段,由内核选择要引入的位置*/ if ( (shm_buf = shmat( shm_id, 0, 0)) < (char *) 0 ) printf ( " segment attached at %p\n", shm_buf ); /*输出导入的位置*/ system("ipcs -m"); sleep(3); /* 休眠 */ if ( (shmdt(shm_buf)) < 0 ) printf ( "segment detached \n" ); system ( "ipcs -m " ); /*再次查看系统IPC状态*/ exit ( 0 ); } (2)在shell中编译该程序如下: $gcc opr_shm.c–o opr_shm (3)在shell中运行该程序如下: $./ opr_shm 2752516 segment attached at 0xb7f29000 ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 65536 root 600 393216 2 dest 0x00000000 2654209 root 666 4096 0 0x0056a4d5 2686978 root 600 488 1 0x0056a4d6 2719747 root 600 131072 1 0x00000000 2752516 root 666 4096 1 segment detached ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 65536 root 600 393216 2 dest 0x00000000 2654209 root 666 4096 0 0x0056a4d5 2686978 root 600 488 1 0x0056a4d6 2719747 root 600 131072 1 0x00000000 2752516 root 666 4096 0 上述程序中从命令行中读取所要引入的共享内存ID,并使用shmat函数引入该内存到当前的进程空间中。注意在使用shmat函数时,将参数addr的值设为0,所表达的意义是由内核来决定该共享内存在当前进程中的位置。由于在编程的过程中,很少会针对某一个特定的硬件或系统编程,所以由内核决定引入位置也就是shmat推荐的使用方式。在导入后使用shell命令ipcs –m来显示当前的系统IPC的状态,可以看出输出信息中nattch字段为该共享内存时的引用值,最后使用shmdt函数分离该共享内存并打印系统IPC的状态。
编辑本段共享内存使用注意事项
共享内存相比其他几种方式有着更方便的数据控制能力,数据在读写过程中会更透明。当成功导入一块共享内存后,它只是相当于一个字符串指针来指向一块内存,在当前进程下用户可以随意的访问。缺点是,数据写入进程或数据读出进程中,需要附加的数据结构控制,共享内存通信数据结构示意如图14-9所示。
编辑本段结构示意
%说明:图中两个进程同时遵循一定的规则来读写该内存。同时,在多进程同步或互斥上也需要附加的代码来辅助共享内存机制。 在共享内存段中都是以字符串的默认结束符为一条信息的结尾。每个进程在读写时都遵守这个规则,就不会破坏数据的完整性。
另外,站长团上有产品团购,便宜有保证
⑸ linux下c语言大内存分配问题
数组太大,超出 0x10000000 或 (268435456)
可以这样:
char *x;
main()
{
x=(char *) malloc(268435456);
if(!x) printf("failed");
else printf("success");
}
⑹ Linux内核编程时(我要编写系统调用内存分配)要用到malloc函数,但是Linux不允许访问C库中的malloc函数
Linux内核运行在X86机器的物理内存管理使用简单平坦内存模型,每个用户进程内存(虚拟内存)地址范围为从0到TASK_SIZE字节,超过此内存的限制不能被用户访问。用户进程被分为几个逻辑段,成为虚拟内存区域,内核跟踪和管理用户进程的虚拟内存区域
⑺ linux的C语言开线程后如何归还使用的内存
线程自身用的内存,是在栈上系统自动分配,或自己配置(操作系统提供了可编程配置参数,但也是操作系统在管理)。线程运行完成后返回栈内存操作系统会自动回收。需要注意的是,如果是在线程运行中中,使用malloc或操作系统的内存分配函数分配的内存,需要在线程返回前或返回后显示释放。自己编写代码,显示调用free或操作系统提供的内存释放函数。
⑻ linux系统下的C语言中的虚拟内存分配问题
因为内存管理由glibc管理,当它认为需要释放时,才释放前提是,你已经让它释放了,说的简单就是,你让它释放,它要过一段时间等合适了,再释放
⑼ linux怎么管理空闲内存
内存组织层次:页式管理—>(numa)—>node的zonelist—>32位DMA/NORMAL/HIGHMEM三个区,64位没有高端内存—>伙伴分配系统—>slab/slub/slob
2.创建进程时内存分配:实际上只分配task_struct和thread_info的内存,而且很可能是从slab缓存中分配的,当进程运行时由于缺页中断,才由内核层具体分配物理内存并与vm挂接
3.malloc是c runtime中的实现,是上层库的内存分配层,至于内核层的,可以看看__alloc_pages/alloc_pages/kmalloc(小内存直接slab,大内存还是alloc_pages)/vmalloc(alloc_page分配不连续的物理页,映射到连续的vm_struct中的pages指针数组)/vmap/map_vm_area等几个函数