浅谈C语言中垃圾回收.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
浅谈C语言中垃圾回收

浅谈C语言中垃圾回收   摘要:本文简要说明了在C语言中垃圾产生的原因和垃圾回收器的基本原理,阐述了C语言是如何利用MarkSweep算法实现垃圾回收及存在的不足。   关键词:C语言 垃圾回收   中图分类号:TP399 文献标识码:A 文章编号:1007-9416(2011)08-0133-02      一般来说,操作系统记录了进程所使用的资源,在进程结束时释放这些资源。但是如果进程运行的时间很长,或者永不结束(主机和小型机经常是常年运行的),操作系统就没有机会来及时地释放这些资源,从而造成系统内存的丢失。系统内存的丢失积累到一定的程度,怪事就该出现了。   C语言实际没有垃圾回收机制,一切依赖程序员和操作系统。如果编写的程序忘记释放内存而又长时间的运行,麻烦就来了。而如果编译器本身的库函数有问题,那就更可怕了。Borland的C/C++编译器经常有这个问题,业界很多人都知道的,因此很少有人敢用它来做大的软件。下面我就来谈一谈如何解决这个问题。   1、C语言中垃圾产生的原因   在诸如C malloc包这样的显式分配器中,应用通过调用malloc和free来分配和释放堆块。应用程序要负责释放所有不再需要的已分配块。   未能释放已分配的块是一种常见的编程错误。例如,考虑下面的C函数,作为处理的一部分,它分配一块临时存储:   Void garbage()   {   int *p=(int *)malloc(56987);   return;   }   因为程序不再需要P,所以在此garbage返回前应该释放P。不幸的是,程序员忘了释放这个块。它在程序的生命周期内都保持为已分配状态,毫无必要地占用着本来可以用来满足后面分配请求的堆空间。   垃圾收集器是一种动态存储分配器,它自动释放程序不再需要的已分配块。这些块被称为垃圾,术语又称之为垃圾收集器。自动回收堆存储的过程叫做垃圾收集。在一个支持垃圾收集的系统中,应用显式分配堆块,但是从不显式地释放它们。在C程序的上下文中,应用调用malloc,但是从不调用free。取而代之的是,垃圾收集器定期识别垃圾块,并相应地调用free,将这些块放回到空闲链表中。   我们这里只讨论局限于McCarthy独创的MarkSweep(标记清除)算法,这个算法很有趣,因为它可以建立在已存在的malloc包的基础之上,为C和C++程序提供垃圾收集。   2、MarkSweep垃圾收集器的基本原理   垃圾收集器将存储器视为一张有向可达图,其形式如图1所示。该图的节点被分成一组根节点和一组堆节点。每个堆节点对应于堆中的一个已分配块。有向边p→q意味着块p中的某个位置指向块q中的某个位置。根节点对应于这样一种不在堆中的位置,它们中包含指向堆中的指针。这些位置可以是寄存器,栈里的变量,或者是虚拟存储器中读写数据区域内的全局变量。   当存在一条从任意根节点出发并到达p的有向路径时,我们说一个节点p是可达。在任何时刻,和垃圾相对应的不可达节点是不能被应用再次使用的。垃圾收集器的角色是维护可达图的某种表示,并通过释放不可达节点并将它们返回给空闲链表,来定期地回收它们。   像ML和Java这样的语言垃圾收集器,对应用如何创建和使用指针有很严格的控制,它们能够维护可达图的一种精确的表示,因此也就能够回收所有垃圾。然而,诸如C和C++这样的语言的收集器通常不能维持可达图的精确表示。这样的收集器也叫做保守的垃圾收集器。从某种意义上来说它们是保守的,也就是,每个可达块都被正确地标记为可达了,而一些不可达节点却可能被错误地标记为可达。   收集器可以按需提供它们的服务,或者它们可以作为一个和应用并行的独立线程,不断地更新可达图和回收垃圾。例如,考虑我们如何为C程序将一个保守的收集器加入到已存在的malloc包中如图2所示。   无论何时应用需要堆空间时,它都会用通常的方式调用malloc。如果malloc找不到一个合适的空闲块,那么它就调用垃圾收集器,希望能够回收一些垃圾到空闲链表。收集器识别出垃圾块,并通过调用free函数将它们返回给堆。关键的想法是收集器代替应用去调用free。当对收集的调用返回时,malloc管理方式,试图发现一个合适的空闲块。如果还是失败了,那么它就会向操作系统要求额外的存储器。最后,malloc返回一个指向请求块的指针(如果成功)或者返回一个空指针(如果不成功)。   MarkSweep的描述将假设使用下列函数,其中ptr定义为typedef char *ptr;   ptr isPtr(ptr p):如果p指向一个已分配块中的某个字,那么就返回一个指向这个块的起始位置的指针b。否则返回NULL。   int blockMarke

文档评论(0)

3471161553 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档