知秋一叶

日出而作,日入而息,凿井而饮,耕田而食,帝力何有于我哉
随笔 - 55, 评论 - 312, 引用 - 79

导航

标签

每月存档

最新留言

广告

 


  关于开心的问题Saucer都来了,我也来凑热闹。咧嘴笑脸
  这个问题在CSDN上碰到好几次,我每次都只给出了简单的答案:不要参考Task Manager的Mem Usage数据,那个数据的大小对程序性能没有直接影响。
 下面是我分析这问题的一些思路,希望对对这个问题感兴趣的朋友有所帮助。(还有一个原因——很久没有update blog,被开心“警告”了... 吐舌笑脸

 Q: Is .NET Alone?
 A: Nope!  前面Saucer说过了,这不是.NET的问题,所有Windows程序都有类似的行为。例如下面的C程序:
    void main { while(1); }   //死循环,便于我们察看Task Manager
  初次运行在我的机器上Mem Usage是632K,把Console最小化以后再恢复,Mem Usage变成了36K。显然,这不是一个.NET独有的问题,而是Windows Memory Management的问题。那么和.NET的GC机制也不会有太大的关系——虽然问题的表现形式很容易让人联想到GC。

 Q: How much memory does my program use?
 A: 回答这个问题并不容易。先来看看操作系统虚拟内存管理的一些基本概念:每个Windows进程都拥有4G的地址空间,但是你的机器显然没有4G的物理内存。在多任务环境下,所有进程使用的内存总和可以超过计算机的物理内存。在特定的情况下,进程的一部分可能会从物理内存中删除而被暂存在硬盘的文件里(pagefile),当进程试图访问这些被交换到pagefile里的内存的时候,系统会产生一个缺页中断(page fault),这时候Windows内存管理器会负责把对应的内存页重新从硬盘调入物理内存。
  在某个时间内,一个进程可以直接访问到的物理内存(不发生缺页中断)叫做这个进程的Working Set;而一个进程从4G的地址空间当中实际分配(commit)了的、可访问的内存称为Committed Virtual Memory。Committed VM可能存在于Page File当中,WorkingSet则一定位于物理内存。
  所以要回答上面的问题先要反问一句:What're you talking about? Physical Memory or Committed Memory?

 Q: What is this "Mem Usage" data?
 A: From Task Manager Help: In Task Manager, the current Working Set of a process, in kilobytes.
  Mem Usage这个名字多少有些误导。它只表示这个进程当前占用的物理内存,也就是WorkingSet。WorkingSet不表示进程当前“占用”的所有虚拟内存,该进程可能还有一部分数据被交换到pagefile当中。这些数据只有在被访问的时候才会被加载到物理内存。
  Task Manager有另一列数据:VM Size,表示了一个进程分配的虚存(Committed Visual Memory)——实际的定义要比这个复杂一些,但这个定义对我们目前分析的问题已经足够了。以前面的C程序为例,在最小化前后的VM Size都是176K,并没有变化。
  所以,结论很简单:当一个Windows程序被最小化的时候,Windows内存管理器把该进程的WorkingSet减到最小(根据先进先出FIFO或者最近最少使用LRU),把大部分数据交换到pagefile里。这很容易理解:我们通常总是希望为前台的应用程序留出更多物理内存,从而具有更好的性能。当该程序从最小化恢复的时候,Windows也不会完全加载程序的所有虚存,只是加载了必要的部分。这也很容易理解:程序启动阶段的代码通常在启动之后很少访问(对.NET程序尤其如此,向fusion这样的模块在程序正常加载之后如果没有用到Reflection通常用不到)。

 Q: So, Do we want a smaller workingset, or a larger one?
 A: It depends. Conventional Wisdom tells us: The smaller, the better. 但是在虚存的问题上却没这么简单。如果WorkingSet太小,程序运行过程中会产生很多缺页中断,这会严重影响程序的性能。另一方面,WorkingSet太大会浪费“宝贵的”物理内存,降低整个系统的性能。 通常情况下(除非是对性能非常敏感的应用程序,并且你对Windows的内存管理了如指掌),建议不要在程序中自己调整WorkingSet的大小,而把这个任务交给Windows内存管理器。调整的方法Saucer有提到: SetProcessWorkingSetSize();

 Q: Final Question, Does my program really occupy that much physical memory?
 A: 这个问题看上去土了点——那个数字明明白白的写在Task Manager里面。笑脸
 sam1111用vadump检查的结果显示进程WorkingSet减小的主要原因是很多DLL在从最小化恢复的时候没有被加载到物理内存。我们知道DLL的一个特点是代码共享,以NTDLL.DLL为例,整个Windows系统的几乎所有应用程序(具体地说,Win32子系统的所有程序)都需要引用NTDLL.DLL,如果每人一份,光这个文件就的占用几十兆内存。Windows地解决办法是只在物理内存中保存一份NTDLL.DLL的COPY,所有引用这个DLL的程序都把这一份COPY映射到自己的内存空间里面,共享NTDLL.DLL的代码段(每个进程的数据段仍然是独立的)。所以虽然NTDLL.DLL的大小被计算在你的程序的WorkingSet里面,但是从你的程序中去掉对这个DLL的引用并不会真的释放多少物理内存——你不用,别人还在用呢!
  所以,你的程序“独占”的物理内存远没有Mem Usage所表示的那么多,需要从Mem Usage里面扣除很多Shared Code Page (vadump里面可以看到)。

  结论?不要参考Task Manager的Mem Usage数据,那个数据的大小对程序性能没有直接影响。笑脸 用Perfomence Monitor里面与.NET相关的Counter要容易、准确的多。

 

打印 | 张贴于 2004-03-17 04:34:00 | Tag:.NET

留言反馈

#yayykgqm - Google Search 编辑
yayykgqm - Google Search
2008-09-23 04:49:56 | [匿名用户:]
#回复: More on Memory Usage 编辑
2008-02-15 11:12:00 | [匿名用户:ww]
#回复: More on Memory Usage 编辑
2008-02-15 11:12:00 | [匿名用户:ww]
#回复: More on Memory Usage 编辑
2008-01-30 13:27:00 | [匿名用户:vvvvvvv]
#回复: More on Memory Usage 编辑
[url=http://www.mmmqt.cn]中国福利彩票[/url]
2008-01-30 13:27:00 | [匿名用户:vvvvvvv]
#回复: More on Memory Usage 编辑
2007-12-18 05:13:00 | [匿名用户:runescape gold]
#re: More on Memory Usage 编辑
我看了上面的文章,还是有点疑惑之处,如果是这样的话,那么在Task Manager中显示的VM Size(也就是Committed Visual Memory)应该一定比Mem Usage(也就是WorkingSe)要大。那么为什么在Taks Manager中可以看到有VM Size小于Mem Usage的情况?
2005-09-11 20:36:00 | [匿名用户:Sun.Huang]
#re: More on Memory Usage 编辑
不错,很清楚,谢谢
2005-08-02 09:06:00 | [匿名用户:enjsky]
#re: More on Memory Usage 编辑
受教了
2005-03-07 09:48:00 | [匿名用户:renyi]
#re: More on Memory Usage 编辑
楼主关于working set的解释不对,随便找一本os的书就会看明白。
working set是指进程使用物理内存的一个临界值,赋予进程大于working set的物理内存,也不能明显提升程序的性能
2004-12-27 10:21:00 | [匿名用户:marrabech]
#re: More on Memory Usage 编辑
說的非常好!
記得4年前學習操作系統的時候,了解了很多缺頁中斷的算法,工作集、頁面文件等等,當時只知道理論,今天終于發現與實際的程序結合了,感謝你!
2004-12-25 20:51:00 | [匿名用户:柚子男]
#re: More on Memory Usage 编辑
收藏先
2004-08-10 00:49:00 | [匿名用户:戏子]
#回复: More on Memory Usage 编辑
很精彩!

几个小纠正。

1。Fusion是CLR Loader的一部分,和Reflection没有关系。如果你所有的Type都装载完了,fusion是用不着了。

2。最小化的时候OS没有把减掉的WorkingSet放到Pagefile里。Windows的内存有三种,一是无人使用的,二是正在使用的,三是不久前刚使用过,但现在不再用的。最小话的时候OS把部分内存从二放到三。
2004-04-12 04:58:00 | [匿名用户:Junfeng Zhang]
#回复: More on Memory Usage 编辑
感觉自己在大学学的(OS原理)用上了,很多知识点知道是知道但没有如此感觉到它们的真实存在,谢谢老大!!!
2004-04-03 09:26:00 | [匿名用户:lr2651]
#回复: More on Memory Usage 编辑
受教了~
2004-03-17 12:29:00 | [匿名用户:minbear]
#回复: More on Memory Usage 编辑
to 开心:
还是你警告一下会比较有用。;)
前段时间比较忙,一定、一定记得update...

>> 为什么我第一眼总把memory看成money ?
More On Money Usage? That would be a hot topic. :D
2004-03-17 12:17:00 | [匿名用户:qqchen]
#回复: More on Memory Usage 编辑
又学了一点
2004-03-17 12:01:00 | [匿名用户:lonelystranger]
#回复: More on Memory Usage 编辑
受教
2004-03-17 11:15:00 | [匿名用户:Meyer]
#回复: More on Memory Usage 编辑
茅塞顿开
2004-03-17 10:54:00 | [匿名用户:Rustle]
#回复: More on Memory Usage 编辑
为什么我第一眼总把memory看成money ?
2004-03-17 10:08:00 | [匿名用户:郭群]
#回复: More on Memory Usage 编辑
最喜歡看qqchen解答問題.他對系統了解很深
2004-03-17 10:07:00 | [匿名用户:Bill]
#回复: More on Memory Usage 编辑
Good job. 看来我没有必要在解释这个问题了。:)
2004-03-17 10:05:00 | [匿名用户:彭刚]
#回复: More on Memory Usage 编辑
豁然开朗,更佩服知秋的说明能力
2004-03-17 09:57:00 | [匿名用户:gujianxin]
#回复: More on Memory Usage 编辑
大牛都出来了
2004-03-17 09:22:00 | [匿名用户:mvm]
#回复: More on Memory Usage 编辑
特别受用,真的非常受教。
知秋一叶还是经常Update呀,不要总让俺“警告”呀:)
2004-03-17 09:18:00 | [匿名用户:开心就好]
#回复: More on Memory Usage 编辑
受教了
2004-03-17 08:57:00 | [匿名用户:sam1111]
#回复: More on Memory Usage 编辑
这个问题我也困惑了很久了,今天终于知道原因了
谢谢各位
2004-03-17 08:37:00 | [匿名用户:豆腐]
#回复: More on Memory Usage 编辑
解释的比我清楚多了, :-)
2004-03-17 05:32:00 | [匿名用户:saucer]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode.MVC引擎 0.5.1.0