公司一程序,用一个service启动好多个进程,运行两天之后发现各种奇怪的问题。诊断是桌面堆耗尽。
简单来说就是对于每个服务系统都会分配默认的堆,win2003是512k,win2008默认是768k。可以在注册表中修改这个值:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows
%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows
SharedSection=1024,3072,512 Windows=On SubSystemType=Windows
ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3
ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off
MaxRequestThreads=16
其中3072是交互式窗口的桌面堆,512是非交互式的(不可见模式)的桌面堆。按照自己的程序类型,增加对应值,可以解决上述问题。关于桌面堆的更加详细介绍在这:http://blogs.msdn.com/b/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx
遇到类似问题,如何判断是否是由于desktop heap 引起来的?
两个工具:dheapmon 或者livekd
1)dheapmon
如果系统是vista之前的版本,参照 http://blogs.msdn.com/b/alejacma/archive/2008/07/29/how-to-use-dheapmon-exe-to-troubleshoot-desktop-heap-issues.aspx
如果系统是vista之后的版本,参照 http://blog.airesoft.co.uk/2009/10/desktop-heap-monitor-vista-7/
主要差别在于 1、vista之后的版本修改了源程序,所以注意两个dheapmon的下载地址是不同的,不能混用。 2、vista之后需要跳过系统对此工具的driver signature check。有三种方法,一是用自己的证书对它进行签名;二是用命令行:BCDEdit /Set LoadOptions DDISABLE_INTEGRITY_CHECKS永久disable签名检测。但是据说vista sp1之后的windows这个命令已经不好用了;三是重启机器时按住F8,在启动画面中选择disalbe driver signature check。麻烦的地方是每次重启都需要按F8,要是忘了就白弄了。有一个工具叫ReadyDriver可以在每次重启的时候自动模拟人手动按F8,并选择disable signature。所以如果选择这种方法,具体诊断的步骤如下:
- 1. 下载安装ReadyDriver http://depositfiles.com/files/jzts8axpq
- 2. 重启机器,会看到自动进入启动画面,disable driver signing checking
- 3. 运行我们的程序直到问题出现
- 4. 下载dheapmon并解压到一个文件夹
- 5. 以Administrator权限运行cmd
- 6. 加载符号集: dheapinst -y srv*http://msdl.microsoft.com/download/symbols
- 7. 装载符号集:dheapmon.exe -l
- 8. 运行 dheapmon.exe 进行诊断
- 9. 卸载dheapmon:
"dheapmon-u"
"dheapinst-r"
-10. 如果不再想用了,可以卸载ReadyDriver重启机器
2)livekd
dheapmon用在vista之后的版本需要重启机器屏蔽driver signature checking,但重启机器之后我们的问题就消失了,还要再运行一段时间重现。另外一个问题就是dheapmon只能显示当前Session的heap信息,如果远程桌面登陆的话,就只能显示Session 1的heap size,不能显示Session 0的,而我们的服务程序是Session 0,所以抓不到。
livekd可以解决上面两个问题。以下为Vista之后windows版本运行livekd的步骤:
- 1. 安装Windbg :http://www.microsoft.com/en-us/download/details.aspx?id=8279
以上地址是windows 7 SDK 的在线安装包,若安装时碰到提示说可能某些组件不能安装使用的时候,选择继续。选择安装组件的时候只须保留Debuggingtools for windows即可。
- 2. 下载livekd,解压到windbg安装目录: http://technet.microsoft.com/en-us/sysinternals/bb897415.aspx
- 3. 打开windbg,按Ctrl+S,在面板中输入符号集地址:SRV**http://msdl.microsoft.com/download/symbols
- 4. 管理员权限打开livekd, 若出现提示,直接选默认选项。
- 5. 命令行输入 !dskheap -s0 出现Session 0的desk heap 信息
类似如下:
D:\AnalysisDocs>livekd
LiveKd v5.2 - Execute kd/windbg on a live system
Sysinternals - www.sysinternals.com
Copyright (C) 2000-2012 Mark Russinovich and Ken Johnson
Symbols are not configured. Would you like LiveKd to set the_NT_SYMBOL_PATH
directory to reference the Microsoft symbol server so thatsymbols can be
obt