========下面的一堆文字为了说明一件事情---.NET程序,内存溢出,如何控制.主要是堆HEAP大小如何控制以及优化.以减轻GC突发性负担及这个时候服务器当机的可能*.对于大型程序,完全依赖GC是不现实的,对于高负载服务器,往往我们80%的堆都由自己的析构函数接管,并辅助以自行设计的bufferpool接管堆释放工作以达到HEAP可控的目的,减少CPU突发性负荷(CPU尖峰).虽然不像C那样可以控制的那么完全,但是多多少少对OOM的发生起到抑制作用,深入下去可以完全避免OOM......好了IF性能和内存开销没什么追求的 THEN 就不必看了,,,,
ELSE
GO
=====================1.下个windbg,去baidu google一下即可..2.sos.dll 这个框架自带,只所以提下,是让大家有搜索的关键字用.3.泄露,对于.net程序,主要是堆泄露,对于大型服务器程序,需要严格排查OOM(内存泄露)的问题,节约服务器GC开销,内存开销,cpu开销,提高支撑4.配置环境变量 添加系统变量 _NT_DEBUGGER_EXTENSION_PATH C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 这个是为了能够找到sos.dll5.实战启动windbg,开启调试窗口,加载用于.NET调试所使用的sos.dll .load sos回车之后无任何显示表示无任何错误,这个时候就可以运行调试命令了.需要说明的是.打头的是windbg自带命令,!打头的命令是sos.dll调试命令.
显示GC堆占用情况命令 !dumpheap -stat大概会显示这些:对象表,对象数量,每个对象内存占用情况...等,如下:---------------------0:000> !dumpheap -statStatistics:MT Count TotalSize Class Name7a787cc4 1 12 System.IO.FileSystemWatcher+FSWAsyncResult7a75904c 1 12 System.Diagnostics.OrdinalCaseInsensitiveComparer7a7575cc 1 12 System.CodeDom.Compiler.CodeDomConfigurationHandler7a7571a8 1 12 System.Net.DefaultCertPolicy7a75661c 1 12 System.Diagnostics.TraceListenerCollection7a755834 1 12 System.Diagnostics.PerformanceCounterCategoryType..................68a66a88 227,559 12,743,304 System.Web.UI.WebControls.Literal68a2f7fc 399,272 14,373,792 System.Web.UI.ControlCollection68a92e2c 768,731 33,824,164 System.Web.UI.Control+OccasionalFields68a884a0 641,952 38,517,120 System.Web.UI.LiteralControl79124228 879,515 43,394,976 System.Object[]790fa3e0 1,431,594 122,806,484 System.String
Total 10,389,625 objects, Total size: 463,313,540 ----------------------
1,431,594 个 System.String对象 占用 122 MBytes
使用!dumpobj 可以查看System.String对象构成情况
0:000> !dumpheap -type System.Web.UI.LiteralControl Address MT Size Gen023ea0a8 68a884a0 60 2 System.Web.UI.LiteralControl 023ea0e4 68a884a0 60 2 System.Web.UI.LiteralControl 023ea374 68a884a0 60 2 System.Web.UI.LiteralControl 023ea460 68a884a0 60 2 System.Web.UI.LiteralControl 023ea510 68a884a0 60 2 System.Web.UI.LiteralControl 023eab3c 68a884a0 60 2 System.Web.UI.LiteralControl ........CONTINUED........023fe31c 68a884a0 60 2 System.Web.UI.LiteralControl 023fe414 68a884a0 60 2 System.Web.UI.LiteralControl 023fe4c4 68a884a0 60 2 System.Web.UI.LiteralControl 023fe500 68a884a0 60 2 System.Web.UI.LiteralControl
哦 基本上都是LiteralControl
随便抓个控件的地址来分析!do命令
0:000> !do 023ea0a8 Name: System.Web.UI.LiteralControlMethodTable: 68a884a0EEClass: 68a88428Size: 60(0x3c) bytesGC Generation: 2(C:\WINDOWS\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll)Fields: MT Field Offset Type VT Attr Value Name790fa3e0 4001fe0 4 System.String 0 instance 00000000 _id790fa3e0 4001fe1 8 System.String 0 instance 00000000 _cachedUniqueID68a2af44 4001fe2 c ...em.Web.UI.Control 0 instance 023e8864 _parent68a91070 4001fe3 2c System.Int32 0 instance 0 _controlState68a85ea0 4001fe4 10 ...m.Web.UI.StateBag 0 instance 00000000 _viewState68a2af44 4001fe5 14 ...em.Web.UI.Control 0 instance 023e8864 _namingContainer68a273d0 4001fe6 18 System.Web.UI.Page 0 instance 01df4514 _page68a92e2c 4001fe7 1c ...+OccasionalFields 0 instance 00000000 _occasionalFields68a2b378 4001fe8 20 ...I.TemplateControl 0 instance 00000000 _templateControl68a14528 4001fe9 24 ...m.Web.VirtualPath 0 instance 00000000 _templateSourceVirtualDirectory68a8bb48 4001fea 28 ...rs.ControlAdapter 0 instance 00000000 _adapter68a3a8f8 4001feb 30 ...SimpleBitVector32 1 instance 023ea0d8 flags790f9c18 4001fda c70 System.Object 0 shared static EventDataBinding>> Domain:Value 000f0d00:NotInit 0011a720:01df0028 <<790f9c18 4001fdb c74 System.Object 0 shared static EventInit>> Domain:Value 000f0d00:NotInit 0011a720:01df0034 <<790f9c18 4001fdc c78 System.Object 0 shared static EventLoad>> Domain:Value 000f0d00:NotInit 0011a720:01df0040 <<790f9c18 4001fdd c7c System.Object 0 shared static EventUnload>> Domain:Value 000f0d00:NotInit 0011a720:01df004c <<790f9c18 4001fde c80 System.Object 0 shared static EventPreRender>> Domain:Value 000f0d00:NotInit 0011a720:01df0058 <<790f9c18 4001fdf c84 System.Object 0 shared static EventDisposed>> Domain:Value 000f0d00:NotInit 0011a720:01df0064 <<79124228 4001fec c88 System.Object[] 0 shared static automaticIDs>> Domain:Value 000f0d00:NotInit 0011a720:01df0070 <<790fa3e0 4002211 34 System.String 0 instance 02238664 _text
这里如果发现某个值过大,就可以继续深入使用!do + 地址 来进入查看,以便找到OOM的根源..试试
0:000> !do 02238664 Name: System.StringMethodTable: 790fa3e0EEClass: 790fa340Size: 158(0x9e) bytesGC Generation: 2(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)String: Fields:MT Field Offset Type VT Attr Value Name790fed1c 4000096 4 System.Int32 0 instance 71 m_arrayLength790fed1c 4000097 8 System.Int32 0 instance 70 m_stringLength790fbefc 4000098 c System.Char 0 instance 3c m_firstChar790fa3e0 4000099 10 System.String 0 shared static Empty>> Domain:Value 000f0d00:790d6584 0011a720:790d6584 <<79124670 400009a 14 System.Char[] 0 shared static WhitespaceChars>> Domain:Value 000f0d00:01d413b8 0011a720:01d44f80 <<
可以看到32位地址为02238664的是用于表格的结束标志存储.
使用!objsize进一步命令查看对象内的的对象构成,精确到class名,自己可以试试了...还有很多命令可以查看Gen的回收情况,对于长时间未释放的unmanaged资源也可以列表出来,这个时候可以do进去,查看内部结构,找到属于哪段代码之后,再返回自己的.cs代码进行逻辑调整....这样的话,性能就很可观了.同时可以尽量使用好CPU,而不必让不必要的CPU时间牺牲框架和底层的代码胶合层上面..永远要记住CPU时间是用户的,不是你的!这样,对内存了解的多一些,你的程序就能跑的更快一点,持久运行的时间就更长一些...
通常,asp.net或者socket服务器运行的时候,对内存的要求是比较高的,如果内存的性能我们不能去把握,真的很难再生产环境中超越LAMP体系架构.我的观点是,内存---能节约,尽量节约吧,能高效利用,尽量高效利用!所以写这篇帖子,非常非常肤浅的介绍了下,前后也就写了20分钟,因为要睡觉了...
----[成都]CCCP苏联程序员
对了可以去买本"windows调试技术"来看 http://bbs.dbgtech.net/forumdisplay.php?fid=16 可以先了解下.
转载于:https://www.cnblogs.com/koumi/archive/2010/10/12/1849077.html
