关于系统缓存的问题-物理内存消耗远远多于实际占用物理内存

【 某某提到: 】
: 一台服务器装有windows server 2008 r2,安装16G内存并设置16G虚拟内存。最近在运行一个用C#编写的大规模计算程序时发现,有很大一部分物理内存被莫名其妙地消耗了。资源监视器显示该程序占用物理内存不到5G,但是总的物理内存消耗接近10G,可用物理内存仅剩6G。随着运?
: 除了这个程序之外没有其它程序大量占用内存。这个程序有大量磁盘IO操作,在运行中会不时地调用GC.Collect()以及时清理不用的内存。这个实验中用到的一系列程序的结构基本相同,都会不时调用GC清理,但其它程序的内存使用都正常,只有这个程序会出现占用内存是实际使用的
: 请问为什么会出现这样莫名其妙多占用内存的情况呢?谢谢大家


这个既不是应用本身的bug,也不是系统的memory leak。

当前资源监视器中关于系统物理内存,有这么几个统计项,可用、缓存、总数、已安装;其中"缓存"这项,代表着已用于文件系统、网络等等子系统的数据缓冲存储的内存容量,其中包含数量巨大的驻留在物理内存中的数据页面。而这样的物理内存消耗并没有归入任何一个进程列表显示的进程所占用的物理内存。这就是为什么下面公式,

进程列表显示的所有进程所占用的物理内存之和 + 可用物理内存 < 物理内存总数

,成立的原因所在。

导致这一现象的原因,从这个大规模计算程序的行为描述看,基本可以断定是由于以下两点,
1)应用本身的大规模数据驻留物理内存,导致parser.exe进程庞大的working set;
2)大量频繁的IO操作,引起大量的物理内存为系统缓存所占用;

对于1),必须注意,GC.Collect()只是设置使能垃圾收集的标志位,并没有立即启动垃圾收集过程,这个过程的实际启动时刻由CLR来动态决议;

所以如果要获得即时的托管内存的释放,并进一步释放物理内存以减小当前进程的working set,可以使用AppDomain这个.net下可以用来资源划分、获取和释放的,在概念上近似于轻量级进程的编程语义;在AppDomain中获取的各种资源,包括托管内存、加载其中的各个assembly以及CCW等,在此AppDomain被释放时都被相应的及时释放(或者引用计数递减)。

对于2),重新观察先前的设计实现和模型,考虑是否能把一些分散的IO操作合并起来进行,比如,
for(long i=0; i < Count; ++i)
{
  ...
  objIO.Operation(Data[i], 1);
  ...
}
修改为
for(long i=0; i < Count; ++i)
{
  ...
  ...
}
objIO.Operation(Data, Count);
这样对于提高应用的IO效率以及提升系统缓存利用率应当会有帮助。


对于2),系统缓存随着这个大规模计算应用的进行而逐步增大,并最后导致整个系统无法获取的物理内存而无法继续运行的现象,估计即使采用了在上文提出的,在应用程序代码中尽可能合并IO操作,减少IO次数的方法,也不会改善系统缓存占用物理内存数量过大的问题。这个问题本质上是Windows操作系统本身从NT时代到现在,一直存在的问题,主要是围绕着Windows kernel中的Cache mananger以及memory manager核心态组件的实现机制而产生的。

根据目前的Cc(对Cache manager的简称,在WindowsResourceKernel开源项目中,Cache manager相关模块的函数都以Cc作为前缀,比如CcCopyRead,CcFlushCache等,Memory manager也同样简称Mm)的实现机制,所有对文件系统的访问,包括本地和网络,都会首先由Cc对相关页面作缓存映射,随着频繁的IO的操作,被Cc缓存的页面也迅速递增,而被缓存页面占用多少物理内存,这是由Windows kernel中的Memory manager决定。目前在64位平台上,系统缓存最高可达1TB,所以这个应用进程的运行中出现分配8G的缓存是完全可能的,但同时问题也随之而来,那就是系统缓存占用了过多的物理内存,导致其他进程以及内核本身无法申请足够的物理内存,最后致使系统“僵死”;

对于这个问题,微软提供了“Microsoft Windows Dynamic Cache Service”工具来提供对系统缓存的工作集working set容量(也就是驻留物理内存的大小)的控制,这个工具主要是对SetSystemFileCacheSize的封装,可以设置系统缓存容量的上下限。

但这只是一种临时的解决方案,因为应用虽然可以通过上面这个Dynamic Cache Service来设置和限制系统缓存容量的大小,但是如何确定缓存容量大小的非常困难,如果过小,所有IO性能大受影响,整个Cc如同虚设;如果过大(等价于不受限),那么系统缓存占用过多物理内存导致系统僵死的现象就会重现。

所以从根本上看,这个问题应由包括Cc和Mm在内的整个Windows kernel作出完整一致的调整,但从目前的实现看要完成整个方案改动很大,据称这个改进可能会考虑包含在Win7中发布。

Microsoft Windows Dynamic Cache Service下载,
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=e24ade0a-5efe-43c8-b9c3-5d0ecb2f39af&displaylang=en

Microsoft Windows Dynamic Cache Service相关的介绍,
http://blogs.msdn.com/b/ntdebugging/archive/2009/02/06/microsoft-windows-dynamic-cache-service.aspx

posted on 2010-12-11 11:19 flagman 阅读(6179) 评论(1)  编辑 收藏 引用 所属分类: 设计 Design操作系统 OS

评论

# re: 关于系统缓存的问题-物理内存消耗远远多于实际占用物理内存 2010-12-11 15:21 十一文

应该与内存对齐有关系吧  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜