免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: ljoolj

[NetBSD] 一个在内存跑进程和文件系统有什么关系? [复制链接]

论坛徽章:
0
发表于 2006-04-18 14:04 |显示全部楼层
系统为什么不在进程死亡后,释放资源时,顺便释放vm_object?为什么要在umount文件系统时候多此一举?

论坛徽章:
1
寅虎
日期:2013-09-29 23:15:15
发表于 2006-04-18 14:13 |显示全部楼层
LZ的顺序好象搞错了,应该是你用-f 强行释放在先,而不是系统不释放.

论坛徽章:
0
发表于 2006-04-18 14:28 |显示全部楼层
原帖由 congli 于 2006-4-18 14:13 发表
LZ的顺序好象搞错了,应该是你用-f 强行释放在先,而不是系统不释放.


嗯,

论坛徽章:
0
发表于 2006-04-18 15:02 |显示全部楼层
我是认为既然系统可以在进程死亡后,释放vm_object,
为什么还要多手多脚在umount时候去释放vm_object. 它为什么要这样设计?

论坛徽章:
0
发表于 2006-04-18 15:42 |显示全部楼层
原帖由 ljoolj 于 2006-4-18 15:02 发表
我是认为既然系统可以在进程死亡后,释放vm_object,
为什么还要多手多脚在umount时候去释放vm_object. 它为什么要这样设计?



vm_object是一个通用模型,并不是专门为哪一个类型的文件设计的,只要存在一个vm_object,进程就可以通过它操作对应的文件。vm_object本身就是一个文件在进程地址空间中的全权代理,进程每操作一个文件,就会生成一个vm_object,(但一个文件只能有一个vm_object,即使有多个进程访问它),因此,文件和vm_object的关系是一里一外,一一对应的。进程对文件的读入和写出都是通过vm_object来进行的,如果你把文件都删除了,这个vm_object就成了无源之水无本之木,留着何用,让进程去读写一个已经不存在的文件么?

当然,按你所说的“小”程序,进程一开始就把它完全读入了内存页中,不需要后续的文件操作了,但岂不是要虚存系统去识别文件的类型、大小、是否已完全读入,将来是否会写出,这好像更不合理。。。

论坛徽章:
1
寅虎
日期:2013-09-29 23:15:15
发表于 2006-04-18 15:58 |显示全部楼层
原帖由 雨丝风片 于 2006-4-18 15:42 发表



vm_object是一个通用模型,并不是专门为哪一个类型的文件设计的,只要存在一个vm_object,进程就可以通过它操作对应的文件。vm_object本身就是一个文件在进程地址空间中的全权代理,进程每操作一个文件,就 ...

学习ing:em11:

论坛徽章:
0
发表于 2006-04-19 11:07 |显示全部楼层
看了看的进程代码,有了点模糊概念,跑进程初始化时候,进程相关的数据结构是把vm_object,和vnode相关资源挂接上来,进程死后是和这些资源脱钩,并不会实质销毁vm_object,和vnode,所以vm_objectg,和vnode,系统还是在挂解文件系统(umount)时候才实际销毁。
不知道这样理解对不对?

论坛徽章:
0
发表于 2006-04-19 12:09 |显示全部楼层
原帖由 ljoolj 于 2006-4-19 11:07 发表
看了看的进程代码,有了点模糊概念,跑进程初始化时候,进程相关的数据结构是把vm_object,和vnode相关资源挂接上来,进程死后是和这些资源脱钩,并不会实质销毁vm_object,和vnode,所以vm_objectg,和vnode,系统还 ...



vm_object虽然是和文件一一对应的,但它本身却是属于进程地址空间的范畴。要理解这个问题,可以举个例子。比如一把钥匙和一把锁,它们的关系是相辅相成、一一对应的。如果锁坏了,那你的钥匙留着也没用,只有丢了。如果你的钥匙丢了,那锁留着也没用,只有换了。因此,这个一一对应关系可以从两头去删除。比如vm_object就是钥匙,而文件则是锁。

进程退出代码代码中有如下调用序列,你可以去仔细研究一下。


  1. _____________________________________________________________________FreeBSD6.0
  2. 101 /*
  3. 102  * Exit: deallocate address space and other resources, change proc state
  4. 103  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
  5. 104  * status and rusage for wait().  Check for child processes and orphan them.
  6. 105  */
  7. 106 void
  8. 107 exit1(struct thread *td, int rv)
  9. 108 {
  10.      ......
  11. 294         (void) vm_map_remove(&vm->vm_map, vm_map_min(&vm->vm_map),
  12. __________________________________________________/usr/src/sys/kern/kern_exit.c
复制代码


  1. _____________________________________________________________________FreeBSD6.0
  2. 2306 /*
  3. 2307  *    vm_map_remove:
  4. 2308  *
  5. 2309  *    Remove the given address range from the target map.
  6. 2310  *    This is the exported form of vm_map_delete.
  7. 2311  */
  8. 2312 int
  9. 2313 vm_map_remove(vm_map_t map, vm_offset_t start, vm_offset_t end)
  10. 2314 {
  11.      ......
  12. 2319     result = vm_map_delete(map, start, end);
  13. _______________________________________________________/usr/src/sys/vm/vm_map.c
复制代码


  1. _____________________________________________________________________FreeBSD6.0
  2. 2213  /*
  3. 2214   *    vm_map_delete:    [ internal use only ]
  4. 2215   *
  5. 2216   *    Deallocates the given address range from the target
  6. 2217   *    map.
  7. 2218   */
  8. 2219  int
  9. 2220  vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end)
  10. 2221  {
  11.       ......
  12. 2300          vm_map_entry_delete(map, entry);
  13. _______________________________________________________/usr/src/sys/vm/vm_map.c
复制代码


  1. _____________________________________________________________________FreeBSD6.0
  2. 2174  /*
  3. 2175   *    vm_map_entry_delete:    [ internal use only ]
  4. 2176   *
  5. 2177   *    Deallocate the given entry from the target map.
  6. 2178   */
  7. 2179  static void
  8. 2180  vm_map_entry_delete(vm_map_t map, vm_map_entry_t entry)
  9. 2181  {
  10.       ......
  11. 2207          vm_object_deallocate(object);
  12. _______________________________________________________/usr/src/sys/vm/vm_map.c
复制代码


  1. _____________________________________________________________________FreeBSD6.0
  2. 425  /*
  3. 426   *    vm_object_deallocate:
  4. 427   *
  5. 428   *    Release a reference to the specified object,
  6. 429   *    gained either through a vm_object_allocate
  7. 430   *    or a vm_object_reference call.  When all references
  8. 431   *    are gone, storage associated with this object
  9. 432   *    may be relinquished.
  10. 433   *
  11. 434   *    No object may be locked.
  12. 435   */
  13. 436  void
  14. 437  vm_object_deallocate(vm_object_t object)
  15. 438  {
  16.       ......
  17. 456              vm_object_vndeallocate(object);
  18. ____________________________________________________/usr/src/sys/vm/vm_object.c
复制代码


  1. _____________________________________________________________________FreeBSD6.0
  2. 393  /*
  3. 394   * Handle deallocating an object of type OBJT_VNODE.
  4. 395   */
  5. 396  void
  6. 397  vm_object_vndeallocate(vm_object_t object)
  7. 398  {
  8.       ......
  9. 422      vrele(vp);
  10. ____________________________________________________/usr/src/sys/vm/vm_object.c
复制代码


  1. _____________________________________________________________________FreeBSD6.0
  2. 2010  /*
  3. 2011   * Vnode put/release.
  4. 2012   * If count drops to zero, call inactive routine and return to freelist.
  5. 2013   */
  6. 2014  void
  7. 2015  vrele(vp)
  8. 2016      struct vnode *vp;
  9. 2017  {
  10.       ......
  11. ___________________________________________________/usr/src/sys/kern/vfs_subr.c
复制代码

论坛徽章:
0
发表于 2006-04-19 14:31 |显示全部楼层
原帖由 雨丝风片 于 2006-4-19 12:09 发表



vm_object虽然是和文件一一对应的,但它本身却是属于进程地址空间的范畴。要理解这个问题,可以举个例子。比如一把钥匙和一把锁,它们的关系是相辅相成、一一对应的。如果锁坏了,那你的钥匙留着也没用,只 ...


老大我在  vrele 中没发现有类似"free"的操作啊,只是一些减引用数,和当引用数==0就放到vnode_hold_list 或者 vnode_free_list 中
netbsd 和freebsd差别不会太大吧?

  1. --------------------------------------------------------------------------netbsd3.0
  2. /*
  3. * Vnode release.
  4. * If count drops to zero, call inactive routine and return to freelist.
  5. */
  6. void
  7. vrele(vp)
  8.         struct vnode *vp;
  9. {
  10. 。。。
  11.         simple_lock(&vp->v_interlock);
  12.         vp->v_usecount--;                                              /*减引用计数*/
  13.         if (vp->v_usecount > 0)           {                           /*引用数>0返回*/
  14.                 simple_unlock(&vp->v_interlock);
  15.                 return;
  16.         }
  17. 。。。
  18.         /*
  19.          * Insert at tail of LRU list.
  20.          */
  21.         simple_lock(&vnode_free_list_slock);
  22.         if (vp->v_holdcnt > 0)
  23.                 TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
  24.         else
  25.                 TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
  26.         simple_unlock(&vnode_free_list_slock);
  27. 。。。
  28. }
  29. --------------------------------------------------------------------/usr/src/sys/kern/vfs_subr.c
复制代码

[ 本帖最后由 ljoolj 于 2006-4-19 14:35 编辑 ]

论坛徽章:
0
发表于 2006-04-19 15:56 |显示全部楼层
原帖由 ljoolj 于 2006-4-19 14:31 发表


老大我在  vrele 中没发现有类似"free"的操作啊,只是一些减引用数,和当引用数==0就放到vnode_hold_list 或者 vnode_free_list 中
netbsd 和freebsd差别不会太大吧?
[code]
---- ...


难说,NetBSD和FreeBSD的虚存模型不太一样,分析这个问题的时候需要注意两者的区别。FreeBSD的vrele 就会调到vfree()。不过这部分我还没有仔细看过,暂时不能给出详细的解释。一直想比较一下FB和NB的虚存模型,借此机会共同学习ing。

【FreeBSD操作系统设计与实现】:
Objects that represent anonymous memory are reclaimed as part of cleaning up a process as it exits. However, objects that refer to files are persistent.When the reference count on a vnode drops to zero, it is stored on a least-recently used (LRU) list known as the vnode cache; see Section 6.6. The vnode does not release its object until the vnode is reclaimed and reused for another file. Unless there is pressure on the memory, the object associated with the vnode will retain its pages. If the vnode is reactivated and a page fault occurs before the associated page is freed, that page can be reattached rather than being reread from disk.


从这段话来看,在FreeBSD里面,代表匿名内存区域的object是在进程退出时立即释放的,而代表文件的object则不在此列,是跟着vnode走的。只要系统没有出现内存紧缺,vnode及其对应的object(当然包括object所占据的物理内存页)就不会被销毁,而是被放到一个LRU链表中,等待着可能出现的再次被使用的机会。这样设计对于一些会高频率使用的小程序文件是很有好处的,比如ls。在第一次运行完毕之后,虽然相应的进程退出了,但对应于ls可执行文件的object(物理页)和vnode都还在,这样当你以后运行ls的时候,就可以避免再次把ls可执行文件的内容映射到内存中了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,8.5折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时8.5折扣期:2019年9月30日前


----------------------------------------

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP