分享
 
 
 

我对编程中的内存泄露问题的探索

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

关于编程中的内存泄露问题的探索

我一直以来很这个内存泄露问题有着自己的担心与探索,现略谈一下我自己的体会。

我个人认为,一个好的编程的习惯(甚至可以提高的水平的高度)就是应该对程序的运行最好作到心中有数。这里的心中有数就是说,你对程序中各种对象(这里的对象是泛指那些占有系统资源的变量(包括各种基本类型变量和类实例对象变量等))的生存(包括从分配到释放)有完全清楚的认识,知道编译器是如何生成他们、释放他们,这中间有两个层次。

第一层是你对你所使用的语言、工具对内存的管理应该了如指掌,应试图守她的规矩、当老实人,比方说既然在C语言中你用malloc分配了一片内存空间,你应该在适当(我个人认为应在不在使用它的最内层程序块)的时候用free去释放它,至于语言所提供的内存管理函数、例程是否能够作到完美无缺(也就是说,free能否真消除malloc的所有影响)那是第二层应该考虑的事情了。

举个例子,函数中的局部变量一般编译器的实现是这样:在调用者的栈空间临时分配空间,随着函数的返回,一般都会退栈释放这些临时变量所占的存储空间(比如说在x86平台下的带参数的返回指令 RET n就有利于编译器实现这一功能)。当了解了这些背景知识后,你就可以心安理得地放心使用这些局部变量而不担心释放他们了!

(关于堆)

但是对于动态的存储分配就不这么简单了,试想你在C语言中用malloc函数分配了指定字节数量的内存,那么编译器(甚至是操作系统)都干了些什么呢?就我的理解,C的库函数malloc一般都是通过在程序运行的堆空间来分配空间而实现。就Win32平台而言,操作系统(就是Windows!)显式地提供了堆管理(分配、释放)API函数支持(如:HeapAlloc, GetProcessHeap, HeapCreate, HeapDestroy, HeapFree, HeapReAlloc, HeapSize等),这些函数给我们如下信息:在进程(我们可以理解为运行中的程序)的地址空间(是一个逻辑地址空间概念,以后我会专门解释)存在一个叫堆的内存空间可供程序使用(实际上,Win32为每个进程保留了一个缺省堆,其尺寸可以在程序的链接过程中通过参数来改变。另外还可创建新的供本进程使用的堆,正如API函数HeapCreate所作的工作那样),C库函数malloc、free就在内部通过调用系统提供的API堆管理函数为程序提供内存分配、释放。那Win32是如何能够做到释放的完整无误的呢,这个以后再讨论(但显然应该为每次内存分配予以记帐,这样就能在释放空间时做到准确(不会多也不会少释放空间))。其它操作系统也通过相应的系统功能调用来提供类似的功能。

(关于内存管理)

那么操作系统是如何管理进程的存储空间甚至其他系统资源(如代表打开的文件对象的句柄)的呢?因为这个问题不搞清楚,你就会有疑虑:我的程序运行结束后,如果操作系统不能完全释放本程序所占有的资源(泛指存储空间及其它系统资源,下同)?那么我们的程序多次运行,或其他具有类似问题的应用程序的经常运行就会逐渐耗尽系统的资源,从而导致系统不得不重启。从这里也可以看出,一个操作系统能够多长时间不需重启能够反映出该操作系统在资源管理方面的能力,是系统健壮性的重要体现,因为尽管程序员们在程序设计时程序力图避免未释放的资源,但总不免有不是做得很好的,而且这种可能几乎是必然的,因此在操作系统设计时就应该对进程资源管理进行重点考虑,怎么又扯到操作系统的设计上去了,跑题了!那么我们来看一下Win32对进程占用资源的管理,关键是考察系统在正常或非正常结束一个进程所做的,就会做到心中有数了。

我们知道,现代操作系统几乎都运行保护模式下,保护模式的一个基本特征就是存储保护,存储保护的基本目标就是使各个进程的地址空间相互隔离,从而一个进程不能看见其它进程的数据(当然,为了共享目的而设立的共享存储区除外),其基本实现机制是分段、分页。分段使得各个进程运行在存储器的不同部分,对于越界的访问企图都被CPU硬件予以拒绝。分页的基本功能使得各个进程的地址空间的页(一种固定大小内存块,在x86平台上是4K)通过CPU硬件透明地映射到不同的物理内存页帧,从而实现自动隔离。考虑到各种平台的可移植性,Windows系统采用分页而非分段的平板式的内存管理模型,这种模型有一个好处,使得对于象C这种支持指针的语言给程序员提供一个连续的内存空间印象。无论是分段还是分页,都给操作系统提供了的内存回收提供了便利条件,操作系统只需重置描述该进程的段或页的信息就可以释放掉该进程所占用的内存空间资源而为以后的进程再利用,当然考虑到内存碎片的问题,内存的回收在实际操中可能更为复杂一些。总之一句话,操作系统要释放一个进程所占有的内存空间是能够做到的。

(关于系统其它资源管理)

还有一个问题就是进程在运行中还要用到操作系统提供的其它资源对象(如文件),操作系统能不能回收这些资源呢。谨慎的程序员会在程序设计时可能不会忘记显式的通知(通过相应的释放系统功能调用)操作系统本进程将不在占用该资源,操作系统应该作相应的处理。但情况并不总是这样乐观,粗心的程序员或者是程序异常终止(比方说出现问题被操作系统给kill掉)总是不能正常释放所占有的这些系统资源。因此,操作系统通过记帐进程所使用的系统资源,在进程结束时一一查看这些资源,予以强制释放。

以Win32平台为例,它为每个进程维护一个句柄表,这些句柄包含指向相应系统资源对象的指针,在进程终止时,操作系统的进程终止进程查看这个句柄表,强制释放进程已打开的的系统资源。可以通过如下一个实例来测试:创建一个进程,该进程打开一个文件对象(设置为非删除共享方式),该进程进入死循环,这时你在资源管理器中删除刚才被打开的文件就会失败,接着你通过kill进程的方式来终止该进程,再删除该文件成功。这个实例说明Win32在进程非正常终止时的确能够释放该进程所占有的系统资源。

能够很好做到第一层的程序员就已经很优秀了!

第二层就是,你对编译器、操作系统的内存管理有相当了解,但又没有透彻了解,从而怀疑他们的管理能力;或者你知道了它的实现详细算法,发现了潜在的缺点(这种可能性似乎不大耶!),于是你有点不放心起来,想:我能不能申请一片内存,通过我自己来管理呢,毕竟我自己管理我自己心里最清楚、最放心,答案是肯定的,起码Win32平台就为你提供了这种可能性,请参阅有关Win32 API(VirtualAlloc,VirtualFree等)。这种另起炉灶的思想在某些情况下是很有用的,比方说要设计长时间运行的服务程序时;另外在Windows内核驱动程序设计时对非分页内存空间的使用,Microsoft公司就鼓励这种方式。不过对这种做法,很多人持有不同见解,认为这破坏了分层思想,不符合软件也积木化的发展潮流。我个人认为还是首先应做到第一层,但一个不“安分”的程序员似乎应该做到第二层,我现在就养成这样一个坏毛病,就是老是想另起炉灶!

以上只是我这几年编程时对内存泄露问题担心、探知的概略,欢迎有兴趣的与我讨论:binaryhead@163.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有