Chinaunix首页 | 论坛 | 博客
  • 博客访问: 536131
  • 博文数量: 103
  • 博客积分: 2024
  • 博客等级: 上尉
  • 技术积分: 1294
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-08 21:17
文章分类

全部博文(103)

文章存档

2012年(2)

2011年(21)

2010年(80)

分类: C/C++

2010-03-17 09:54:13

记得有个帖子讨论,一个进程申请了一块内存,创建一个自进程,自进程也有这块内存的拷贝,但子进程中却不会释放这块内存,岂不是会造成内存泄露?
乍看有理,细想则不然,什么是内存泄露?有一块实际的内存,os认为有进程在使用他,所以不会释放掉,(可能会被换出到虚拟内存那儿),而进程则永远不会访问这块内存,这样这块内存对于os,对于进程都没有用了,也就泄露了。
再说说,操作系统对内存的管理,是基于分页的,这块内存有没有进程在用,引用计数,,这些信息,os有一个表来维护。对泄露的内存来说,当然是有进程在用了,所以这块内存不会给别的进程用。
对于进程,os维护了进程的地址空间,kernel里用struct vma描述,进程要用一块内存时,首先要申请一个地址空间(有就不用申请了),如果立即访问的话,由于还没有虚拟空间到物理空间的映射,会触发一个异常,os,建立映射,告诉进程ok,u got it.这里也就是linux的写时复制技术,也就是说fork创建进程的时候,他只是复制父进程的地址空间,只是把父进程的虚拟地址给继承下来,虚拟地址到实地址的映射并没有继承,这里并不会增加malloc那块内存的引用计数,因为子进程根本不会访问那块实际的内存,父子进程拥有的只是相同的虚拟地址,当父进程free的时候就可以释放掉那块内存。所以也就不存在内存泄露的问题。
刚刚又想到了vfork,父子进程共享内存空间,这样会造成内存的泄露,但vfork一般都execv加载一个新的进程空间了,原先的映射都over了,那块内存又可以被释放了。
刚看了vfork的手册页,吓了一跳
vfork() differs from fork(2) in that the parent is suspended until  the
       child  terminates  (either normally, by calling exit(2), or abnormally,
       after delivery of a fatal signal), or it makes  a  call  to  execve(2).
       Until  that point, the child shares all memory with its parent, includ-
       ing the stack.  The child must not return from the current function  or
       call exit(3), but may call _exit(2).
特别是这句including the stack,太狠了。
阅读(2837) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~