记得有个帖子讨论,一个进程申请了一块内存,创建一个自进程,自进程也有这块内存的拷贝,但子进程中却不会释放这块内存,岂不是会造成内存泄露?
乍看有理,细想则不然,什么是内存泄露?有一块实际的内存,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) |