<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Performance Tuning相关的</title><subtitle type="text">好好学习，天天向上</subtitle><id>http://feed.cnblogs.com/blog/u/1145/rss</id><updated>2012-04-24T06:34:03Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/1145/rss"/><entry><id>http://www.cnblogs.com/juqiang/archive/2011/03/09/1977996.html</id><title type="text">微软上海招聘有经验的.NET开发人员</title><summary type="text">如题，主要是做企业的项目开发，Vendor职位（非FTE）。要求对C#、ASP.NET、SQL比较熟练。工作经验三年以上，学历不限。有意的兄弟，请发简历给我：charju@microsoft.com</summary><published>2011-03-09T02:37:00Z</published><updated>2011-03-09T02:37:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2011/03/09/1977996.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2011/03/09/1977996.html"/><content type="html">&lt;p&gt;如题，主要是做企业的项目开发，Vendor职位（非FTE）。要求对C#、ASP.NET、SQL比较熟练。工作经验三年以上，学历不限。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;有意的兄弟，请发简历给我：&lt;a href="&amp;#109;&amp;#97;&amp;#105;&amp;#108;&amp;#116;&amp;#111;&amp;#58;&amp;#99;&amp;#104;&amp;#97;&amp;#114;&amp;#106;&amp;#117;&amp;#64;&amp;#109;&amp;#105;&amp;#99;&amp;#114;&amp;#111;&amp;#115;&amp;#111;&amp;#102;&amp;#116;&amp;#46;&amp;#99;&amp;#111;&amp;#109;"&gt;charju@microsoft.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/juqiang/aggbug/1977996.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2011/03/09/1977996.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2011/02/27/1966495.html</id><title type="text">塔防蜀的存档分析</title><summary type="text">最近在玩塔防新春版，上手很容易，过关也简单。偶很喜欢研究游戏存档，看看有没有什么特别的剧情、人物、道具能够出来。</summary><published>2011-02-27T13:18:00Z</published><updated>2011-02-27T13:18:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2011/02/27/1966495.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2011/02/27/1966495.html"/><content type="html">&lt;p&gt;最近在玩塔防新春版，上手很容易，过关也简单。偶很喜欢研究游戏存档，看看有没有什么特别的剧情、人物、道具能够出来。&lt;/p&gt;&lt;p&gt;首先用iFunBox或者别的东西，把存档目录copy到本地电脑上，如我这里就是存放在了：C:\Users\username\Desktop\FolderName\F38DE1C9-0098-42AC-AF62-8D2A6A82E44F。&lt;/p&gt;&lt;p&gt;下面有4个子目录，我感兴趣的是两个，一个是documents，这里存放存档文件；另一个是threekingdomstdsehd.app，这里面有所有的图片、音乐、将领资料、道具资料、地图、剧情。除了save.plist在documents目录外，其他的都是在前文中的第二个目录。所有的xml文件都包含有英语、简体中文、繁体中文和日文四种语言。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Items_HD.xml &lt;ul&gt;&lt;li&gt;物品一共分为3种，武器、装备、坐骑。对应的itemtypename分别是Weapon，equipment和viecle。攻击力最大的是方天画戟150，其次是青钢剑和朱雀爪，各自140。攻击范围最大的兵器是青龙偃月刀，32；最大的装备是孙子兵法、神兽砚、饺子和中国结，都是攻击范围增加40；最大的坐骑是赤兔，攻击范围增加48。&lt;/li&gt;&lt;li&gt;每个item下面 &lt;ul&gt;&lt;li&gt;icon image，指定了该道具的图片名称。&lt;/li&gt;&lt;li&gt;money包含buy和sell，我玩的里面没发现有可以买卖道具的地方，所以这个可能是为将来扩展用的。&lt;/li&gt;&lt;li&gt;limites。lv，这个应该是说武器最低使用等级，如诸葛连弩，只能3级或以上兵来用。wuxings这个不详，也许和五行有关？bosses，这个应该是该道具只能某个武将用。如，方天画戟只能吕布用。&lt;/li&gt;&lt;li&gt;Impacts，value=1应该是指攻击力，num=+150则意味着增加150。所以&amp;lt;impact value=&amp;#8221;1&amp;#8221; num=&amp;#8221;+150&amp;#8221;意味着方天画戟可以增加武将攻击力150。从其他的道具，如8651丈八蛇矛，impact value=&amp;#8221;5&amp;#8221; num=&amp;#8221;+32&amp;#8221;，结合介绍，可以看到，5代表攻击范围，值是num/2。所以这里意味着丈八蛇矛的攻击范围可以增加16。从9540倚天剑的介绍中可以猜出来，impact value=&amp;#8221;3&amp;#8221; num=&amp;#8221;+0.1&amp;#8221;，意味着倚天剑的攻击速度+0.1。再如9542青钢剑，impace value=&amp;#8221;5&amp;#8221; num=&amp;#8221;-32&amp;#8221;意味着青钢剑的攻击范围减少16。 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Skills_HD.xml &lt;ul&gt;&lt;li&gt;技能分为将领和普通兵的，但是从xml item上没有明显标志区分。&lt;/li&gt;&lt;li&gt;expend/food~value代表该技能消耗术的点数。如鼓舞，消耗45点术。注意的是，effectarea表明技能的使用范围，如鼓舞的effectarea value=&amp;#8221;320&amp;#8221;，但是游戏中用大、局部、全局来表示范围大小。如果看主要将领的最高一级技能，如水淹七军，可以知道effectarea value=&amp;#8221;19998&amp;#8221;代表全局。&lt;/li&gt;&lt;li&gt;duration代表技能持续时间；&lt;/li&gt;&lt;li&gt;effectargets，代表该技能针对哪些soldier有效，包括将领、普通兵种。如skill id=&amp;#8221;27&amp;#8220;，勇猛，专门针对张飞的：effectarget soldierid=&amp;#8221;18&amp;#8221;/8816/8815/8814/8813 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;soldier_HD.xml &lt;ul&gt;&lt;li&gt;所有的将领和普通兵的资料，这里面包含的是该将领&amp;#8220;&lt;strong&gt;初始&lt;/strong&gt;&amp;#8221;状态具有的道具和技能。&lt;/li&gt;&lt;li&gt;让人诟病的是，每个将领都按照start lv从1到5，设置了5条记录，并且分别采用不同的soldier id，不知道为什么要这么设计。本来我想写一个修改器，可以把曹操、吕布等都选成我的人，但是里面有5个曹操、5个吕布，实在影响心情啊！！！每个将领从1到5，是通过Promotie来连接的，类似于一个链表一样。如刘备id=16, promotie=8805;id=8805,promotie=8806这么连接下去的。&lt;/li&gt;&lt;li&gt;hp value、atk value分别是生命、攻击力，注意的是def value，如张飞def value=&amp;#8221;90&amp;#8221;，代表他的防御力，这个游戏里面没有用到。&lt;/li&gt;&lt;li&gt;Soldierskill代表该将领在每级可以拥有的技能，最多3项。注意里面有一个是requirementskillid value=&amp;#8221;0&amp;#8221;，貌似技能需要另外技能作为前提，这个游戏里面现在没有体现。&lt;/li&gt;&lt;li&gt;kindoms，似乎代表每个将领属于哪个主公的，xml中都是空，这个估计做外将来游戏扩展用。&lt;/li&gt;&lt;li&gt;里面有超过100个将领（士兵）的头像是dazhonglian01，就是&amp;#8220;大众脸&amp;#8221;，这个比较搞。如大名鼎鼎的曹彰、司马兄弟等。 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;save.plist &lt;ul&gt;&lt;li&gt;这里就是存档文件。因为游戏支持三个存档，所以文件中有三组plist/array/dict。&lt;/li&gt;&lt;li&gt;每个dict下面主要分为hero、level、storage、unit、是否完成。&lt;/li&gt;&lt;li&gt;hero &lt;ul&gt;&lt;li&gt;下面有若干个dict，代表将领的信息。isActive意味着该将领是否在出征队列。curExp代表经验值，这是一个real类型，比较怪异。&lt;/li&gt;&lt;li&gt;然后是5组的道具信息，用center/downleft/downright/topleft/topright代表，该位置是否装备着某个武器或者道具或者坐骑（中间、左下、右下、左上、右上）。如果是-1，则意味该位置没有装备。如果都是-1,则该将领没有任何装备。&lt;/li&gt;&lt;li&gt;id代表武将或者士兵的id，和soldier_hd.xml相关联。 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;level &lt;ul&gt;&lt;li&gt;easyHighscore、hardHighscore，代表普通、难的最高分。&lt;/li&gt;&lt;li&gt;maxStar代表几个星 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;storage &lt;ul&gt;&lt;li&gt;包含了当前仓库里面可用的装备信息，用id与items_hd.xml关联。 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Unit &lt;ul&gt;&lt;li&gt;代表出场的士兵，如大象、弓兵等，用id与soldier_hd.xml关联。 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Stage*_level_hd.xml &lt;ul&gt;&lt;li&gt;*代表第几关，如01代表第一关。&lt;/li&gt;&lt;li&gt;enemy_bosses代表本关会出场的boss的id，与soldier_hd.xml关联。&lt;/li&gt;&lt;li&gt;exp_prize代表本关可以得到的经验值&lt;/li&gt;&lt;li&gt;resource/money代表初始金币，resource/food代表初始术&lt;/li&gt;&lt;li&gt;bonusitems代表本关可能出现的宝物奖励。如level01，有铁戟蛇矛、钱串等物品。每个物品后面有一个probability，应该代表掉落纪律。如铁戟蛇矛，0.7，但是钱串是1.3。所以不解这里是代表70%、130%还是说代表0.7%和1.3%。如果是后者，那么掉落几率是在太小了。&lt;/li&gt;&lt;li&gt;Attackwave代表第几波的攻击。soldiers/soldier代表这一波有哪些将领、士兵来攻击；pathnodes代表在地图上的行动路线。&lt;/li&gt;&lt;li&gt;最后是events，分为condition和result，如event id=123226代表刘备如果遇到孙权，那么会发生单挑，如果单挑成功，则孙权退走。&amp;lt;dropitem triger=&amp;#8221;false&amp;#8221; itemid=&amp;#8221;0/&amp;gt;，这里让我比较迷惑，看了很多关，这里好像都是triger=false, itemid=0。 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;state*_map_hd.xml &lt;ul&gt;&lt;li&gt;同上，02代表第二关。&lt;/li&gt;&lt;li&gt;里面都是地图的描述，不感兴趣。除非自己要写地图编辑器。 &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;总结一下，基本上通过上述几个文件的增加、修改，开发商就可以迅速造出大量剧本和关卡莱。我们要自己改，也很容易。&lt;/p&gt;&lt;p&gt;如果要改装备，就修改save.plist。如果要改将领的攻击力、速度等，就改soldier_hd.xml，如果要改将领的技能，也改soldier_hd这个文件。&lt;/p&gt;&lt;p&gt;如果改某项技能的花钱数（如水淹七军只用1个术，或者负数），则修改skill_hd.xml。&lt;/p&gt;&lt;p&gt;其他诸如每关开始的钱、术，修改stage*_level_hd.xml即可。&lt;/p&gt; &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1966495.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2011/02/27/1966495.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/08/04/1792551.html</id><title type="text">我的HD2手机</title><summary type="text">在我的HD2上写的程序，原生的CF太那个了，要崩溃了……</summary><published>2010-08-04T11:33:00Z</published><updated>2010-08-04T11:33:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/08/04/1792551.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/08/04/1792551.html"/><content type="html">&lt;p&gt;感觉Windows Mobile 6.5的API实在太那个了&amp;#8230;&amp;#8230;&amp;#8230;&amp;#8230;&amp;#8230;&amp;#8230;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;放两张下午写的小东西的图。那个comboBox、那个numericUpDown、那个MenuItem，偶要疯掉了。&lt;/p&gt;&lt;p&gt;这个是竖屏的，numericUpDown是自己做的一个很简单的UserControl。&lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/juqiang/Screen002.jpg" width="480" height="800" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这个也是竖屏的，恶心的ComboBox，手根本不好点选。&lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/juqiang/Screen003.jpg" width="480" height="800" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这个做成了横屏的，WM自己的numricUpDown&lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/juqiang/Screen006.jpg" width="800" height="480" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;最后这个是天气预报，下午刚写的，看起来还好，hoho。&lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/juqiang/Screen005.jpg" width="480" height="800" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;看到这个&amp;#8220;选择城市&amp;#8221;的菜单，我崩溃了&amp;#8230;&amp;#8230;黑乎乎的界面，&lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/juqiang/Screen007.jpg" width="480" height="800" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/juqiang/aggbug/1792551.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/08/04/1792551.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/06/27/1766181.html</id><title type="text">和我一起作Tess的windbg lab，结束</title><summary type="text">这7篇post是花了3个小时分析+写完的。欣慰的是，偶已经比当年牛一些了，Tess大牛的7个lab被这么快搞完，哈哈！应一些兄弟的要求，写了一下这个，还是比较粗糙。因为好多人最concern的是，抓到这个dump后，你为什么要敲那些命令？而不是敲这些命令？so，偶尽量写一下思路。当然，windbg这个东西还是要多练习的。否则的话，时间长了，就废了。我的分析还是很粗糙，有的思路也不严谨，so，可以到...</summary><published>2010-06-27T07:25:00Z</published><updated>2010-06-27T07:25:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766181.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766181.html"/><content type="html">&lt;p&gt;这7篇post是花了3个小时分析+写完的。欣慰的是，偶已经比当年牛一些了，Tess大牛的7个lab被这么快搞完，哈哈！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;应一些兄弟的要求，写了一下这个，还是比较粗糙。因为好多人最concern的是，抓到这个dump后，你为什么要敲那些命令？而不是敲这些命令？so，偶尽量写一下思路。&lt;/p&gt;&lt;p&gt;当然，windbg这个东西还是要多练习的。否则的话，时间长了，就废了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;我的分析还是很粗糙，有的思路也不严谨，so，可以到tess的blog上看。我在7篇中写的是lab的地址，每个review的地址大家可以自己找。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Tess现在是GTSC的EE，瑞典人，大牛，貌似也是一个美女，膜拜一下&amp;#8230;&amp;#8230;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1766181.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766181.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/06/27/1766180.html</id><title type="text">和我一起作Tess的windbg lab - Lab7, MemoryLeak</title><summary type="text">跟我来一起分析Tess的系列Lab，这是第七部分，关于Memory Leak的，主要介绍分析思路，以及一些技巧...</summary><published>2010-06-27T07:21:00Z</published><updated>2010-06-27T07:21:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766180.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766180.html"/><content type="html">&lt;p&gt;原文地址：&lt;a href="http://blogs.msdn.com/b/tess/archive/2008/03/25/net-debugging-demos-lab-7-memory-leak.aspx" target="_blank"&gt;http://blogs.msdn.com/b/tess/archive/2008/03/25/net-debugging-demos-lab-7-memory-leak.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;操作步骤：&lt;/p&gt;&lt;p&gt;1、产生压力：tinyget -srv:localhost -uri:/BuggyBits/News.aspx -threads:500 -loop:200&lt;/p&gt;&lt;p&gt;2、抓一个hang的dump，看看gc heap大小，!eeheap -gc，如下：&lt;/p&gt;&lt;p&gt;GC Heap Size&amp;nbsp; 0x1899f44c(412742732)，大概400M，dump文件整个为550M。&lt;/p&gt;&lt;p&gt;3、看一下gc heap的总体状况：!dumpheap -stat，输出如下：&lt;/p&gt;&lt;p&gt;7912d7c0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1342&amp;nbsp;&amp;nbsp;&amp;nbsp; 400044140 System.Int32[]&lt;/p&gt;&lt;p&gt;嗯，一共1300多个数组，但是这些数组居然占了400M，和gc heap的大小差不多。&lt;/p&gt;&lt;p&gt;4、察看一下详细情况，因为只有1300多个，所以我们可以全部打印出来：!dumpheap -mt 7912d7c0&lt;/p&gt;&lt;p&gt;5、几乎所有的数组，大小都是400K，随便找一个，然后找一下该数组的root，运行!gcroot 1f981e60，结果如下：&lt;/p&gt;&lt;p&gt;Scan Thread 49 OSTHread 2234&lt;br /&gt;DOMAIN(00115B40):HANDLE(WeakLn):24b10dc:Root:02a621f4(System.Web.NativeFileChangeNotification)-&amp;gt;&lt;br /&gt;02a621d8(System.Web.DirMonCompletion)-&amp;gt;&lt;br /&gt;02a61ea4(System.Web.DirectoryMonitor)-&amp;gt;&lt;br /&gt;02a61ec8(System.Collections.Hashtable)-&amp;gt;&lt;br /&gt;02a61f00(System.Collections.Hashtable+bucket[])-&amp;gt;&lt;br /&gt;02a62100(System.Web.FileMonitor)-&amp;gt;&lt;br /&gt;02a62134(System.Collections.Specialized.HybridDictionary)-&amp;gt;&lt;br /&gt;02a62178(System.Collections.Specialized.ListDictionary)-&amp;gt;&lt;br /&gt;02a62194(System.Collections.Specialized.ListDictionary+DictionaryNode)-&amp;gt;&lt;br /&gt;02a5d538(System.Web.Compilation.BuildManager)-&amp;gt;&lt;br /&gt;02a5e0fc(System.Web.Compilation.MemoryBuildResultCache)-&amp;gt;&lt;br /&gt;02a2c970(System.Web.Caching.CacheSingle)-&amp;gt;&lt;br /&gt;02a2ca00(System.Web.Caching.CacheExpires)-&amp;gt;&lt;br /&gt;02a2ca20(System.Object[])-&amp;gt;&lt;br /&gt;02a2cd64(System.Web.Caching.ExpiresBucket)-&amp;gt;&lt;br /&gt;02b2e948(System.Web.Caching.ExpiresPage[])-&amp;gt;&lt;br /&gt;1b078ff0(System.Web.Caching.ExpiresEntry[])-&amp;gt;&lt;br /&gt;1b20583c(System.Web.Caching.CacheEntry)-&amp;gt;&lt;br /&gt;1b20581c(System.Web.Caching.CacheItemRemovedCallback)-&amp;gt;&lt;br /&gt;1b203db0(ASP.news_aspx)-&amp;gt;&lt;br /&gt;1f981e60(System.Int32[])&lt;br /&gt;6、看其他的几个数组，引用顺序差不多。&lt;/p&gt;&lt;p&gt;7、猜测：代码中用了cache，cache中包含了一个400K的数组。但是由于某种原因，cache里面的东西没释放掉，越来越大。&lt;/p&gt;&lt;p&gt;8、查看源代码&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string news = "&amp;lt;I&amp;gt;New site launched 2008-02-02&amp;lt;/I&amp;gt;";&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string key = Guid.NewGuid().ToString();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cache.Add(key, news, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 5, 0), CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(this.RemovedCallback)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblNews.Text = ((string)Cache[key]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Cache有一个5分钟的失效期。但是由于我们的测试中，负载上来了，还没有到5分钟，所以看到的cache还在内存中。那么5分钟之后呢，可能会消失。但是更可能的是，在3分钟的时候，负载太大了，cache的东西又加上来了，最终导致OOM，程序挂了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Over&lt;/p&gt; &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1766180.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766180.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/06/27/1766174.html</id><title type="text">和我一起作Tess的windbg lab - Lab6, MemoryLeak</title><summary type="text">跟我来一起分析Tess的系列Lab，这是第六部分，关于Memory Leak的，主要介绍分析思路，以及一些技巧... </summary><published>2010-06-27T06:59:00Z</published><updated>2010-06-27T06:59:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766174.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766174.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: 12pt"&gt;原文地址：&lt;/span&gt;&lt;a href="http://blogs.msdn.com/b/tess/archive/2008/03/17/net-debugging-demos-lab-6-memory-leak.aspx" target="_blank"&gt;&lt;span style="font-size: 12pt"&gt;http://blogs.msdn.com/b/tess/archive/2008/03/17/net-debugging-demos-lab-6-memory-leak.aspx&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;操作步骤：&lt;/p&gt;&lt;p&gt;1、产生压力：&amp;nbsp;tinyget -srv:localhost -uri:/BuggyBits/ProductInfo.aspx?ProductName=Bugspray -threads:50 -loop:20&lt;/p&gt;&lt;p&gt;2、这个比较有意思，CPU很高，经常100%，内存很少，几十M而已。如果你仔细看taskmgr，会看到有几个csc诡异的出现，忙了一会，又消失了。&lt;/p&gt;&lt;p&gt;3、抓一个hang的dump，运行!eeheap -gc，看看内存状况：&lt;/p&gt;&lt;p&gt;GC Heap Size&amp;nbsp; 0x68a0fc(6856956)&lt;/p&gt;&lt;p&gt;托管内存只用到了6M多，而我的dump是190M，那么，其余的内存被谁用了？&lt;/p&gt;&lt;p&gt;4、联想到步骤2中的诡异的csc进程，我们需要再检查一下，!eeheap -loader，看看有多少dll在loader heap里面？我这里一共看到了2223个&lt;/p&gt;&lt;p&gt;5、随便找一个module看看&lt;/p&gt;&lt;p&gt;0:000&amp;gt; !dumpmodule -mt 06f0ab78&lt;br /&gt;Name: oghe0kiv, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null&lt;br /&gt;Attributes: PEFile &lt;br /&gt;Assembly: 07093808&lt;br /&gt;LoaderHeap: 00000000&lt;br /&gt;TypeDefToMethodTableMap: 0702f8c4&lt;br /&gt;TypeRefToMethodTableMap: 0702f8dc&lt;br /&gt;MethodDefToDescMap: 0702f93c&lt;br /&gt;FieldDefToDescMap: 0702f9a8&lt;br /&gt;MemberRefToDescMap: 0702f9d4&lt;br /&gt;FileReferencesMap: 0702fac4&lt;br /&gt;AssemblyReferencesMap: 0702fac8&lt;br /&gt;MetaData start address: 072e09e4 (4184 bytes)&lt;/p&gt;&lt;p&gt;Types defined in this module&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MT&amp;nbsp;&amp;nbsp;&amp;nbsp; TypeDef Name&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;06f0b7ac 0x02000002 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterProduct&lt;br /&gt;06f0b6fc 0x02000006 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializerContract&lt;/p&gt;&lt;p&gt;Types referenced in this module&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MT&amp;nbsp;&amp;nbsp;&amp;nbsp; TypeRef Name&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;63a28fb0 0x01000001 System.Xml.Serialization.XmlSerializationWriter&lt;br /&gt;63a295a4 0x01000004 System.Xml.Serialization.XmlSerializerImplementation&lt;br /&gt;05e60b3c 0x01000005 Product&lt;br /&gt;05e60bbc 0x01000006 ShippingInfo&lt;br /&gt;79101fe4 0x01000008 System.Collections.Hashtable&lt;br /&gt;79106894 0x01000009 System.Type&lt;br /&gt;790fd0f0 0x0100000f System.Object&lt;br /&gt;639ff1c4 0x01000013 System.Xml.XmlConvert&lt;br /&gt;&lt;/p&gt;&lt;p&gt;6、看到这里基本清楚了，这就是那个著名的XmlSerializer的问题。可以参考我以前写的blog：&lt;a href="http://www.cnblogs.com/juqiang/archive/2008/01/15/1039936.html" target="_blank"&gt;http://www.cnblogs.com/juqiang/archive/2008/01/15/1039936.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Over&lt;/p&gt; &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1766174.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766174.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/06/27/1766171.html</id><title type="text">和我一起作Tess的windbg lab - Lab5, Crash</title><summary type="text">跟我来一起分析Tess的系列Lab，这是第五部分，关于Crash的，主要介绍分析思路，以及一些技巧... </summary><published>2010-06-27T06:44:00Z</published><updated>2010-06-27T06:44:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766171.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766171.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: 12pt"&gt;原文地址：&lt;/span&gt;&lt;a href="http://blogs.msdn.com/b/tess/archive/2008/03/05/net-debugging-demos-lab-5-crash.aspx" target="_blank"&gt;&lt;span style="font-size: 12pt"&gt;http://blogs.msdn.com/b/tess/archive/2008/03/05/net-debugging-demos-lab-5-crash.aspx&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;操作步骤：&lt;/p&gt;&lt;p&gt;1、运行CompanyInformation.aspx&lt;/p&gt;&lt;p&gt;2、在输入框中输入一个字符串，如aaa，点Send按钮&lt;/p&gt;&lt;p&gt;3、等了几秒钟，IE报错：无法显示网页&lt;/p&gt;&lt;p&gt;4、抓一个crash的dump，加载SOS，看一下!threads，输出如下：&lt;/p&gt;&lt;p&gt;Hosted Runtime: yes&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreEmptive&amp;nbsp;&amp;nbsp; GC Alloc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lock&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ID OSID ThreadOBJ&amp;nbsp;&amp;nbsp;&amp;nbsp; State&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Domain&amp;nbsp;&amp;nbsp; Count APT Exception&lt;br /&gt;XXXX&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp; dd0 000dbce8&amp;nbsp;&amp;nbsp; 1808220 Disabled 00000000:00000000 00102870&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 Ukn (Threadpool Worker) System.StackOverflowException (0291106c) (nested exceptions)&lt;br /&gt;XXXX&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp; f70 000e7ec8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b220 Enabled&amp;nbsp; 00000000:00000000 000d91a0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn (Finalizer)&lt;br /&gt;XXXX&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;nbsp; f80 000ec3a8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1220 Enabled&amp;nbsp; 00000000:00000000 000d91a0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;br /&gt;XXXX&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp; 868 000ff360&amp;nbsp;&amp;nbsp;&amp;nbsp; 80a220 Enabled&amp;nbsp; 00000000:00000000 000d91a0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn (Threadpool Completion Port)&lt;br /&gt;XXXX&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&amp;nbsp; fac 00151ad0&amp;nbsp;&amp;nbsp; 880a220 Enabled&amp;nbsp; 00000000:00000000 000d91a0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn (Threadpool Completion Port)&lt;br /&gt;托管线程有5个，但是都挂掉了。&lt;/p&gt;&lt;p&gt;5、重新抓dump，使用参数-FullOnFirst，等了N久，dump也没抓完。咋回事？停掉adplus，到dump目录看一下，2分钟内，居然有10几个dump，而且大小完全一致。&lt;/p&gt;&lt;p&gt;6、打开最早的一个dump，由于是crash的dump，所以windbg自动切换到出问题的线程，如下：&lt;/p&gt;&lt;p&gt;OS Thread Id: 0x364 (16)&lt;br /&gt;ESP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EIP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0203f1f0 7c80bee7 [HelperMethodFrame: 0203f1f0] &lt;br /&gt;0203f294 05770ae7 BuggyMail.IsValidEmailAddress(System.String)&lt;/p&gt;&lt;p&gt;嗯，看来是IsValidEmailAddress这里出问题了。&lt;/p&gt;&lt;p&gt;7、别急，打开第二个dump看看：&lt;/p&gt;&lt;p&gt;OS Thread Id: 0x364 (16)&lt;br /&gt;ESP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EIP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0203efbc 7c80bee7 [HelperMethodFrame: 0203efbc] &lt;br /&gt;0203f060 7948d980 System.IO.__Error.WinIOError(Int32, System.String)&lt;br /&gt;0203f08c 79395557 System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean)&lt;br /&gt;0203f184 793983c8 System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)&lt;br /&gt;0203f1b0 793984e3 System.IO.StreamWriter.CreateFile(System.String, Boolean)&lt;br /&gt;0203f1c0 79398550 System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)&lt;br /&gt;0203f1e0 7949959c System.IO.StreamWriter..ctor(System.String)&lt;br /&gt;0203f1ec 05770b52 Utility.WriteToLog(System.String, System.String)&lt;br /&gt;0203f220 05770b0b ExceptionHandler.LogException(System.Exception)&lt;br /&gt;0203f224 05770a81 BuggyMail.SendEmail(System.String, System.String)&lt;/p&gt;&lt;p&gt;比较有意思，在SendEmail里面，调用了LogException，然后在最上面产生了一个WinIOError&lt;/p&gt;&lt;p&gt;8、打开最后一个看看：&lt;/p&gt;&lt;p&gt;OS Thread Id: 0x364 (16)&lt;br /&gt;ESP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EIP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0203ec4c 7c80bee7 [HelperMethodFrame: 0203ec4c] &lt;br /&gt;0203ecf0 7948d980 System.IO.__Error.WinIOError(Int32, System.String)&lt;br /&gt;0203ed1c 79395557 System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean)&lt;br /&gt;0203ee14 793983c8 System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)&lt;br /&gt;0203ee40 793984e3 System.IO.StreamWriter.CreateFile(System.String, Boolean)&lt;br /&gt;0203ee50 79398550 System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)&lt;br /&gt;0203ee70 7949959c System.IO.StreamWriter..ctor(System.String)&lt;br /&gt;0203ee7c 05770b52 Utility.WriteToLog(System.String, System.String)&lt;br /&gt;0203eeb0 05770b0b ExceptionHandler.LogException(System.Exception)&lt;br /&gt;0203eeb4 05770bd4 Utility.WriteToLog(System.String, System.String)&lt;br /&gt;0203ef60 05770b0b ExceptionHandler.LogException(System.Exception)&lt;br /&gt;0203ef64 05770bd4 Utility.WriteToLog(System.String, System.String)&lt;br /&gt;0203f010 05770b0b ExceptionHandler.LogException(System.Exception)&lt;br /&gt;0203f014 05770bd4 Utility.WriteToLog(System.String, System.String)&lt;br /&gt;0203f0c0 05770b0b ExceptionHandler.LogException(System.Exception)&lt;br /&gt;0203f0c4 05770bd4 Utility.WriteToLog(System.String, System.String)&lt;br /&gt;0203f170 05770b0b ExceptionHandler.LogException(System.Exception)&lt;br /&gt;0203f174 05770bd4 Utility.WriteToLog(System.String, System.String)&lt;br /&gt;0203f220 05770b0b ExceptionHandler.LogException(System.Exception)&lt;br /&gt;0203f224 05770a81 BuggyMail.SendEmail(System.String, System.String)&lt;br /&gt;0203f2c8 05770a28 CompanyInformation.btnContact_Click(System.Object, System.EventArgs)&lt;br /&gt;从最下面的SendEmail往上看，LogException调用了WriteToLog，然后WriteToLog又调用了LogException，后者又调用了WriteToLog。&lt;/p&gt;&lt;p&gt;9、结合上面步骤4的线程1最后那个列：StackOverFlowException，我们猜测，上面步骤8的结果可能就是StackOverFlowException的原因。那么，步骤8的最上面一行的WinIOError是什么意思呢？我们看一下出问题的线程16上的栈上的变量，运行!dso，结果如下：（部分）&lt;/p&gt;&lt;p&gt;0203ee48 02b38358 System.String&amp;nbsp;&amp;nbsp;&amp;nbsp; c:\log.txt&lt;br /&gt;0203ee54 02b3a850 System.String&amp;nbsp;&amp;nbsp;&amp;nbsp; Access to the path 'c:\log.txt' is denied.&lt;/p&gt;&lt;p&gt;10、基本能猜测到，要访问c:\log.txt，但是无权限导致IOError的。&lt;/p&gt;&lt;p&gt;11、看代码，找到SendEmail那段：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void SendEmail(string message, string emailAddres){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IsValidEmailAddress(emailAddres))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // send an email with the message&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception ex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExceptionHandler.LogException(ex);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;回到步骤6，正是从IsValidEmailAddress开始发生异常的。由于我输入的字符串是bbb，不是一个合理的email地址，所以会有异常（可以看Isvalid这个方法），然后异常被扔到了catch块中。&lt;/p&gt;&lt;p&gt;12、看catch里面的LogException怎么写的：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void LogException(Exception ex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Utility.WriteToLog(ex.Message, "c:\\log.txt");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;13、哈，这里出现了上面从!dso中看到的c:\log.txt字符串。这个没问题，看WriteToLog怎么写的。代码如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void WriteToLog(string message, string fileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (StreamWriter sw = new StreamWriter(fileName))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Log the event with date and time.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sw.WriteLine("--------------------------");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sw.WriteLine(DateTime.Now.ToLongTimeString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sw.WriteLine("-------------------");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sw.WriteLine(message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception ex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExceptionHandler.LogException(ex);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/p&gt;&lt;p&gt;这里try的地方可能会有问题，比如无权限、文件不存在等。关键的地方在于，try的地方如果出错，会被扔到catch块里面，执行LogException操作。&lt;/p&gt;&lt;p&gt;看明白了吗？如果这里有exception出现，就又返回到了步骤12中，最终又调用到了这里，又有exception，又返回到步骤12&amp;#8230;&amp;#8230;&amp;#8230;&amp;#8230;&amp;#8230;&amp;#8230;&lt;/p&gt;&lt;p&gt;14、解决办法，手工创建一个c:\log.txt，右键修改该文件的security，增加iuser_机器名这个用户，赋予full control。重新运行程序，好了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Over&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1766171.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766171.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/06/27/1766157.html</id><title type="text">和我一起作Tess的windbg lab - Lab4, High CPU</title><summary type="text">跟我来一起分析Tess的系列Lab，这是第四部分，关于High CPU的，主要介绍分析思路，以及一些技巧... ... </summary><published>2010-06-27T06:02:00Z</published><updated>2010-06-27T06:02:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766157.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766157.html"/><content type="html">&lt;p&gt;原文地址：&lt;a href="http://blogs.msdn.com/b/tess/archive/2008/02/22/net-debugging-demos-lab-4-high-cpu-hang.aspx" target="_blank"&gt;http://blogs.msdn.com/b/tess/archive/2008/02/22/net-debugging-demos-lab-4-high-cpu-hang.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;操作步骤：&lt;/p&gt;&lt;p&gt;1、产生压力：tinyget -srv:localhost -uri:/BuggyBits/AllProducts.aspx -threads:5 -loop:1&lt;/p&gt;&lt;p&gt;2、观察taskmgr的输出，w3wp的CPU为99%，这是一个典型的高CPU的Hang。抓一个hang的dump，然后等待10秒钟，再抓一个；10秒钟之后再抓一个。一共抓3个。&lt;/p&gt;&lt;p&gt;3、打开这三个dump，加载sos之后，分别查看!runaway的输出。&lt;/p&gt;&lt;p&gt;第一个dump的结果：&lt;/p&gt;&lt;p&gt;0:000&amp;gt; !runaway&lt;br /&gt;&amp;nbsp;User Mode Time&lt;br /&gt;&amp;nbsp; Thread&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Time&lt;br /&gt;&amp;nbsp; 27:848&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:06.279&lt;br /&gt;&amp;nbsp; 26:c84&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:03.054&lt;br /&gt;&amp;nbsp; 16:f10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:02.784&lt;br /&gt;&amp;nbsp; 28:d14&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:02.403&lt;br /&gt;&amp;nbsp; 23:f0c&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:02.323&lt;/p&gt;&lt;p&gt;第二个dump的结果：&lt;/p&gt;&lt;p&gt;0:000&amp;gt; !runaway&lt;br /&gt;&amp;nbsp;User Mode Time&lt;br /&gt;&amp;nbsp; Thread&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Time&lt;br /&gt;&amp;nbsp; 26:848&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:06.990&lt;br /&gt;&amp;nbsp; 25:c84&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:06.138&lt;br /&gt;&amp;nbsp; 22:f0c&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:05.718&lt;br /&gt;&amp;nbsp; 16:f10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:05.387&lt;br /&gt;&amp;nbsp; 27:d14&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:04.546&lt;/p&gt;&lt;p&gt;第三个dump的结果：&lt;/p&gt;&lt;p&gt;0:000&amp;gt; !runaway&lt;br /&gt;&amp;nbsp;User Mode Time&lt;br /&gt;&amp;nbsp; Thread&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Time&lt;br /&gt;&amp;nbsp; 25:848&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:12.167&lt;br /&gt;&amp;nbsp; 26:d14&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:09.373&lt;br /&gt;&amp;nbsp; 22:f0c&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:08.422&lt;br /&gt;&amp;nbsp; 24:c84&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:07.811&lt;br /&gt;&amp;nbsp; 16:f10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 days 0:00:07.250&lt;/p&gt;&lt;p&gt;4、从上面三个dump来看，只有16和26号线程的时间一直在增长。&lt;/p&gt;&lt;p&gt;5、查看三个dump的!threadpool，都是100%&lt;/p&gt;&lt;p&gt;6、查看16和26号的托管callstack，如下：&lt;/p&gt;&lt;p&gt;OS Thread Id: 0xd14 (26)&lt;br /&gt;ESP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EIP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;04faf034 7c9585ec [HelperMethodFrame: 04faf034] &lt;br /&gt;04faf0a0 058f0981 AllProducts.Page_Load(System.Object, System.EventArgs)&lt;/p&gt;&lt;p&gt;7、查看所有托管线程的callstack，与上述代码类似，如25号线程。这里我们猜测，tinyget的压力不是一下子上来的，25号线程是后跑起来的，所以第一个dump的runaway中没有它的比较大的时间输出。&lt;/p&gt;&lt;p&gt;8、查看其他线程，加载合适的symbol之后，你会发现24号线程在作String.Concat和GC的操作。&lt;/p&gt;&lt;p&gt;9、查看上述的Page_load方法，里面调用了一个循环10000次的方法，然后针对输出的DataTable，进行了大量的String.Concat操作。我们知道，大量的Concat操作，同时也会在内存上产生大量的字符串对象，对内存会有压力，对GC也会有压力。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Over&lt;/p&gt; &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1766157.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766157.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/06/27/1766143.html</id><title type="text">和我一起作Tess的windbg lab - Lab3, Memory</title><summary type="text">跟我来一起分析Tess的系列Lab，这是第三部分，关于Memory的，主要介绍分析思路，以及一些技巧... ... </summary><published>2010-06-27T05:30:00Z</published><updated>2010-06-27T05:30:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766143.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766143.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: 12pt"&gt;原文地址：&lt;/span&gt;&lt;a href="http://blogs.msdn.com/b/tess/archive/2008/02/15/net-debugging-demos-lab-3-memory.aspx" target="_blank"&gt;&lt;span style="font-size: 12pt"&gt;http://blogs.msdn.com/b/tess/archive/2008/02/15/net-debugging-demos-lab-3-memory.aspx&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;操作步骤：&lt;/p&gt;&lt;p&gt;1、产生压力：tinyget -srv:localhost -uri:/BuggyBits/Links.aspx -loop:4000&lt;/p&gt;&lt;p&gt;2、观察taskmgr的输出，w3wp的内存每秒钟大概增长100M。&lt;/p&gt;&lt;p&gt;3、内存到700M左右的时候，抓一个hang dump&lt;/p&gt;&lt;p&gt;4、由于这是一个memory的问题，所以我们要先看GC Heap的情况，运行命令：!eeheap -gc，结果如下：&lt;/p&gt;&lt;p&gt;GC Heap Size&amp;nbsp; 0x2b307720(724596512)&lt;/p&gt;&lt;p&gt;由于dump一共870M，而GC占用了720M左右，所以我们的重点在于托管内存的分析。&lt;/p&gt;&lt;p&gt;5、看heap的整体状况，运行!dumpheap -stat，结果如下：&lt;/p&gt;&lt;p&gt;790fd8c4&amp;nbsp;&amp;nbsp;&amp;nbsp; 49787&amp;nbsp;&amp;nbsp;&amp;nbsp; 721599752 System.String&lt;/p&gt;&lt;p&gt;嗯，720M的托管内存中，String占用了绝大多数。&lt;/p&gt;&lt;p&gt;6、看一下string的情况，根据2/8原则，大小相同的string也许会很多，这里我们过滤一下，看看10K以上大小的字符串，运行命令：!dumpheap -mt 790fd8c4&amp;nbsp;&amp;nbsp;-min 10000&lt;/p&gt;&lt;p&gt;0331d6dc 790fd8c4&amp;nbsp;&amp;nbsp;&amp;nbsp; 20020&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;03322534 790fd8c4&amp;nbsp;&amp;nbsp;&amp;nbsp; 20020&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0332738c 790fd8c4&amp;nbsp;&amp;nbsp;&amp;nbsp; 20020&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0332c1e4 790fd8c4&amp;nbsp;&amp;nbsp;&amp;nbsp; 20020&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0333103c 790fd8c4&amp;nbsp;&amp;nbsp;&amp;nbsp; 20020&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p&gt;大部分都是20K的字符串，随便找一个，我们需要看它被谁分配的&lt;/p&gt;&lt;p&gt;7、运行!gcroot 0331d6dc，结果如下：&lt;/p&gt;&lt;p&gt;Scan Thread 16 OSTHread 318&lt;br /&gt;Scan Thread 18 OSTHread c38&lt;br /&gt;Scan Thread 19 OSTHread a40&lt;br /&gt;Scan Thread 20 OSTHread c00&lt;br /&gt;Scan Thread 24 OSTHread 998&lt;br /&gt;Scan Thread 14 OSTHread 4cc&lt;br /&gt;Finalizer queue:Root:0331d6b8(Link)-&amp;gt;&lt;br /&gt;0331d6c8(System.Text.StringBuilder)-&amp;gt;&lt;br /&gt;0331d6dc(System.String)&lt;/p&gt;&lt;p&gt;在14号线程中，Link引用了这个字符串。而且我们看到，link是在Finalizer Queue中的。&lt;/p&gt;&lt;p&gt;8、查看finalizequeue，输出如下：&lt;/p&gt;&lt;p&gt;057e0bcc&amp;nbsp;&amp;nbsp;&amp;nbsp; 35998&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 575968 Link&lt;/p&gt;&lt;p&gt;一共35998个Link对象。由于该对象存在于Finalizequeue中，所以一定显示的实现了Finalize方法。&lt;/p&gt;&lt;p&gt;9、查看该方法，代码如下：&lt;/p&gt;&lt;p&gt;~Link()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//some long running operation when cleaning up the data&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(5000);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;10、换个方向，看上面步骤7中的那个Link对象，!do 0331d6b8，输出结果如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MT&amp;nbsp;&amp;nbsp;&amp;nbsp; Field&amp;nbsp;&amp;nbsp; Offset&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type VT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Attr&amp;nbsp;&amp;nbsp;&amp;nbsp; Value Name&lt;br /&gt;790fdc5c&amp;nbsp; 4000006&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4 ...ext.StringBuilder&amp;nbsp; 0 instance 0331d6c8 url&lt;br /&gt;790fd8c4&amp;nbsp; 4000007&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.String&amp;nbsp; 0 instance 029bb0b8 name&lt;br /&gt;再看第一个url对象，运行!do 0331d6c8 ，结果如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MT&amp;nbsp;&amp;nbsp;&amp;nbsp; Field&amp;nbsp;&amp;nbsp; Offset&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type VT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Attr&amp;nbsp;&amp;nbsp;&amp;nbsp; Value Name&lt;br /&gt;791016bc&amp;nbsp; 40000b1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.IntPtr&amp;nbsp; 1 instance&amp;nbsp;&amp;nbsp;&amp;nbsp; dc1d8 m_currentThread&lt;br /&gt;79102290&amp;nbsp; 40000b2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Int32&amp;nbsp; 1 instance 2147483647 m_MaxCapacity&lt;br /&gt;790fd8c4&amp;nbsp; 40000b3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.String&amp;nbsp; 0 instance 0331d6dc m_StringValue&lt;/p&gt;&lt;p&gt;注意最后一行的那个m_StringValue，对比一下步骤7中的!gcroot输入。&lt;/p&gt;&lt;p&gt;从这里我们看到，Link中包含了一个StringBuilder，而StringBuilder中包含了一个20K的字符串。&lt;/p&gt;&lt;p&gt;11、看代码：&lt;/p&gt;&lt;p&gt;public Link(string name, string url)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.name = name;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.url.Append(url);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;可以看到，Link对象的构造方法中，引用了字符串。&lt;/p&gt;&lt;p&gt;12、再回头看上面的步骤9，Link自作聪明的实现了Finalize方法，但是该方法执行的时间太长（这里是5秒钟），导致垃圾回收的时候，迟迟不能把该对象回收掉。因为Link引用了字符串url，所以相应的字符串也无法被回收。这样内存就上涨的很快了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Over&lt;/p&gt;  &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1766143.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766143.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/juqiang/archive/2010/06/27/1766132.html</id><title type="text">和我一起作Tess的windbg lab - Lab2, Crash</title><summary type="text">跟我来一起分析Tess的系列Lab，这是第二部分，关于Crash的，主要介绍分析思路，以及一些技巧... </summary><published>2010-06-27T05:01:00Z</published><updated>2010-06-27T05:01:00Z</updated><author><name>鞠强</name><uri>http://www.cnblogs.com/juqiang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766132.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766132.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: 12pt"&gt;原文地址：&lt;/span&gt;&lt;a href="http://blogs.msdn.com/b/tess/archive/2008/02/08/net-debugging-demos-lab-2-crash.aspx" target="_blank"&gt;&lt;span style="font-size: 12pt"&gt;http://blogs.msdn.com/b/tess/archive/2008/02/08/net-debugging-demos-lab-2-crash.aspx&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;操作步骤：&lt;/p&gt;&lt;p&gt;1、打开&amp;nbsp;&lt;a href="http://localhost/BuggyBits/Reviews.aspx" target="_blank"&gt;http://localhost/BuggyBits/Reviews.aspx&lt;/a&gt;，点击5次refresh按钮，然后看到巨大的黑色粗体字：Service Unavailable&lt;/p&gt;&lt;p&gt;2、检察eventlog，点开始-运行，输入：eventvwr，先看Application的，会有如下错误：&lt;/p&gt;&lt;p&gt;Process ID: 1808&lt;/p&gt;&lt;p&gt;Exception: System.NullReferenceException&lt;br /&gt;&lt;/p&gt;&lt;p&gt;以及&lt;/p&gt;&lt;p&gt;Process ID: 3544&lt;/p&gt;&lt;p&gt;Exception: System.NullReferenceException&lt;br /&gt;&lt;/p&gt;&lt;p&gt;以及&lt;/p&gt;&lt;p&gt;Process ID: 7234&lt;/p&gt;&lt;p&gt;Exception: System.NullReferenceException&lt;br /&gt;&lt;/p&gt;&lt;p&gt;以及&lt;/p&gt;&lt;p&gt;Process ID: 2343&lt;/p&gt;&lt;p&gt;Exception: System.NullReferenceException&lt;br /&gt;&lt;/p&gt;&lt;p&gt;以及&lt;/p&gt;&lt;p&gt;Process ID: 9087&lt;/p&gt;&lt;p&gt;Exception: System.NullReferenceException&lt;br /&gt;3、上面的错误，我们可以看到，W3WP一共crash了5次，然后看System的日志，可以看到：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;事件类型:&amp;nbsp;错误&lt;br /&gt;事件来源:&amp;nbsp;W3SVC&lt;br /&gt;事件种类:&amp;nbsp;无&lt;br /&gt;事件 ID:&amp;nbsp;1002&lt;br /&gt;日期:&amp;nbsp;&amp;nbsp;2010-6-27&lt;br /&gt;事件:&amp;nbsp;&amp;nbsp;12:35:28&lt;br /&gt;用户:&amp;nbsp;&amp;nbsp;N/A&lt;br /&gt;计算机:&amp;nbsp;VPC2003&lt;br /&gt;描述:&lt;br /&gt;应用程序池 'LabAppPool' 被自动禁用，原因是为此应用程序池提供服务的进程中出现一系列错误。&lt;/p&gt;&lt;p&gt;有关更多信息，请参阅在 &lt;a href="http://go.microsoft.com/fwlink/events.asp" target="_blank"&gt;http://go.microsoft.com/fwlink/events.asp&lt;/a&gt; 的帮助和支持中心。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;4、打开IIS，察看应用程序池，你会发现LabAppPool已经被disable掉了。&lt;/p&gt;&lt;p&gt;5、右键查看该apppool的属性，在快速失败保护中会发现，如果5分钟之内有5次crash，则该apppool会被禁用掉。&amp;nbsp;&lt;/p&gt;&lt;p&gt;6、好了，这是一个典型的crash问题，并导致apppool被disable掉，对客户端显示HTTP503错误。现在开始debug&lt;/p&gt;&lt;p&gt;7、抓一个crash的dump，我们会发现产生了3个dump，分别是1st chance的AV、1st chance的process shutdown和2nd chance的netclr full，先打开第一个av的dump&lt;/p&gt;&lt;p&gt;a、由于是crash的dump，所以windbg会自动切换到导致AV的那个线程，我这里是18号。&lt;/p&gt;&lt;p&gt;b、加载sos，会有如下信息：&lt;/p&gt;&lt;p&gt;0:018&amp;gt; .loadby sos mscorwks&lt;br /&gt;------------------------------------------------------------&lt;br /&gt;sos.dll needs a full memory dump for complete functionality.&lt;br /&gt;You can create one with .dump /ma &amp;lt;filename&amp;gt;&lt;br /&gt;------------------------------------------------------------&lt;br /&gt;因为这是一个mini dump，所以很多信息我们看不到。解决办法之一是在adplus的时候，用参数-FullOnFirst，但是这个参数有副作用，我们后面会看到。&lt;/p&gt;&lt;p&gt;c、查看托管线程，如下：&lt;/p&gt;&lt;p&gt;0:018&amp;gt; !clrstack&lt;br /&gt;PDB symbol for mscorwks.dll not loaded&lt;br /&gt;OS Thread Id: 0x64c (18)&lt;br /&gt;ESP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EIP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0221f950 05500efb Review.Finalize()&lt;br /&gt;0221fc1c 79fbcca7 [ContextTransitionFrame: 0221fc1c] &lt;br /&gt;0221fcec 79fbcca7 [GCFrame: 0221fcec] &lt;br /&gt;可以看到，Review.Finalize方法导致了AV错误。&lt;br /&gt;d、运行!threads，输出如下：&lt;/p&gt;&lt;p&gt;0:018&amp;gt; !threads&lt;br /&gt;ThreadCount: 4&lt;br /&gt;UnstartedThread: 0&lt;br /&gt;BackgroundThread: 4&lt;br /&gt;PendingThread: 0&lt;br /&gt;DeadThread: 0&lt;br /&gt;Hosted Runtime: yes&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreEmptive&amp;nbsp;&amp;nbsp; GC Alloc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lock&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ID OSID ThreadOBJ&amp;nbsp;&amp;nbsp;&amp;nbsp; State&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Domain&amp;nbsp;&amp;nbsp; Count APT Exception&lt;br /&gt;16&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp; 2a4 000dbce8&amp;nbsp;&amp;nbsp; 3808220 Enabled&amp;nbsp; 00000000:00000000 001028a8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 Ukn (Threadpool Worker)&lt;br /&gt;18&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp; 64c 000e7de0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b220 Disabled 00000000:00000000 001028a8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn (Finalizer)&lt;br /&gt;19&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;nbsp; 538 000ec2c0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1220 Enabled&amp;nbsp; 00000000:00000000 000d8fd8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;br /&gt;&amp;nbsp; 　 20&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp; 594 000ff408&amp;nbsp;&amp;nbsp;&amp;nbsp; 80a220 Enabled&amp;nbsp; 00000000:00000000 000d8fd8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn (Threadpool Completion Port)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;可以看到发生AV的18号线程是GC的finalizer线程。那么具体的exception在哪里呢？&lt;/p&gt;&lt;p&gt;e、执行命令，!dso。输出如下：&lt;/p&gt;&lt;p&gt;0:018&amp;gt; !dso&lt;br /&gt;Error requesting details&lt;br /&gt;Unable to determine bounds of gc heap&lt;/p&gt;&lt;p&gt;ooh，我们在一个mini的dump里面，很多东西是看不到的。so，需要抓一个fulldump来看。&lt;/p&gt;&lt;p&gt;f、重新运行adplus，增加参数：-FullOnFirst，重新看dump。&lt;/p&gt;&lt;p&gt;g、看!dso的结果：&lt;/p&gt;&lt;p&gt;0:018&amp;gt; !dso&lt;br /&gt;OS Thread Id: 0x908 (18)&lt;br /&gt;ESP/REG&amp;nbsp; Object&amp;nbsp;&amp;nbsp; Name&lt;br /&gt;esi&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 029b9158 Review&lt;br /&gt;0221f990 029b9158 Review&lt;br /&gt;0221f9dc 029b9158 Review&lt;br /&gt;0221f9e8 029b9158 Review&lt;br /&gt;0221f9fc 029b9158 Review&lt;br /&gt;0221fa00 029b9158 Review&lt;br /&gt;0221fa10 029b9158 Review&lt;br /&gt;0221fae8 029b9158 Review&lt;br /&gt;0221fcb0 029b9158 Review&lt;/p&gt;&lt;p&gt;没有exception，只有一个Review对象，继续看，执行!do 029b9158 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MT&amp;nbsp;&amp;nbsp;&amp;nbsp; Field&amp;nbsp;&amp;nbsp; Offset&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type VT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Attr&amp;nbsp;&amp;nbsp;&amp;nbsp; Value Name&lt;br /&gt;790fd8c4&amp;nbsp; 4000008&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.String&amp;nbsp; 0 instance 00000000 quote&lt;br /&gt;790fd8c4&amp;nbsp; 4000009&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.String&amp;nbsp; 0 instance 00000000 source&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;注意上面的两个string，都是0，这意味着都是null，那么，是否可能是null.SomeMethod导致的呢？&lt;/p&gt;&lt;p&gt;h、看步骤c中的Review.Finalizer方法，代码如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ~Review()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (quote.ToString() != string.Empty)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; quote = null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p&gt;嗯，问题找到了，在于上面的quote.ToString造成的，因为某个原因，quote这个字符串变成了null，所以出现AV了。&lt;/p&gt;&lt;p&gt;i、实际上如果查看页面代码，我们能看到一个Clear方法把这个变量变成了null。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Over&lt;br /&gt;&lt;/p&gt;   &lt;img src="http://www.cnblogs.com/juqiang/aggbug/1766132.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/juqiang/archive/2010/06/27/1766132.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
