<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.1.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>垃圾回收站</title>
	<link>http://panweizeng.com/document</link>
	<description>咕噜咕噜</description>
	<pubDate>Mon, 16 Jun 2008 05:07:06 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.1.2</generator>
	<language>en</language>
			<item>
		<title>母版页判断登陆 及 母版页与内容页的执行顺序</title>
		<link>http://panweizeng.com/document/archives/218</link>
		<comments>http://panweizeng.com/document/archives/218#comments</comments>
		<pubDate>Mon, 16 Jun 2008 05:06:13 +0000</pubDate>
		<dc:creator>弗里曼·潘</dc:creator>
		
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://panweizeng.com/document/archives/218</guid>
		<description><![CDATA[http://www.cnblogs.com/cooolbin/archive/2008/04/18/1160394.html
在checkLogin.cs里有check方法：
public static void check(Page aPage)
{
if (aPage.Session[&#8221;ok&#8221;] == null &#124;&#124; aPage.Session[&#8221;ok&#8221;].ToString() != &#8220;ok&#... ]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cnblogs.com/cooolbin/archive/2008/04/18/1160394.html">http://www.cnblogs.com/cooolbin/archive/2008/04/18/1160394.html</a><br />
在checkLogin.cs里有check方法：</p>
<p>public static void check(Page aPage)<br />
{<br />
if (aPage.Session[&#8221;ok&#8221;] == null || aPage.Session[&#8221;ok&#8221;].ToString() != &#8220;ok&#8221;)<br />
{<br />
aPage.Response.Redirect(&#8221;login.aspx&#8221;);<br />
}<br />
}</p>
<p>在母版页里调用的正确方法：</p>
<p>protected void Page_Init(object sender, EventArgs e)<br />
{<br />
checkLogin.check(this.Page);<br />
}</p>
<p>原因：</p>
<p>母版页和内容页的执行顺序：</p>
<p>1.母版页中控件的Init;<br />
2.内容页控件的Init;<br />
3.母版页的Init;<br />
4.内容页的Init;<br />
5.内容页的Load;<br />
6.母版页的Load;<br />
7.内容页中控件的Load;<br />
8.内容页的PreRender;<br />
9.母版页的PreRender;<br />
10.母版页控件的PreRender;<br />
11.内容页中控件的PreRender</p>
<p>出错方法：</p>
<p>１、checkLogin.check(mypage);<br />
运行：MasterPage类转Page类出错</p>
<p>２、Page mypage=new Page();<br />
checkLogin.check(mypage);<br />
运行：System.Web.HttpException: 响应在此上下文中不可用。</p>
<p>３、用户自定义控件MasterPublicMethod.ascx，调用检查方法<br />
protected void Page_Load(object sender, EventArgs e)<br />
{<br />
checkLogin.check(this.Page);<br />
}<br />
控件加入母版页：<uc1:masterpublicmethod runat="server" id="MasterPublicMethod1"></uc1:masterpublicmethod><br />
这个方法改成：在母版页的Page_Load事件里：checkLogin.check(this.Page);<br />
运行：正常<br />
出错原因：事件执行顺序：内容页的Page_Load事件-&gt;母版页的Page_Load事件，要在页面最开始检查有没有登录</p>
<p>４、母版页：<br />
protected void Page_Load(object sender, EventArgs e)<br />
{<br />
//Response.Write(&#8221;母版&#8221;);<br />
checkLogin.check(this.Page);<br />
}<br />
内容页的Page_LoadComplete事件：<br />
protected void Page_LoadComplete(Object sender, EventArgs e)<br />
{<br />
int t, bid;<br />
//初始化自定义控件用的参数<br />
pg = Convert.ToInt32(Request.QueryString[&#8221;pg&#8221;]);<br />
bid = Convert.ToInt32(Request.QueryString[&#8221;id&#8221;]);<br />
t = Convert.ToInt32(Request.QueryString[&#8221;t&#8221;]);<br />
switch (t)<br />
{<br />
case 1:<br />
//回复<br />
break;<br />
case 2:<br />
//修改回复<br />
break;<br />
case 3:<br />
//隐藏<br />
HideBook(bid);<br />
break;<br />
case 4:<br />
//删除<br />
DelBook(bid);<br />
break;<br />
}<br />
}<br />
修改原因：页面执行顺序：内容页的Page_Load-&gt;母版页的Page_Load-&gt;内容页的Page_LoadComplete<br />
运行：自定义控件里有变量未赋值出错<br />
出错原因：有的内容页里有自定义控件，自定义控件的Page_Load事件里有代码，自定义控件的参数在内容页的Page_LoadComplete事件里初始化<br />
Page_Load的执行顺序：内容Page_Load-&gt;母版Page_Load-&gt;自定义控件Page_Load-&gt;内容Page_LoadComplete</p>
]]></content:encoded>
			<wfw:commentRss>http://panweizeng.com/document/archives/218/feed/</wfw:commentRss>
		</item>
		<item>
		<title>10年编程无师自通</title>
		<link>http://panweizeng.com/document/archives/217</link>
		<comments>http://panweizeng.com/document/archives/217#comments</comments>
		<pubDate>Sun, 27 Apr 2008 08:49:57 +0000</pubDate>
		<dc:creator>弗里曼·潘</dc:creator>
		
		<category><![CDATA[其他技术]]></category>

		<guid isPermaLink="false">http://panweizeng.com/document/archives/217</guid>
		<description><![CDATA[FooSleeper 翻译&#160;&#160; 更新：2005-01-12 10:18:06&#160; 版本: 1.09&#160;&#160;&#160; 
原文：Teach Yourself Programming in Ten Years   作者：Peter Norvig    翻译：郭晓刚（foosleeper@163.net）    最后修订日期：2004-3-19    2... ]]></description>
			<content:encoded><![CDATA[<p>FooSleeper 翻译&#160;&#160; 更新：2005-01-12 10:18:06&#160; 版本: 1.09&#160;&#160;&#160; </p>
<p>原文：Teach Yourself Programming in Ten Years   <br />作者：Peter Norvig    <br />翻译：郭晓刚（foosleeper@163.net）    <br />最后修订日期：2004-3-19    <br />2005-01-12增加了新的译本链接。 </p>
<p>本中文译本得到了Peter Norvig的许可。 </p>
<p>为什么每个人都急不可耐？ </p>
<p>走进任何一家书店，你会看见《Teach Yourself Java in 7 Days》（7天Java无师自通）的旁边是一长排看不到尽头的类似书籍，它们要教会你Visual Basic、Windows、Internet等等，而只需要几天甚至几小时。我在Amazon.com上进行了如下搜索：   <br /> pubdate: after 1992 and title: days and (title: learn or title: teach yourself)    <br /> (出版日期：1992年后 and 书名：天 and （书名：学会 or 书名：无师自通）)    <br />我一共得到了248个搜索结果。前面的78个是计算机书籍（第79个是《Learn Bengali in 30 days》，30天学会孟加拉语）。我把关键词&#8220;days&#8221;换成&#8220;hours&#8221;，得到了非常相似的结果：这次有253本书，头77本是计算机书籍，第78本是《Teach Yourself Grammar and Style in 24 Hours》（24小时学会文法和文体）。头200本书中，有96%是计算机书籍。    <br />结论是，要么是人们非常急于学会计算机，要么就是不知道为什么计算机惊人地简单，比任何东西都容易学会。没有一本书是要在几天里教会人们欣赏贝多芬或者量子物理学，甚至怎样给狗打扮。    <br />让我们来分析一下像《Learn Pascal in Three Days》（3天学会Pascal）这样的题目到底是什么意思： </p>
<p>学会：在3天时间里，你不够时间写一些有意义的程序，并从它们的失败与成功中学习。你不够时间跟一些有经验的程序员一起工作，你不会知道在那样的环境中是什么滋味。简而言之，没有足够的时间让你学到很多东西。所以这些书谈论的只是表面上的精通，而非深入的理解。如Alexander Pope（译注：英国诗人、作家，1688-1744）所言，一知半解是危险的（a little learning is a dangerous thing）   <br />。    <br />Pascal：在3天时间里你可以学会Pascal的语法（如果你已经会一门类似的语言），但你无法学到多少如何运用这些语法。简而言之，如果你是，比如说一个Basic程序员，你可以学会用Pascal语法写出Basic风格的程序，但你学不到Pascal真正的优点（和缺点）。那关键在哪里？Alan Perlis（译注：ACM第一任主席，图灵奖得主，1922-1990）曾经说过：&#8220;如果一门语言不能影响你对编程的想法，那它就不值得去学&#8221;。另一种观点是，有时候你不得不学一点Pascal（更可能是Visual Basic和JavaScript之类）的皮毛，因为你需要接触现有的工具，用来完成特定的任务。但此时你不是在学习如何编程，你是在学习如何完成任务。 </p>
<p>3天：不幸的是，这是不够的，正如下一节所言。 </p>
<p>10年编程无师自通 </p>
<p>一些研究者（Hayes、Bloom）的研究表明，在许多领域，都需要大约10 年时间才能培养出专业技能，包括国际象棋、作曲、绘画、钢琴、游泳、网球，以及神经心理学和拓扑学的研究。似乎并不存在真正的捷径：即使是莫扎特，他4 岁就显露出音乐天才，在他写出世界级的音乐之前仍然用了超过13年时间。再看另一种音乐类型的代表&#8211;披头士，他们似乎是在1964年的Ed Sullivan节目中突然冒头的。但其实他们从1957年就开始表演了，即使他们很早就显示出了巨大的吸引力，他们第一次真正的成功之作《Sgt. Peppers》也要到1967年才发行。Samuel Johnson（译注：英国诗人）认为10 年还是不够的：&#8220;任何领域的卓越成就都只能通过一生的努力来获得；稍低一点的代价也换不来。&#8221;（Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price.） 乔叟（译注：Chaucer，英国诗人，1340-1400）也抱怨说：&#8220;生命如此短暂，掌握技艺却要如此长久。&#8221;（the lyf so short, the craft so long to lerne.）   <br />下面是我在编程这个行当里获得成功的处方： </p>
<p>对编程感兴趣，因为乐趣而去编程。确定始终都能保持足够的乐趣，以致你能够将10年时间投入其中。 </p>
<p>跟其他程序员交谈；阅读其他程序。这比任何书籍或训练课程都更重要。 </p>
<p>编程。最好的学习是从实践中学习。用更加技术性的语言来讲，&#8220;个体在特定领域最高水平的表现不是作为长期的经验的结果而自动获得的，但即使是非常富有经验的个体也可以通过刻意的努力而提高其表现水平。&#8221;（p. 366），而且&#8220;最有效的学习要求为特定个体制定适当难度的任务，有意义的反馈，以及重复及改正错误的机会。&#8221;（p. 20-21）《Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life》（在实践中认知：心智、数学和日常生活的文化）是关于这个观点的一本有趣的参考书。 </p>
<p>如果你愿意，在大学里花上4年时间（或者再花几年读研究生）。这能让你获得一些工作的入门资格，还能让你对此领域有更深入的理解，但如果你不喜欢进学校，（作出一点牺牲）你在工作中也同样能获得类似的经验。在任何情况下，单从书本上学习都是不够的。&#8220;计算机科学的教育不会让任何人成为内行的程序员，正如研究画笔和颜料不会让任何人成为内行的画家&#8221;，Eric Raymond，《The New Hacker&#8217;s Dictionary》（新黑客字典）的作者如是说。我曾经雇用过的最优秀的程序员之一仅有高中学历；但他创造出了许多伟大的软件，甚至有讨论他本人的新闻组，而且股票期权让他达到我无法企及的富有程度（译注：指Jamie Zawinski，XEmacs和Netscape Navigator的作者）。 </p>
<p>跟别的程序员一起完成项目。在一些项目中成为最好的程序员；在其他一些项目中当最差的一个。当你是最好的程序员时，你要测试自己领导项目的能力，并通过你的洞见鼓舞其他人。当你是最差的时候，你学习高手们在做些什么，以及他们不喜欢做什么（因为他们让你帮他们做那些事）。 </p>
<p>接手别的程序员完成项目。用心理解别人编写的程序。看看在没有最初的程序员在场的时候理解和修改程序需要些什么。想一想怎样设计你的程序才能让别人接手维护你的程序时更容易一些。 </p>
<p>学会至少半打编程语言。包括一门支持类抽象（class abstraction）的语言（如Java或C++），一门支持函数抽象（functional abstraction）的语言（如Lisp或ML），一门支持句法抽象（syntactic abstraction）的语言（如Lisp），一门支持说明性规约（declarative specification）的语言（如Prolog或C++模版），一门支持协程（coroutine）的语言（如Icon或Scheme），以及一门支持并行处理（parallelism）的语言（如Sisal）。 </p>
<p>记住在&#8220;计算机科学&#8221;这个词组里包含&#8220;计算机&#8221;这个词。了解你的计算机执行一条指令要多长时间，从内存中取一个word要多长时间（包括缓存命中和未命中的情况），从磁盘上读取连续的数据要多长时间，定位到磁盘上的新位置又要多长时间。（答案在这里。） </p>
<p>尝试参与到一项语言标准化工作中。可以是ANSI C++委员会，也可以是决定自己团队的编码风格到底采用2个空格的缩进还是4个。不论是哪一种，你都可以学到在这门语言中到底人们喜欢些什么，他们有多喜欢，甚至有可能稍微了解为什么他们会有这样的感觉。 </p>
<p>拥有尽快从语言标准化工作中抽身的良好判断力。 </p>
<p>抱着这些想法，我很怀疑从书上到底能学到多少东西。在我第一个孩子出生前，我读完了所有&#8220;怎样&#8230;&#8230;&#8221;的书，却仍然感到自己是个茫无头绪的新手。30个月后，我第二个孩子出生的时候，我重新拿起那些书来复习了吗？不。相反，我依靠我自己的经验，结果比专家写的几千页东西更有用更靠得住。   <br />Fred Brooks在他的短文《No Silver Bullets》（没有银弹）中确立了如何发现杰出的软件设计者的三步规划： </p>
<p>尽早系统地识别出最好的设计者群体。 </p>
<p>指派一个事业上的导师负责有潜质的对象的发展，小心地帮他保持职业生涯的履历。 </p>
<p>让成长中的设计师们有机会互相影响，互相激励。 </p>
<p>这实际上是假定了有些人本身就具有成为杰出设计师的必要潜质；要做的只是引导他们前进。Alan Perlis说得更简洁：&#8220;每个人都可以被教授如何雕塑；而对米开朗基罗来说，能教给他的倒是怎样能够不去雕塑。杰出的程序员也一样&#8221;。   <br />所以尽管去买那些Java书；你很可能会从中找到些用处。但你的生活，或者你作为程序员的真正的专业技术，并不会因此在24小时、24天甚至24个月内发生真正的变化。 </p>
<p>参考文献 </p>
<p>Bloom, Benjamin (ed.) Developing Talent in Young People, Ballantine, 1985.    <br />Brooks, Fred, No Silver Bullets, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19.     <br />Hayes, John R., Complete Problem Solver, Lawrence Erlbaum, 1989.     <br />Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988. </p>
<p>答案 </p>
<p>各种操作的计时，2001年夏天在一台典型的1GHz PC上完成：   <br /> 执行单条指令 1 纳秒 = (1/1,000,000,000) 秒    <br /> 从L1缓存中取一个word 2 纳秒    <br /> 从主内存中取一个word 10 纳秒    <br /> 从连续的磁盘位置中取一个word 200 纳秒    <br /> 从新的磁盘位置中取一个word（寻址） 8,000,000纳秒 = 8毫秒 </p>
<p>脚注 </p>
<p>T. Capey指出Amazon上面《Complete Problem Solver》的页面中，《Teach Yourself Bengali in 21 days》和《Teach Yourself Grammar and Style》被列在了&#8220;购买此书的顾客还买了以下书籍&#8221;栏目里面。我猜其中一大部分察看这两本书的人都是从我这里过去的。 </p>
<p>译本 </p>
<p>感谢以下作者将本文翻译成其他语言：   <br />日文（Yasushi Murakawa），中文（郭晓刚），繁体中文（Jason Chen），西班牙文（Carlos Rueda），德文（Stefan Ram），法文（P. E. Allary），土耳其文（&#199;ağıl Uluşahin）。 </p>
<p>Peter Norvig (Copyright 2001)</p>
]]></content:encoded>
			<wfw:commentRss>http://panweizeng.com/document/archives/217/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Javascript风格要素</title>
		<link>http://panweizeng.com/document/archives/216</link>
		<comments>http://panweizeng.com/document/archives/216#comments</comments>
		<pubDate>Tue, 15 Apr 2008 07:16:06 +0000</pubDate>
		<dc:creator>弗里曼·潘</dc:creator>
		
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://panweizeng.com/document/archives/216</guid>
		<description><![CDATA[http://dancewithnet.com/2008/01/26/the-elements-of-javascript-style-part-one/
程序设计是困难的，其核心是管理的复杂性。计算机程序是人类做出的最复杂的东西。质量是不可靠的且隐蔽的。 
好的体系架构是必... ]]></description>
			<content:encoded><![CDATA[<p><a title="http://dancewithnet.com/2008/01/26/the-elements-of-javascript-style-part-one/" href="http://dancewithnet.com/2008/01/26/the-elements-of-javascript-style-part-one/">http://dancewithnet.com/2008/01/26/the-elements-of-javascript-style-part-one/</a></p>
<p>程序设计是困难的，其核心是管理的复杂性。计算机程序是人类做出的最复杂的东西。质量是不可靠的且隐蔽的。 </p>
<p>好的体系架构是必需给程序足够的结构使其健壮而不会陷入混乱的泥淖，但我们表达一个程序细节的方式是同等重要的。一个程序的本质会被不良的编码所隐藏。只有当一个程序的表达清晰时，我们才能有希望正确的推理出它的效率、安全和正确性。 </p>
<p>William Strunk的《风格要素》(The Elements of Style)是关于文学风格的经典著作，它是一本关于英文写作的薄手册，在用法、组织和形式上提出忠告。风格的理念应用于编程，在1972年Kreitzberg和Shneiderman的《FORTRAN风格要素》（The Elements of FORTRAN Style）中是不成功的，但在1978年的Kernighan和Plauger的《编程风格要素》（The Elements of Programming Style）中是非常成功的： </p>
<p>好的编程不能通过笼统的说教。学习编程的好方法是一次又一次的思考：真正的编程是如何通过一些良好实践的原则和一点常识来进行改进的。 </p>
<p>他们从他们批评和改进的其他的编程教科书中筛选程序。 </p>
<p>当我们在这里谈论风格时，我们谈论的不是潮流或者时尚，也不是CSS、布局惯例或排版。我们正在谈论的是能真正提高代码价值的表达式的永恒品质。对于公司来说，他们的评估和他们的代码是息息相关的，风格应该是一个至关重要的受关注内容。 </p>
<p>我们使用许多编程语言，但在某一方面，Javascript是最重要的，它是浏览器的语言。当人们访问我们的站点时，他们将邀请我们的Javascript程序在他们的机器中执行。我们有义务使那些程序执行好。 </p>
<p>没有好的关于Javascript编程的课本。在网页使用Javascript的大多数人学习它是通过从糟糕的书、糟糕的站点和糟糕的工具中复制相当糟糕的例子。我们这里有极好的Javascript程序员社区，但我们依旧能从较好的风格实践中获益。 </p>
<p>为了证明这个问题，我将从公共网站中抽取一些程序，展示它们如何能被改进。这并不是我有意为难任何人。我的意图仅是通过例子展示风格的价值。我不会保留任何秘密：我展示给你的是我们已经传送给世界上的每一个人。   <br />淘汰过时结构 </p>
<p>下面的例子是2005-09-19摘自www.yahoo.com：   <br />&lt;script language=javascript&gt;&lt;!&#8211;    <br />&#160;&#160;&#160;&#160; lck=&#8221;,    <br />&#160;&#160;&#160;&#160; sss=1127143538,    <br />&#160;&#160;&#160;&#160; ylp=&#8217;p.gif?t=1127143538&amp;_ylp=A0Je5ipy2C5D54AAwVX1cSkA&#8217;,    <br />&#160;&#160;&#160;&#160; _lcs=&#8221;;    <br />&#8211;&gt;&lt;/script&gt; </p>
<p>这个脚本块用了language属性。这个特性是微软为了支持VBScript引入的。然而Netscape采用它是为了支持非标准偏差。W3C不采取这个language属性，倾向使用MIME类型的type属性取代。不幸的是，MIME类型未得到标准化，所以它有时是&#8221;text/javascript&#8221;、&#8221;application/ecmascript&#8221;或其他。幸运的是所有的浏览器都选择Javascript作为默认的编程语言，所以简单的写&lt;script&gt;是最好的。它最小，且工作在最多的浏览器。在脚本中使用HTML的注释的时间要回溯到Netscape Navigator和Netscape Navigator 2的兼容问题上来。后者引入了&lt;script&gt;标签。然而，前者的用户能像文本一样看到脚本，因为在HTML惯例中不能识别的标签被忽略。&lt;!&#8211;注释hack在Netscape Navigator 3出现的时候是需要的，现在它不被需要了。它是丑陋的且浪费空间的。 </p>
<p>逗号运算符像Javascript语法的大多数一样从C语言中借用。逗号运算符获得两个值，且返回第二个。在语言的定义中它的存在易于掩盖一定的编码错误，编译器也易于对一些错误视而不见。最好避免逗号运算符，并以分号运算符代替。 </p>
<p>在这个案例里，我们定义了一些全局变量。当指定一个未知（匿名）的变量时，Javascript会创建一个新的全局变量来替代产生的错误。事后看来，这是一个错误。即使当他们是一个标准错误，这是避免错误的最好办法。我们应该明确的声明变量。它花费我们四个字符，但是它正是要做的正确的事。   <br />&lt;script&gt;    <br />var lck = &#8216;3ek6b0i2he2a5eh3/o&#8217;,    <br />&#160;&#160;&#160; sss = 1126894256,    <br />&#160;&#160;&#160; ylp = &#8216;p.gif?t=1126894256&amp;_ylp=A0Je5iOwCitDw2YBX331cSkA&#8217;,    <br />&#160;&#160;&#160; _lcs = &#8216;94040&#8242;;    <br />&lt;/script&gt; </p>
<p>从上面我们能得出这样的原则：淘汰过时结构   <br />结构化语句要始终使用区块 </p>
<p>下面这个例子是一个cookie类构造器。它创建了一个有get和set方法的对象。   <br />function yg_cookie() {    <br />&#160;&#160;&#160; this.get = function (n) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var s,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; v = &#8221;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; c = &#8216; &#8216; + document.cookie + &#8216;;&#8217;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ((s = c.indexOf((&#8217; &#8216; + n + &#8216;=&#8217;))) &gt;= 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ((e = c.indexOf(&#8217;;',s)) == -1)    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e = c.length;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; s += n.length + 2;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; v = unescape(c.substring(s, e));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return (v);    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; this.set = function (n,v,e) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; document.cookie = n + &quot;=&quot; + escape(v) +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;expires=&quot; + (new Date(e * 1000)).toGMTString() +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;path=/&quot; + &quot;;domain=www.yahoo.com&quot;;    <br />&#160;&#160;&#160; }    <br />}    <br />var _yc = new yg_cookie(); </p>
<p>Javascript的if语句和C语言的相似：它能执行一个语句或一个区块。关于用语句的问题是一个普通的错误非常难以探测。最好把   <br />if ((e = c.indexOf(&#8217;;', s)) == -1)    <br />&#160;&#160;&#160; e = c.length; </p>
<p>写成   <br />if ((e = c.indexOf(&#8217;;', s)) == -1) {    <br />&#160;&#160;&#160; e = c.length;    <br />} </p>
<p>区块的用处是避免了下面的情况：   <br />if ((e = c.indexOf(&#8217;;', s)) == -1)    <br />&#160;&#160;&#160; e = c.length;    <br />&#160;&#160;&#160; s += n.length + 2; </p>
<p>它将出现当indexOf返回-1是，s是只被增加，但这不是实际情形。像这样的bug被发现代价是非常高的，但是可以通过一直使用大括号声明结构来廉价的避免。   <br />避免赋值表达式 </p>
<p>Javascript从C继承的另一个坏习惯是赋值表达式。它出现在流线型代码中，但它能使控制流更难以理解。如果我们从他们的使用中分离了s和e的计算，get方法会变得更清晰。   <br />this.get = function (n) {    <br />&#160;&#160;&#160; var v = &#8221;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; c = &#8216; &#8216; + document.cookie + &#8216;;&#8217;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; s = c.indexOf((&#8217; &#8216; + n + &#8216;=&#8217;)),    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; e = c.indexOf(&#8217;;', s);    <br />&#160;&#160;&#160; if (s &gt;= 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (e == -1) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e = c.length;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; s += n.length + 2;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; v = unescape(c.substring(s, e));    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; return (v);    <br />} </p>
<p>我们现在能看到当s被计算时，在indexOf参数两边有多余的括号。（在return语句中也有非必须的括号。）但是更重要的是，能容易的看出if (e == -1)的目的是什么：如果cookie中末尾的分号不存在，假定cookie结束在字符串的末端。然而，当我们计算c时，我们在cookie中加入了一个分号，它保证了预料的if条件将绝不会发生。所以我们能移除if。   <br />使用对象参数 </p>
<p>当一个函数被指定一个值，像在this.get = function (n) { &#8230; }中，它应该以一个分号来结束所有的赋值语句。   <br />function yg_cookie() {    <br />&#160;&#160;&#160; this.get = function (n) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var v = &#8221;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; c = &#8216; &#8216; + document.cookie + &#8216;;&#8217;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; s = c.indexOf((&#8217; &#8216; + n + &#8216;=&#8217;));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (s &gt;= 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; s += n.length + 2;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; v = unescape(c.substring(s, c.indexOf(&#8217;;', s)));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return v;    <br />&#160;&#160;&#160; };    <br />&#160;&#160;&#160; this.set = function (n,v,e) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; document.cookie = n + &quot;=&quot; + escape(v) +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;expires=&quot; + (new Date(e * 1000)).toGMTString() +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;path=/&quot; + &quot;;domain=www.yahoo.com&quot;;    <br />&#160;&#160;&#160; };    <br />}    <br />var _yc = new yg_cookie(); </p>
<p>最后，我们看到yg_cookie是一个能产生一个无状态对象的构造器。我们一点也不需要构造器函数。我们能简单创建一个空对象，通过指派方法的方式来增加它。   <br />var _yc = new Object();    <br />_yc.get = function (n) {    <br />&#160;&#160;&#160; var v = &#8221;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; c = &#8216; &#8216; + document.cookie + &#8216;;&#8217;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; s = c.indexOf((&#8217; &#8216; + n + &#8216;=&#8217;));    <br />&#160;&#160;&#160; if (s &gt;= 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; s += n.length + 2;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; v = unescape(c.substring(s, c.indexOf(&#8217;;', s)));    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; return v;    <br />};    <br />_yc.set = function (n,v,e) {    <br />&#160;&#160;&#160; document.cookie = n + &quot;=&quot; + escape(v) +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;expires=&quot; + (new Date(e * 1000)).toGMTString() +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;path=/&quot; + &quot;;domain=www.yahoo.com&quot;;    <br />}; </p>
<p>如果我们不需要支持Netscape3和IE4，我们能通过对象字面量来实现的更加优雅。   <br />var _yc = {    <br />&#160;&#160;&#160; get: function (n) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var v = &#8221;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; c = &#8216; &#8216; + document.cookie + &#8216;;&#8217;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; s = c.indexOf((&#8217; &#8216; + n + &#8216;=&#8217;));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (s &gt;= 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; s += n.length + 2;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; v = unescape(c.substring(s, c.indexOf(&#8217;;', s)));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return v;    <br />&#160;&#160;&#160; },    <br />&#160;&#160;&#160; set: function (n,v,e) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; document.cookie = n + &quot;=&quot; + escape(v) +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;expires=&quot; + (new Date(e * 1000)).toGMTString() +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;;path=/&quot; + &quot;;domain=www.yahoo.com&quot;;    <br />&#160;&#160;&#160; }    <br />};    <br />使用通用库 </p>
<p>此时对于处理cookies我们有几种方法。我们发现下一个事情是令人惊奇的，它是没有利用我们定义的方法的cookies处理方式代码。   <br />var b,    <br />&#160;&#160;&#160; l = &#8221;,    <br />&#160;&#160;&#160; n = &#8216;0&#8242;,    <br />&#160;&#160;&#160; y;    <br />y = &#8216; &#8216; + document.cookie + &#8216;;&#8217;;    <br />if ((b = y.indexOf(&#8217; Y=v&#8217;)) &gt;= 0) {    <br />&#160;&#160;&#160; y = y.substring(b, y.indexOf(&#8217;;', b)) + &#8216;&amp;&#8217;;    <br />&#160;&#160;&#160; if ((b = y.indexOf(&#8217;l=&#8217;)) &gt;= 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; l = y.substring(b + 2, y.indexOf(&#8217;&amp;&#8217;, b));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ((b = y.indexOf(&#8217;n=&#8217;)) &gt;= 0)    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; n = y.substring(b + 2, y.indexOf(&#8217;&amp;&#8217;, b));    <br />&#160;&#160;&#160; }    <br />} </p>
<p>它甚至复制了我们早前看到的同样技术。很有可能两块代码都改写自同一个有缺点的原稿。我们可以利用我们最近的工作来改进它：   <br />var l = &#8221;,    <br />&#160;&#160;&#160; n = &#8216;0&#8242;,    <br />&#160;&#160;&#160; y = _yc.get(&#8217;Y') + &#8216;&amp;&#8217;,    <br />&#160;&#160;&#160; b = y.indexOf(&#8217;l=&#8217;);    <br />if (b &gt;= 0) {    <br />&#160;&#160;&#160; l = y.substring(b + 2, y.indexOf(&#8217;&amp;&#8217;, b));    <br />&#160;&#160;&#160; b = y.indexOf(&#8217;n=&#8217;);    <br />&#160;&#160;&#160; if (b &gt;= 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; n = y.substring(b + 2, y.indexOf(&#8217;&amp;&#8217;, b));    <br />&#160;&#160;&#160; }    <br />} </p>
<p>代码重用是软件工程的圣杯。我们可以想象通过最先进的技术避免大量的必需的手工工作来得到高效率。这里我们发现一种失败，使用一种方法需要在相邻需要它的地方进行定义。 </p>
<p>软件的体系结构倾向于反映生产他们的组织结构。在这种情况下，我们看到一个组织由于缺乏流程的连通意识而导致的明显低效的证据。风格的应用是吹毛求疵的，因为如果我们理解这几条是什么才有可能正确的一起使用这几条。 </p>
<p>原文：Douglas Crockford的The Elements of JavaScript Style Part One</p>
<p>&#160;</p>
<p>我们使用习惯用法可以使我们的意图更加的清晰和简洁。   <br />使用==时，当心强制转换 </p>
<p>考虑下面函数：   <br />function gw(f) {    <br />&#160;&#160;&#160; if (d.w.sv.checked == true) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; zv = &#8216;on&#8217;;    <br />&#160;&#160;&#160; } else {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; zv = &#8216;off&#8217;;    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; procframe.location.replace(&quot;<a href="http://b.www.yahoo.com/module/wtr_tr.php?p="">http://b.www.yahoo.com/module/wtr_tr.php?p=&quot;</a> +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; escape(f.p.value) + &quot;&amp;sv=&quot; + zv);    <br />&#160;&#160;&#160; return false;    <br />} </p>
<p>==运算符不应该被用着和true比较值，因为它要执行强制转换。如果我们想确定d.w.sv.checked是否是布尔值   <br />true，我们必须用===运算符。如果我们仅在意一个值是真实存在的不是假的，最好不要用相等运算符。 </p>
<p>例如，由于强制转换：1 == true是真，1 === true是假。==运算符隐藏了类型错误。   <br />使用?:运算符选择两值之一 </p>
<p>if语句通常被用来从两个值中选择一个。这应该是三元操作符?:最适合的。   <br />zv = d.w.sv.checked ? &#8216;on&#8217; : &#8216;off&#8217;;    <br />绝不使用隐含的全局变量 </p>
<p>变量zv不是作为一个var或函数参数来声明的，所以它是一个隐式的全局变量。如果这个页面的另一个函数使用了同样名字的全局变量，则可能得到一个失败的结果。这样的臭虫（bug）是非常难以发现，却很容易避免。这个例子中，我们既可以声明zv为一个var，也可以发现它仅仅被使用过一次而整个去掉它。   <br />function gw(f) {    <br />&#160;&#160;&#160; procframe.location.replace(&quot;<a href="http://b.www.yahoo.com/module/wtr_tr.php?p="">http://b.www.yahoo.com/module/wtr_tr.php?p=&quot;</a> +    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; escape(f.p.value) + &quot;&amp;sv=&quot; + d.w.sv.checked ? &#8216;on&#8217; : &#8216;off&#8217;);    <br />&#160;&#160;&#160; return false;    <br />}    <br />绝不使用?:运算符选择两种行为之一 </p>
<p>我们常质疑那些返回一个常量的函数，但这有时是在浏览器环境下所必需的。 </p>
<p>下面我们看一个不正确使用?:运算符的例子。它常被用于在两个任务间选择。   <br />function u(o, z) {    <br />&#160;&#160;&#160; var em = o.id.substring(1);    <br />&#160;&#160;&#160; var p = d.getElementById(&#8217;e&#8217; + em);    <br />&#160;&#160;&#160; if (p) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; (z == 0) ? p.style.backgroundColor = &#8216;#fff&#8217; :    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; p.style.backgroundColor = &#8216;#989898&#8242;;    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; p = d.getElementById(&#8217;e&#8217; + (em - 1));    <br />&#160;&#160;&#160; if (p) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; (z == 0) ? p.style.backgroundColor = &#8216;#fff&#8217; :    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; p.style.backgroundColor = &#8216;#989898&#8242;;    <br />&#160;&#160;&#160; }    <br />} </p>
<p>对Z的判断是模糊不清的。Z正好等于0时我们选择#fff颜色，那么，Z不等于时？如上所述似乎指明的是前者，但它实际上是后者。在这个例子中幸运的是，我们大概想要的就是后者，所以它不是技术上错误（这次）。但是在文体上只糟糕的。 </p>
<p>我们可以用if代替?:，但碰巧的是这些值对应的是同一个左值(lvalue)，所以我们无需if就可以改正这个错误。   <br />function u(o, z) {    <br />&#160;&#160;&#160; var em = o.id.substring(1),    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; p = d.getElementById(&#8217;e&#8217; + em);    <br />&#160;&#160;&#160; if (p) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; p.style.backgroundColor = z ? &#8216;#fff&#8217; : &#8216;#989898&#8242;;    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; p = d.getElementById(&#8217;e&#8217; + (em - 1));    <br />&#160;&#160;&#160; if (p) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; p.style.backgroundColor = z ? &#8216;#fff&#8217; : &#8216;#989898&#8242;;    <br />&#160;&#160;&#160; }    <br />}    <br />使用||运算符指定一个默认值 </p>
<p>事件处理程序依赖于浏览器。理想情况下，应用程序应该通过公共库隔绝对浏览器的依赖。当没有这样的库时，就会有些函数发生如下情况：   <br />function md(e) {    <br />&#160;&#160;&#160; (window.event) ? ev = window.event : ev = e;    <br />&#160;&#160;&#160; (ev.target) ? sr = ev.target : sr = ev.srcElement;    <br />&#160;&#160;&#160; if (ev &amp;&amp; sr &amp;&amp; sr.id == &quot;fp&quot; || sr.id == &quot;sb&quot;) st = 1;    <br />&#160;&#160;&#160; if (sr.className.indexOf(&quot;pllist&quot;) &lt; 0 &amp;&amp; sr.className != &quot;more&quot; &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sr.className != &quot;plinkc&quot; &amp;&amp; sr.tagName != &quot;scrollbar &quot; &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toClose &amp;&amp; _toCloseNorgie) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(_toClose).innerHTML = &quot;&quot;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toClose = &quot;&quot;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toCloseNorgie.parentNode.className = &#8221;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toCloseNorgie = &#8221;;    <br />&#160;&#160;&#160; }    <br />} </p>
<p>一些浏览器把事件对象作为一个参数传给事件管理程序。微软选用把事件对象放入到一个全局的事件变量中。在Javascript中，全局变量是全局对象的成员。在浏览器中，全局对象始终包含一个window对象成员，其值是全局对象。当测试一个变量是否存在时，通过window访问全局变量是避免未定义变量错误的一种方法。无论如何，做这样的测试不应该是必要的。 </p>
<p>我们能通过问它是否是另外一种，来代替首先判断是否是微软事件。   <br />ev = e || event; </p>
<p>我们用||(默认)运算符。如果e是真，我们将有它的值，但是如果e是假，则我们将用event。 </p>
<p>在下一个语句，我们又用||运算符去确定sr是哪个值。 </p>
<p>我们应该用var去声明ev和sr来避免全局冲突：   <br />function md(e) {    <br />&#160;&#160;&#160; var ev = e || event,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; sr = ev.target || ev.srcElement;    <br />&#160;&#160;&#160; if (sr &amp;&amp; (sr.id == &#8216;fp&#8217; || sr.id == &#8217;sb&#8217;)) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; st = 1;    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; if (sr.className.indexOf(&#8217;pllist&#8217;) &lt; 0 &amp;&amp; sr.className != &#8216;more&#8217; &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sr.className != &#8216;plinkc&#8217; &amp;&amp; sr.tagName != &#8217;scrollbar &#8216; &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toClose &amp;&amp; _toCloseNorgie) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(_toClose).innerHTML = &#8221;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toClose = &#8221;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toCloseNorgie.parentNode.className = &#8221;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _toCloseNorgie = &#8221;;    <br />&#160;&#160;&#160; }    <br />}    <br />全局变量是魔鬼 </p>
<p>下面我们看到另一个时间处理程序。正如你所料，它重复像前面一样破坏风格。   <br />function kd(e) {    <br />&#160;&#160;&#160; (window.event) ? ev = window.event : ev = e;    <br />&#160;&#160;&#160; (ev.target) ? el = ev.target : el = ev.srcElement;    <br />&#160;&#160;&#160; if (ev &amp;&amp; el) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; code = ev.keyCode;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; id = el.id;    <br />&#160;&#160;&#160; } else {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; ctn = lt.id.substring(1);    <br />&#160;&#160;&#160; if (code == 13) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;    <br />&#160;&#160;&#160; } else if ((code == 191 || code == 222) &amp;&amp; id != &#8216;fp&#8217;) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _ffs = 1;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gk = 0;    <br />&#160;&#160;&#160; } else if ((code &lt; 31 || code &gt; 41) &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (code &lt; 16 || code &gt; 18) &amp;&amp; code != 9 &amp;&amp; code != 8 ) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gk = 1;    <br />&#160;&#160;&#160; } else {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gk = 0;    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; if (!_ffs &amp;&amp; (id == &#8216;fp&#8217; || id == &#8217;st&#8217;)) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (code == 9) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (box.value == &#8221; || (box.value != &#8221; &amp;&amp; (at == 1 || ev.shiftKey))) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mt(ctn);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (id == &#8217;st&#8217; &amp;&amp; box.value != &#8221; &amp;&amp; at == 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; at = 1;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mt(ctn);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (id == &#8216;fp&#8217; &amp;&amp; gk == 0 &amp;&amp;&#160; (box.value == &#8221; &amp;&amp; st == 0)    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &amp;&amp; !ev.shiftKey &amp;&amp; !ev.ctrlKey &amp;&amp; !ev.altKey) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).focus();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).blur();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (gk == 1) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; at = 0;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160; } else if ((id == &#8216;mk2&#8242; &amp;&amp; box.value != &#8221; &amp;&amp; ev.shiftKey &amp;&amp; code == 9) ||    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (id == &#8216;m6&#8242; &amp;&amp; !ev.shiftKey &amp;&amp; code == 9)){    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).focus();    <br />&#160;&#160;&#160; } else if (!_ffs &amp;&amp; gk == 1 &amp;&amp; el.type != &#8216;text&#8217; &amp;&amp; !ev.ctrlKey &amp;&amp; !ev.altKey){    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; box.value = &#8221;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; box.focus();    <br />&#160;&#160;&#160; }    <br />}    <br />function mt(ctn) {    <br />&#160;&#160;&#160; if ((ev &amp;&amp; !ev.ctrlKey &amp;&amp; !ev.altKey) || !ev) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (ev.shiftKey){    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; nextTab = parseInt(ctn) - 1;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; nextTab = parseInt(ctn) + 1;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (nextTab == 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).focus();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (nextTab &lt; 8 ) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; t(d.getElementById(&#8217;v&#8217; + nextTab));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160; }    <br />} </p>
<p>有意思的是它有一个同伴函数mt，它仅被kd调用。mt被传给一个参数ctn，但kd和mt之间的通讯大部分是通过全局变量。   <br />使用内部函数避免全局变量 </p>
<p>我们可以通过增加传递给mt的参数数量来除掉所有的全局变量。但代替方案，我们将使mt变成kd的内部函数。作为一个内部函数，mt能访问kd的所有变量。   <br />unction kd(e) {    <br />&#160;&#160;&#160; var ev = e || event,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; el = ev.target || ev.srcElement,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; cnt,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; code = ev.keyCode,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gk,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; id = el.id,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; ctn = lt.id.substring(1); </p>
<p>&#160;&#160;&#160; function mt() {   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var nextTab;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!ev.ctrlKey &amp;&amp; !ev.altKey) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; nextTab = parseInt(ctn) + ev.shiftKey ? -1 : 1;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!nextTab) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).focus();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (nextTab &lt; 8 ) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; t(d.getElementById(&#8217;v&#8217; + nextTab));    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; if (code == 13) {   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;    <br />&#160;&#160;&#160; } else if ((code == 191 || code == 222) &amp;&amp; id != &#8216;fp&#8217;) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; _ffs = 1;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gk = 0;    <br />&#160;&#160;&#160; } else if ((code &lt; 31 || code &gt; 41) &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (code &lt; 16 || code &gt; 18) &amp;&amp; code != 9 &amp;&amp; code != 8 ) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gk = 1;    <br />&#160;&#160;&#160; } else {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; gk = 0;    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; if (!_ffs &amp;&amp; (id == &#8216;fp&#8217; || id == &#8217;st&#8217;)) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (code == 9) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (box.value == &#8221; ||    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (box.value != &#8221; &amp;&amp; (at == 1 || ev.shiftKey))) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mt();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (id == &#8217;st&#8217; &amp;&amp; box.value != &#8221; &amp;&amp; at == 0) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; at = 1;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; mt();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (id == &#8216;fp&#8217; &amp;&amp; gk == 0 &amp;&amp; (box.value == &#8221; &amp;&amp; st == 0) &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; !ev.shiftKey &amp;&amp; !ev.ctrlKey &amp;&amp; !ev.altKey) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).focus();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).blur();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } else if (gk == 1) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; at = 0;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160; } else if ((id == &#8216;mk2&#8242; &amp;&amp; box.value != &#8221; &amp;&amp; ev.shiftKey &amp;&amp; code == 9) ||    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (id == &#8216;m6&#8242; &amp;&amp; !ev.shiftKey &amp;&amp; code == 9)){    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; d.getElementById(&#8217;mk&#8217;).focus();    <br />&#160;&#160;&#160; } else if (!_ffs &amp;&amp; gk == 1 &amp;&amp; el.type != &#8216;text&#8217; &amp;&amp; !ev.ctrlKey &amp;&amp;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; !ev.altKey) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; box.value = &#8221;;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; box.focus();    <br />&#160;&#160;&#160; }    <br />} </p>
<p>在函数kd中，从两个地方调用函数mt。通过使它成为一个内部函数，我们能有效的减少kd所用到的全局变量的数目，这将降低了干扰其他组件的可能性。kd依旧是一个烂摊子，但它现在不是一无是处的烂摊子。 </p>
<p>原文：Douglas Crockford的The Elements of JavaScript Style Part Two: Idioms</p>
]]></content:encoded>
			<wfw:commentRss>http://panweizeng.com/document/archives/216/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Survey of the JavaScript Programming Language</title>
		<link>http://panweizeng.com/document/archives/215</link>
		<comments>http://panweizeng.com/document/archives/215#comments</comments>
		<pubDate>Mon, 14 Apr 2008 15:59:00 +0000</pubDate>
		<dc:creator>弗里曼·潘</dc:creator>
		
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://panweizeng.com/document/archives/215</guid>
		<description><![CDATA[A Survey of the JavaScript Programming Language 
简介 
这篇文章是为专业程序员介绍的JavaScript语言的，它是一种小巧的语言，如果你熟悉其他的编程语言，那么这篇文章对你来讲不是那么难以理解。 
JavaS... ]]></description>
			<content:encoded><![CDATA[<p><a href="http://javascript.crockford.com/survey.html" target="_blank">A Survey of the JavaScript Programming Language</a> </p>
<p>简介 </p>
<p>这篇文章是为专业程序员介绍的JavaScript语言的，它是一种小巧的语言，如果你熟悉其他的编程语言，那么这篇文章对你来讲不是那么难以理解。 </p>
<p>JavaScript不是Java，他们是两门完全不同的语言，JavaScript不是Java的子集，JavaScript不能被认为是Java(Java就是Java)。JavaScript分享了像Java一样分享C语言的语法，但从更深角度讲JavaScript更与Scheme 和Self有相似之处。它是一门小巧的语言，但是它确实强大的和丰富的语言。你应该好好观察一下它，你会发现它不是一个玩具语言，而是一个拥有许多与众不同特性的、完整的语言。 </p>
<p>JavaScript是一门不用花太多时间学习的正规语言。它能更好地适合一些任务，比如与Java相比它更适合客户端编程。以我的实践经验，我发现用JavaScript工作使我成为一个更好的Java程序员，因为它给我带来一套丰富的技巧。 </p>
<p>当我最初接触JavaScript时，我没有理他以为它不值得我的注意。后来，我对它刮目相看，因为我发现隐藏在浏览器中的它是一个如此有效的程序语言。我最初是在JavaScript在Sun和Netscape公司的初始陈述注意到它的。他们对JavaScript做了许多错误陈述，以免使它和Java处于竞争的位置。这些错误陈述继续充斥这那些只为傀儡和业余爱好者提供的、不好的JavaScript书中。 </p>
<p>历史 </p>
<p>JavaScript是被Netscape的Brendan Eich，作为一个页面脚本语言，在Navigator 2中开发的。它是一个非常具有表现力的动态程序语言，因为和浏览器的关系，它立刻变的大红大紫了。它从来没有得到一个可以校正它的问题的和基于真正使用目的测试周期，这一切导致它很强大却也有缺陷。 </p>
<p>这篇文章描述了ECMAScript 版本3 (也叫 JavaScript 1.5)。 Microsoft和Netscape一起开发了一个没有改正缺陷的呆滞版本。新版本的语言也许不能叫JavaScript，也不在这篇文章的讨论范围内。 </p>
<p>数据类型 </p>
<p>JavaScript包含一小套数据类型，它有3种简单的类型：boolean, number, 和 string;特殊的值：null,undefined;其他的所有基于object类型的变化。 </p>
<p>布尔类型有2个值：true和false。 </p>
<p>数字是64位的浮点值，与Java的Double类似。它没有整型。除法运算可能带来小数位的结果。数字包括特殊值NaN(不是一个数字)和Infinity。 </p>
<p>字符串(string)是从零到多个Unicode字符组成的。没有单独的字节类型。一个字节被描绘成一个长度为1的字符串。字符串被&#8217;符号或&quot;符号引用到一起，单引号和双引号可以替换使用，但必须前后匹配使用。 </p>
<p>&#8216;This is a string.&#8217; </p>
<p>&quot;Isn&#8217;t this a string? Yes!&quot; </p>
<p>&#8216;A&#8217; // The character A </p>
<p>&quot;&quot; // An empty string </p>
<p>转义用\字符，就像Java一样。字符串是不可变的。字符串有一个length属性类查看字符串的用字符的个数。 </p>
<p>var s = &quot;Hello World!&quot;; </p>
<p>s.length == 12 </p>
<p>可以给这些简单类型增加函数，你可以为所有数字类型增加一个int()的函数，当你调用Math.PI.int()的时候就会得到3这个结果。 </p>
<p>一个实现可能提供其它类型，比如日期(Dates)类型,正则表达式类型，但是他们真正的类型是Object类型，所有其它类型都是Object类型。 </p>
<p>对象 </p>
<p>JavaScript拥有非常漂亮的符号便利以对付那些键值集合(哈希表)(hashtables)。 </p>
<p>var myHashtable = {}; </p>
<p>这条语句了声明了一个键值集合，并把它分配到一个局部变量里。JavaScript是弱类型的，所以我们不能用类型的名称来进行声明。我们用索引的方式从键值结合中增加、替换和获取对象。 </p>
<p>myHashtable[&quot;name&quot;] = &quot;Carl Hollywood&quot;; </p>
<p>也可以使用&#8220;.&#8221;的方式带来一点便利。 </p>
<p>myHashtable.city = &quot;Anytown&quot;; </p>
<p>当索引是一个合法的系统保留字时，点符号就变得没用了。这是因为一个语言上的定义错误，保留字不能被用于点符号的形势下，但是可以用于索引的形式下。 </p>
<p>你会发现JavaScript的哈希表符号与Java的对象和数组符号非常地相似。JavaScript把这更发扬广大了：对象和哈希表是一个回事，所以我可以这样写 </p>
<p>var myHashtable = new Object(); </p>
<p>这个结果确实是一样的。 </p>
<p>用for语句可以实现对象一个枚举的能力。 </p>
<p>for (var n in myHashtable) { </p>
<p>&#160;&#160;&#160; if (myHashtable.hasOwnProperty(n)) { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; document.writeln(&quot;&lt;p&gt;&quot; + n + &quot;: &quot; + myHashtable[n] + &quot;&lt;/p&gt;&quot;); </p>
<p>&#160;&#160;&#160; } </p>
<p>} </p>
<p>这个结果应该是 </p>
<p>&lt;p&gt;name: Carl Hollywood&lt;/p&gt; </p>
<p>&lt;p&gt;city: Anytown&lt;/p&gt; </p>
<p>一个对象就是一个涉及到键/值对的集合，键是字符串（或者其他的元素比如那些被转化为字符串的数字），值可以是任何数据类型，包括其他对象。对象经常以哈希表的方式实现，但是没有任何哈希表（比如哈希函数或重写的函数）天性的可见。 </p>
<p>对象很容易被嵌套到别的对象当中，并且对象的表达式可以内容对象里使用。 </p>
<p>this.div = document.body.children[document.body.children.length - 1]; </p>
<p>对象的文字表达中，一个对象描述了包含在大括弧中的一组用逗点隔开的键/值对。键可以是在其后用冒号的标识符或字符串。由于语言定义的错误，系统预留字不能以标识符方式出现，但可以用字符串方式出现。值可以是任何类型的文字或表达式。 </p>
<p>var myObject = {name: &quot;Jack B. Nimble&quot;, &#8216;goto&#8217;: &#8216;Jail&#8217;, grade: &#8216;A&#8217;, level: 3}; </p>
<p>return { </p>
<p>&#160;&#160;&#160; event: event, </p>
<p>&#160;&#160;&#160; op: event.type, </p>
<p>&#160;&#160;&#160; to: event.srcElement, </p>
<p>&#160;&#160;&#160; x: event.clientX + document.body.scrollLeft, </p>
<p>&#160;&#160;&#160; y: event.clientY + document.body.scrollTop}; </p>
<p>emptyObject = {}; </p>
<p>JavaScript的对象模式是JSON的数据交换格式的基础。 </p>
<p>新的成员可以在任何时候被附着增加到任何对象上。 </p>
<p>myObject.nickname = &#8216;Jackie the Bee&#8217;; </p>
<p>数组和函数以对象方式实现。 </p>
<p>数组 </p>
<p>JavaScript中数组也是哈希表对象，这使它非常好地与稀少的数组程序相称。当你声明了一个数组，你不需要声明它的大小，数组会自增长，这很像Java的向量（vectors）。数组的值根据键来定位，而不是根据偏移量，这使JavaScript数组非常方便地使用，但不适合那些数字分析应用。 </p>
<p>对象和数组最主要的不同点是length属性。length属性总是比最大的整数键大1。有2种方式创建一个新数组。 </p>
<p>var myArray = []; </p>
<p>var myArray = new Array(); </p>
<p>数组不是强类型，它可以包括数字、字符串、布尔值、对象、函数和数组，你可以在一个数组中混合使用字符串、数字和对象。你以嵌套序列的方式使用数组，这和s-expressions的方式非常地类似。数组的第一个索引通常用0。 </p>
<p>当数组增加一个新元素的时候，它的索引是比数组长度。然后数组的长度变成在索引基础上加1。这个便利的特性使数组很容易在for循环中增加元素的数量。 </p>
<p>数组有个与对象类似的符号标记。 </p>
<p>myList = [&#8217;oats&#8217;, &#8216;peas&#8217;, &#8216;beans&#8217;, &#8216;barley&#8217;]; </p>
<p>emptyArray = []; </p>
<p>month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; </p>
<p>slides = [ </p>
<p>&#160;&#160;&#160; {url: &#8217;slide0001.html&#8217;, title: &#8216;Looking&amp;nbsp;Ahead&#8217;}, </p>
<p>&#160;&#160;&#160; {url: &#8217;slide0008.html&#8217;, title: &#8216;Forecast&#8217;}, </p>
<p>&#160;&#160;&#160; {url: &#8217;slide0021.html&#8217;, title: &#8216;Summary&#8217;} </p>
<p>]; </p>
<p>新元素以分配的方式增加到数组中。 </p>
<p>a[i + j] = f(a, a[j]); </p>
<p>函数 </p>
<p>JavaScript的函数看起来想C语言的函数一样，但JavaScript用function声明而不是类型关键字。当调用一个函数时，传递指定数目的参数不是必须的，过度的参数会被忽略，丢失的参数被赋值为undefined，这使写一个处理可选参数的函数变的很容易。 </p>
<p>一个函数有权使用一个参数数组，这个数组包含了所有的实际上被调用传递进来的参数。这使处理一个带可变数目的参数变的很容易，例如： </p>
<p>function sum() {&#160; // Take any number of parameters and return the sum </p>
<p>&#160;&#160;&#160; var total = 0; </p>
<p>&#160;&#160;&#160; for (var i = 0; i &lt; arguments.length; ++i) { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; total += arguments; </p>
<p>&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; return total; </p>
<p>} </p>
<p>JavaScript有内部函数，这与Java的内部类起了相同的作用，但是不是那么地明显。JavaScript也有也有扮演着lambda表达式的匿名函数。函数有词法上的作用域。 </p>
<p>函数是对象的第一课，这意味着函数可以被存储在对象中，并且作为参数传递给其它函数。 </p>
<p>定义函数 </p>
<p>有3种方式定义一个函数：function声明，function操作符和function构造器。 </p>
<p>function声明 </p>
<p>function声明在当前的作用域内创建一个被命名的函数。 </p>
<p>function name(argumentlist) block </p>
<p>函数可以嵌套，必须闭合，有0个或多个以逗号隔开的参数名称。block是由0个或多个{ }附着着。 </p>
<p>function声明以function操作符形式速记： </p>
<p>var name = function name (argumentlist) block ; </p>
<p>function操作符 </p>
<p>function操作符是一个产生一个对象的前缀操作符，它看起来和function声明很类似。 </p>
<p>function name(argumentlist) block </p>
<p>名称是可选的，如果提供了，那么可以用于函数的递归调用。这也用于访问函数的对象成员(除了IE以外)。如果名称被省略了，那么它就是一个匿名函数。 </p>
<p>函数的操作符经常用于把它分配给一个原型（prototype）。 </p>
<p>函数的操作符也经常用于在适当的地方定义函数，比迅速地得到当写回调的时候。( The function operator can also be used to define functions in-place, which is handy when writing callbacks.) </p>
<p>function构造器 </p>
<p>function构造器携带字符包含在参数和内部，从而产生一个function对象。 </p>
<p>new Function(strings&#8230;) </p>
<p>不要使用这种方式，由于语言引用的惯例导致很难恰当的表达一个函数身体作为一个字符串。在字符形式中，早期的错误检查不起作用。这也是很慢的，因为编译器必须被触发每当构造器被调用的时候，并且这样浪费内存，因为每个函数需要它自己独立的实现。 </p>
<p>对象和this </p>
<p>一个函数是一个对象，它可以包含成员就像其它对象一样。这就允许一个函数包含它自己的数据表，这也允许一个对象扮演一个&#8220;类&#8221;，包含构造函数和一套相关的函数。 </p>
<p>一个方式可以是一个对象的成员，当一个函数是一个对象的成员的时候，被成为&#8220;方法&#8221;。有一个特殊的变量，叫做&#8220;this&#8221;，当一个对象的方式被调用时指向了对象。 </p>
<p>例如：在表达式foo.bar()中，this变量就指向了对象foo，它作为了函数bar的一个额外的参数。函数bar可以使用this进入对象内部以找到有用的项目。 </p>
<p>一个深一点的表示式do.re.mi.fa()，this变量指向了对象do.re.mi，而不是对象do。在一个简单的函数调用中，this指向了没有太大用的Global Object (也叫 window)。当调用一个内部函数时，正确的行为是保护好当前this的值。 </p>
<p>构造器 </p>
<p>当函数被用于初始化对象的时候被叫做构造器，调用一个构造器的次序与调用一个普通的函数有一些细微的不同。一个构造器带着new前缀被调用： </p>
<p>new Constructor(parameters&#8230;) </p>
<p>根据习惯，构造器的名字的首字母使用大写的。 </p>
<p>new前缀改变了this 的含义，不是平常的值，而是代表了&#8220;新对象&#8221;。构造器的身体将会初始化对象的成员。构造起将会返回一个新对象，除非明确的使用了return语句进行替换。 </p>
<p>被构造的对象将会包含一个秘密的指向了构造器的prototype的成员的原型链接域。 </p>
<p>原型(Prototype) </p>
<p>对象包含一个隐藏的连接属性，这个链接指向了prototype，就是构造器的实例。 </p>
<p>当条目以点形式或索引形式从一个对象被访问的时候，如果条目没有在对象中被发现那么就检查他的链接对象，如果链接对象中也没发现，那么如果链接对象本身有一个链接对象，那么就继续检查这个链接对象，如果链接对象所有环节都检查完毕，那么就返回undefined。 </p>
<p>原型用于链接住一系列的继承 </p>
<p>成员可以用分配的方式增加到prototype中来，这我们定义一个类Demo，它从Ancestor继承，并增加了它独有的方法foo。 </p>
<p>function Demo() {} </p>
<p>Demo.prototype = new Ancestor(); </p>
<p>Demo.prototype.foo = function () {}; </p>
<p>变量 </p>
<p>定义变量使用var语句。当变量在函数内部定义时，var有着函数范围（function-scope）级别，这个变量不能在函数外被访问。JavaScript中没有其他的范围域粒度了，更具体的说，JavaScript中没有块域（block-scope）。 </p>
<p>任何在函数中使用但没有用var明确定义的变量，都会被假定属于全局对象。 </p>
<p>任何没有被明确初始化的变量都会被赋值于undefined。 </p>
<p>变量不是强类型的，一个变量引用一个对象、字符串、数字、布尔值、null值或者是undefined。 </p>
<p>当函数被调用的时候会产生一套新的变量，这允许递归的调用。 </p>
<p>闭合 </p>
<p>函数可以被定义到其他函数中，内部函数有权使用在外部函数定义的变量，如果一个引用内部函数继续存在（例如一个回调函数），那么外部函数的变量也将继续存在。 </p>
<p>返回值 </p>
<p>JavaScript没有void类型，所以每个函数都必须返回一个值，除了构造器之外默认值是undefined，构造器的默认返回值是this </p>
<p>语句 </p>
<p>语句包括 var, if, switch, for, while, do, break, continue, return, try, throw, and with，它们大多数与C类的语言相同。 </p>
<p>var语句是一个或多个变量名称的列表，它们以逗号隔开，带着可选的初始化表达式。 </p>
<p>var a, b = window.document.body; </p>
<p>如果var语句出现在所有的函数之外那么就声明了一个全局的变量。如果出现在一个函数内，就声明了一个局部的变量。 </p>
<p>在if语句，while语句，do语句， 和符合逻辑的操作符中，JavaScript视为false，null，undefined， &quot;&quot;(空字符串)，和数字0作为假（false）。其它所有值被视为真（true）。 </p>
<p>在switch语句中的case标记可以是表达式，它们不必非得是常数，也可以是字符串。 </p>
<p>有2种形式的for语句，第一种像这样 (init; test; inc)形式。第二种是对象重复器。 </p>
<p>for (name in object) { </p>
<p>&#160;&#160;&#160; if (object.hasOwnProperty(name)) { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; value = object[name]; </p>
<p>&#160;&#160;&#160; } </p>
<p>} </p>
<p>上面执行在object中的每一个name，名字产生的次序是不确定的。 </p>
<p>语句可以有个前缀，就是一个标识符跟着一个冒号。 </p>
<p>with语句不应该被使用 </p>
<p>操作符 </p>
<p>JavaScript有还算完整的操作符，大多数他们都与C类的语言工作的方式相同，但请注意一些细微的差异 </p>
<p>+操作符用于加法和字符串联，如果任意操作数是字符串，那么进行串联，这可能会引起错误，比如说&#8217;$&#8217; + 3 + 4 会得到&#8217;$34&#8242;，而不是&#8217;$7&#8242;。 </p>
<p>+可以作为一个前缀操作符把字符操作数转化为数字。 </p>
<p>!!可以作为一个前缀操作符，转化操作数为布尔值。 </p>
<p>&amp;&amp;操作符，一般被称为&#8220;逻辑与&#8221;(logical and)，它也被称为guard，如果第一个操作数是false、null、undefined、&quot;&quot;(空字符串)或者数字0那么将返回第一个操作数，否则将返回第二个操作数。这提供了一个便利地测试null值的方法： </p>
<p>var value = p &amp;&amp; p.name; /* The name value will </p>
<p>only be retrieved from p if p has a value, avoiding an error. */ </p>
<p>||操作符一般被称为&#8220;逻辑或&#8221;(logical or)，它也被称为default，如果第一个操作数是false、null、undefined、&quot;&quot;(空字符串)或者数字0， 那么将返回第二个操作数，否则返回第一个操作数。这提供了一个便利地设定默认值的方式： </p>
<p>value = v || 10; /* Use the value of v, but if v </p>
<p>doesn&#8217;t have a value, use 10 instead. */ </p>
<p>JavaScript支持一套逐位和移位的操作运算符，但却没有偶提供整型将他们应用。当一个数字操作数（一个64位浮点数）转化成32位整型的在运算之前，然后在转化回浮点数在操作在运算之后会发生什么呢？ </p>
<p>在JavaScript中，void是一个前缀操作符，而不是一种类型，它总是返回undefined值。这仅仅有一点点价值，我提到它的原因是万一你不小心以习惯打出来它，而不会被它怪异的行为所迷惑。 </p>
<p>typeof操作符返回一个基于它的操作数的字符串 </p>
<p>错误产生了。   <br />Object&#160;&#160;&#160;&#160; <br />&#8216;object&#8217; </p>
<p>Array&#160;&#160;&#160;&#160; <br />&#8216;object&#8217; </p>
<p>Function&#160;&#160;&#160;&#160; <br />&#8216;function&#8217; </p>
<p>String&#160;&#160;&#160;&#160; <br />&#8217;string&#8217; </p>
<p>Number&#160;&#160;&#160;&#160; <br />&#8216;number&#8217; </p>
<p>Boolean&#160;&#160;&#160;&#160; <br />&#8216;boolean&#8217; </p>
<p>null&#160;&#160;&#160;&#160; <br />&#8216;object&#8217; </p>
<p>undefined&#160;&#160;&#160;&#160; <br />&#8216;undefined&#8217; </p>
<p>杂目 </p>
<p>全局对象 </p>
<p>全局对象包含着所有的函数和所有的那些不在任何函数内定义的变量和对象，令人惊讶的是，全局变量在语言中并没有一个确切的名字。一些时候，this指向它，但大多数情况并不是的。在浏览器中window和self都是指向全局对象的全局对象成员，因此给了一个间接的对它的寻址方法。 </p>
<p>如果一个变量可以被访问，但是没有在当前域下被找到，就会在全局对象范围查找，如果仍没有，就会返回错误。 </p>
<p>ECMAScript规范没有谈论关于多个全局对象的可行性,或者上下文关系，但是浏览器支持这个，每个窗口都有它自己的全局对象。 </p>
<p>分号的插入时机 </p>
<p>这个语言的一个错误及时分号的插入，有一个技巧是用分号来终止语句。用各种开发工具去进行插入工作是合理的，没有必要为了语言的定义而让编译器去去做，请使用分号。 </p>
<p>预留字 </p>
<p>JavaScript对系统预留字的支持严重的过了头，这些预留字是： </p>
<p>abstract   <br />boolean break byte    <br />case catch char class const continue    <br />debugger default delete do double    <br />else enum export extends    <br />false final finally float for function    <br />goto    <br />if implements import in instanceof int interface    <br />long    <br />native new null    <br />package private protected public    <br />return    <br />short static super switch synchronized    <br />this throw throws transient true try typeof    <br />var volatile void    <br />while with </p>
<p>很大一部分这些关键字并没有在JavaScript中使用，一个预留字不可以在如下的方式下被使用： </p>
<p>1. 作为一个对象名字标记 </p>
<p>2. 作为点形式的的成员 </p>
<p>3. 作为函数的参数 </p>
<p>4. 作为一个var </p>
<p>5. 作为一个绝对的全局变量 </p>
<p>6. 作为一个语句标号(As a statement label) </p>
<p>前2个限制是不可原谅的，绝对不要使用。接下来的2个的使用可以被接受，但是这样使用是非常不牢靠的。 </p>
<p>特别声明，文章翻译于 <a href="http://javascript.crockford.com/survey.html" target="_blank">A Survey of the JavaScript Programming Language</a>    <br />版权由原作者所有。</p>
]]></content:encoded>
			<wfw:commentRss>http://panweizeng.com/document/archives/215/feed/</wfw:commentRss>
		</item>
		<item>
		<title>三个关键命令找出ASP.NET程序内存分片的原因</title>
		<link>http://panweizeng.com/document/archives/214</link>
		<comments>http://panweizeng.com/document/archives/214#comments</comments>
		<pubDate>Mon, 24 Mar 2008 00:56:32 +0000</pubDate>
		<dc:creator>弗里曼·潘</dc:creator>
		
		<category><![CDATA[.NET Framework]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://panweizeng.com/document/archives/214</guid>
		<description><![CDATA[http://www.cnblogs.com/lixiong/archive/2007/10/26/938430.html
最近一位朋友的ASP.NET程序怀疑有内存泄露问题。几个简单的页面，起来运行几分钟后，虚拟内存就到600多MB。从性能监视上看，private bytes只有200... ]]></description>
			<content:encoded><![CDATA[<p><a title="http://www.cnblogs.com/lixiong/archive/2007/10/26/938430.html" href="http://www.cnblogs.com/lixiong/archive/2007/10/26/938430.html">http://www.cnblogs.com/lixiong/archive/2007/10/26/938430.html</a></p>
<p>最近一位朋友的ASP.NET程序怀疑有内存泄露问题。几个简单的页面，起来运行几分钟后，虚拟内存就到600多MB。从性能监视上看，private bytes只有200多MB。 </p>
<p>这样的问题从经验上来说，十有八九都是内存碎片了。ASP.NET程序发生内存碎片的原因比较多，我常见的有: </p>
<p>1. Web.config中的debug=true，导致batch compilation=false,使得每一个ASPX页面都生成一个临时assembly。当页面比较多的时候，大量的assembly导致内存泄露。   <br />2. 程序中误用了XmlSerializer。频繁的XML序列化导致大量的动态assembly    <br />3. 程序中有大量的blocking IO操作，而且IO buffer没有及时释放。比如程序中有大量的Web Service调用，但是对方web service返回比较慢，使得调用程序中用来接收web service结果的小块buffer大量堆积，导致内存泄露 </p>
<p>下面是我拿到dump后的分析步骤。对于managed程序，找出问题的大致线索还是挺简单的。 </p>
<p>(随便无耻地推销下，《Windows高效排错》书中对这样的问题有更多的讨论。包括更多的案例和命令解释。该书最初的PDF草稿在http://www.cnblogs.com/lixiong/archive/2006/08/16/475520.html。如果有朋友从这个PDF中找到过排错的灵感，麻烦也帮忙无耻推销下。) </p>
<p>首先是看看CLR的版本了。这个直接看mscorwks文件或者mscorsrv文件。如果文件版本比较低，后面的就没必要仔细看了，升级CLR补丁后再说。 </p>
<p>0:000&gt; lmvm mscorwks   <br />start&#160;&#160;&#160; end&#160;&#160;&#160;&#160;&#160;&#160;&#160; module name    <br />79e70000 7a3d6000&#160;&#160; mscorwks&#160;&#160; (deferred)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; Image path: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll    <br />&#160;&#160;&#160; Image name: mscorwks.dll    <br />&#160;&#160;&#160; Timestamp:&#160;&#160;&#160;&#160;&#160;&#160;&#160; Fri Apr 13 15:15:54 2007 (461F2E2A)    <br />&#160;&#160;&#160; CheckSum:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00564CA8    <br />&#160;&#160;&#160; ImageSize:&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00566000    <br />&#160;&#160;&#160; File version:&#160;&#160;&#160;&#160; 2.0.50727.832    <br />&#160;&#160;&#160; Product version:&#160; 2.0.50727.832    <br />&#160;&#160;&#160; File flags:&#160;&#160;&#160;&#160;&#160;&#160; 0 (Mask 3F)    <br />&#160;&#160;&#160; File OS:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 4 Unknown Win32    <br />&#160;&#160;&#160; File type:&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2.0 Dll    <br />&#160;&#160;&#160; File date:&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00000000.00000000    <br />&#160;&#160;&#160; Translations:&#160;&#160;&#160;&#160; 0409.04b0    <br />&#160;&#160;&#160; CompanyName:&#160;&#160;&#160;&#160;&#160; Microsoft Corporation    <br />&#160;&#160;&#160; ProductName:&#160;&#160;&#160;&#160;&#160; Microsoft&#174; .NET Framework    <br />&#160;&#160;&#160; InternalName:&#160;&#160;&#160;&#160; mscorwks.dll    <br />&#160;&#160;&#160; OriginalFilename: mscorwks.dll    <br />&#160;&#160;&#160; ProductVersion:&#160;&#160; 2.0.50727.832    <br />&#160;&#160;&#160; FileVersion:&#160;&#160;&#160;&#160;&#160; 2.0.50727.832 (QFE.050727-8300)    <br />&#160;&#160;&#160; FileDescription:&#160; Microsoft .NET Runtime Common Language Runtime - WorkStation    <br />&#160;&#160;&#160; LegalCopyright:&#160;&#160; &#169; Microsoft Corporation.&#160; All rights reserved.    <br />&#160;&#160;&#160; Comments:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Flavor=Retail </p>
<p>恩，版本还是比较新的。既然是内存问题，先看GC中有多少object，占用了多少内存 </p>
<p>0:000&gt; !eeheap -gc   <br />Number of GC Heaps: 4    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br />Heap 0 (000f3f10)    <br />generation 0 starts at 0&#215;02fad2fc    <br />generation 1 starts at 0&#215;02f83ff8    <br />generation 2 starts at 0&#215;02f00038    <br />ephemeral segment allocation context: none    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />00109198 7a72c42c&#160; 7a74d308 0&#215;00020edc(134876)    <br />000fdfb0 790d5588&#160; 790f4b38 0&#215;0001f5b0(128432)    <br />02f00000 02f00038&#160; 03081450 0&#215;00181418(1578008)    <br />Large object heap starts at 0&#215;12f00038    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />12f00000 12f00038&#160; 131b00a0 0&#215;002b0068(2818152)    <br />Heap Size&#160; 0&#215;47190c(4659468)    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br />Heap 1 (000f50a0)    <br />generation 0 starts at 0&#215;06f5b110    <br />generation 1 starts at 0&#215;06f5acf8    <br />generation 2 starts at 0&#215;06f00038    <br />ephemeral segment allocation context: none    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />06f00000 06f00038&#160; 06ff511c 0&#215;000f50e4(1003748)    <br />Large object heap starts at 0&#215;14f00038    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />14f00000 14f00038&#160; 14f00048 0&#215;00000010(16)    <br />Heap Size&#160;&#160; 0xf50f4(1003764)    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br />Heap 2 (000f68a0)    <br />generation 0 starts at 0&#215;0af78634    <br />generation 1 starts at 0&#215;0af09d40    <br />generation 2 starts at 0&#215;0af00038    <br />ephemeral segment allocation context: none    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />0af00000 0af00038&#160; 0af92a0c 0&#215;000929d4(600532)    <br />Large object heap starts at 0&#215;16f00038    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />16f00000 16f00038&#160; 16f00048 0&#215;00000010(16)    <br />Heap Size&#160;&#160; 0&#215;929e4(600548)    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br />Heap 3 (000f7bc8)    <br />generation 0 starts at 0&#215;0ef7b270    <br />generation 1 starts at 0&#215;0ef7b264    <br />generation 2 starts at 0&#215;0ef00038    <br />ephemeral segment allocation context: none    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />0ef00000 0ef00038&#160; 0ef7d27c 0&#215;0007d244(512580)    <br />Large object heap starts at 0&#215;18f00038    <br /> segment&#160;&#160;&#160; begin allocated&#160;&#160;&#160;&#160; size    <br />18f00000 18f00038&#160; 18f00048 0&#215;00000010(16)    <br />Heap Size&#160;&#160; 0&#215;7d254(512596)    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br />GC Heap Size&#160; 0&#215;676638(6776376) </p>
<p>内存占用只有6M，显然不是CLR object导致的问题。那看来真的就是内存碎片了。于是先看看程序中有多少DLL:   <br />0:000&gt; lmf    <br />start&#160;&#160;&#160; end&#160;&#160;&#160;&#160;&#160;&#160;&#160; module name    <br />00900000 00bc5000&#160;&#160; xpsp2res C:\WINDOWS\system32\xpsp2res.dll    <br />01000000 01005000&#160;&#160; w3wp&#160;&#160;&#160;&#160; c:\WINDOWS\system32\inetsrv\w3wp.exe    <br />1b740000 1b748000&#160;&#160; App_global_asax_incckcvw C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\App_global.asax.incckcvw.dll    <br />1b770000 1b790000&#160;&#160; Boke_WebRoot_Admin C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\assembly\dl3\0854db20\0aaa279d_a314c801\Boke.WebRoot.Admin.DLL    <br />1b7e0000 1b820000&#160;&#160; log4net&#160; C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\assembly\dl3\8af1019b\00a071ef_de00c801\log4net.DLL    <br />1bb00000 1bb0e000&#160;&#160; App_Web_fsrghzyk C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\App_Web_fsrghzyk.dll    <br />1bb20000 1bb30000&#160;&#160; AspNetPager C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\assembly\dl3\53ce5ce1\00a071ef_de00c801\AspNetPager.DLL    <br />1bb30000 1bb3c000&#160;&#160; App_Web_qenznn_e C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\App_Web_qenznn_e.dll    <br />1bb60000 1bb70000&#160;&#160; UDMap&#160;&#160;&#160; D:\webfolder\dvdvAdmin\bin\Map.dll    <br />50210000 5025c000&#160;&#160; SMDiagnostics_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\SMDiagnostics\da4366daf8361c62ed3fcec4c55fa9ca\SMDiagnostics.ni.dll    <br />50270000 50368000&#160;&#160; System_IdentityModel_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.IdentityModel\bc31a40dee949687576d5395efcab6a0\System.IdentityModel.ni.dll    <br />504e0000 50728000&#160;&#160; System_Runtime_Serialization_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Runtime.Seri#\c861896fa11d6eef9fed23cff7b77b01\System.Runtime.Serialization.ni.dll    <br />507a0000 5185e000&#160;&#160; System_ServiceModel_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.ServiceModel\719a7cce9b36b780b3edd9869ceb2537\System.ServiceModel.ni.dll    <br />5a300000 5a307000&#160;&#160; w3tp&#160;&#160;&#160;&#160; c:\WINDOWS\system32\inetsrv\w3tp.dll    <br />5a320000 5a332000&#160;&#160; w3isapi&#160; c:\WINDOWS\system32\inetsrv\w3isapi.dll    <br />5a360000 5a36d000&#160;&#160; w3dt&#160;&#160;&#160;&#160; c:\WINDOWS\system32\inetsrv\w3dt.dll    <br />5a390000 5a3e8000&#160;&#160; w3core&#160;&#160; c:\WINDOWS\system32\inetsrv\w3core.dll    <br />5a3f0000 5a3f6000&#160;&#160; w3comlog c:\WINDOWS\system32\inetsrv\w3comlog.dll    <br />5a400000 5a408000&#160;&#160; w3cache&#160; c:\WINDOWS\system32\inetsrv\w3cache.dll    <br />5a420000 5a431000&#160;&#160; iismap&#160;&#160; C:\WINDOWS\system32\iismap.dll    <br />5b640000 5b658000&#160;&#160; strmfilt C:\WINDOWS\system32\strmfilt.dll    <br />5e620000 5e6da000&#160;&#160; Microsoft_JScript C:\WINDOWS\assembly\GAC_MSIL\Microsoft.JScript\8.0.0.0__b03f5f7f11d50a3a\Microsoft.JScript.dll    <br />5f270000 5f2ca000&#160;&#160; hnetcfg&#160; C:\WINDOWS\system32\hnetcfg.dll    <br />60060000 60066000&#160;&#160; aspnet_filter C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll    <br />60070000 60075000&#160;&#160; aspnet_isapi \\?\c:\WINDOWS\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll    <br />608f0000 60901000&#160;&#160; admwprox C:\WINDOWS\system32\admwprox.dll    <br />60ba0000 60bb1000&#160;&#160; wamreg&#160;&#160; c:\WINDOWS\system32\inetsrv\wamreg.dll    <br />62da0000 62da7000&#160;&#160; lonsint&#160; c:\WINDOWS\system32\inetsrv\lonsint.dll    <br />637a0000 63d02000&#160;&#160; System_Xml_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Xml\e342cc4334d3ab13ce752de73164c01b\System.Xml.ni.dll    <br />64700000 6472d000&#160;&#160; iisutil&#160; c:\WINDOWS\system32\inetsrv\iisutil.dll    <br />647b0000 647d7000&#160;&#160; iisrtl&#160;&#160; C:\WINDOWS\system32\iisrtl.dll    <br />64890000 6498a000&#160;&#160; System_Configuration_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Configuration\edc1f15b90b2c6a4dc59b305f14bb98d\System.Configuration.ni.dll    <br />64e70000 6513c000&#160;&#160; System_Data C:\WINDOWS\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    <br />65140000 657a6000&#160;&#160; System_Data_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Data\42481d9f835b4b6c150c50d2642781b9\System.Data.ni.dll    <br />65f20000 66ac6000&#160;&#160; System_Web_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Web\83c662f1a20af1b2deea3f9a040ccbd6\System.Web.ni.dll    <br />67150000 67159000&#160;&#160; httpapi&#160; C:\WINDOWS\system32\httpapi.dll    <br />68000000 68035000&#160;&#160; rsaenh&#160;&#160; C:\WINDOWS\system32\rsaenh.dll    <br />685b0000 685ba000&#160;&#160; gzip&#160;&#160;&#160;&#160; C:\WINDOWS\system32\inetsrv\gzip.dll    <br />695a0000 697da000&#160;&#160; System_Web_Mobile_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Web.Mobile\e7d2fee1612b52a914d8d253d5e49a7c\System.Web.Mobile.ni.dll    <br />69890000 698d0000&#160;&#160; System_Web_RegularExpressions_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Web.RegularE#\1fa927a42b36176da2cdc193f0435950\System.Web.RegularExpressions.ni.dll    <br />6a2a0000 6a307000&#160;&#160; webengine \\?\c:\WINDOWS\microsoft.net\framework\v2.0.50727\webengine.dll    <br />6d0f0000 6d110000&#160;&#160; iisres&#160;&#160; c:\WINDOWS\system32\inetsrv\iisres.dll    <br />71640000 7180d000&#160;&#160; acgenral C:\WINDOWS\AppPatch\acgenral.dll    <br />71ae0000 71ae8000&#160;&#160; wshtcpip C:\WINDOWS\system32\wshtcpip.dll    <br />71af0000 71b12000&#160;&#160; shimeng&#160; C:\WINDOWS\system32\shimeng.dll    <br />71b20000 71b61000&#160;&#160; mswsock&#160; C:\WINDOWS\system32\mswsock.dll    <br />71b70000 71ba6000&#160;&#160; uxtheme&#160; C:\WINDOWS\system32\uxtheme.dll    <br />71bb0000 71bb9000&#160;&#160; wsock32&#160; C:\WINDOWS\system32\wsock32.dll    <br />71bd0000 71be1000&#160;&#160; mpr&#160;&#160;&#160;&#160;&#160; C:\WINDOWS\system32\mpr.dll    <br />71bf0000 71bf8000&#160;&#160; ws2help&#160; C:\WINDOWS\system32\ws2help.dll    <br />71c00000 71c17000&#160;&#160; ws2_32&#160;&#160; C:\WINDOWS\system32\ws2_32.dll    <br />71c40000 71c97000&#160;&#160; netapi32 C:\WINDOWS\system32\netapi32.dll    <br />745e0000 7489e000&#160;&#160; msi&#160;&#160;&#160;&#160;&#160; C:\WINDOWS\system32\msi.dll    <br />75490000 754f5000&#160;&#160; usp10&#160;&#160;&#160; C:\WINDOWS\system32\usp10.dll    <br />75e60000 75e87000&#160;&#160; apphelp&#160; C:\WINDOWS\system32\apphelp.dll    <br />76190000 761a2000&#160;&#160; msasn1&#160;&#160; C:\WINDOWS\system32\msasn1.dll    <br />761b0000 76243000&#160;&#160; crypt32&#160; C:\WINDOWS\system32\crypt32.dll    <br />76290000 762ad000&#160;&#160; imm32&#160;&#160;&#160; C:\WINDOWS\system32\imm32.dll    <br />76920000 769e2000&#160;&#160; userenv&#160; C:\WINDOWS\system32\userenv.dll    <br />76aa0000 76acd000&#160;&#160; winmm&#160;&#160;&#160; C:\WINDOWS\system32\winmm.dll    <br />76b70000 76b7b000&#160;&#160; psapi&#160;&#160;&#160; C:\WINDOWS\system32\psapi.dll    <br />76c90000 76cb7000&#160;&#160; msv1_0&#160;&#160; C:\WINDOWS\system32\msv1_0.dll    <br />76cf0000 76d0a000&#160;&#160; iphlpapi C:\WINDOWS\system32\iphlpapi.dll    <br />76e30000 76e3c000&#160;&#160; rtutils&#160; C:\WINDOWS\system32\rtutils.dll    <br />76e40000 76e52000&#160;&#160; rasman&#160;&#160; C:\WINDOWS\system32\rasman.dll    <br />76e60000 76e8f000&#160;&#160; tapi32&#160;&#160; C:\WINDOWS\system32\tapi32.dll    <br />76e90000 76ecf000&#160;&#160; rasapi32 C:\WINDOWS\system32\rasapi32.dll    <br />76ed0000 76efa000&#160;&#160; dnsapi&#160;&#160; C:\WINDOWS\system32\dnsapi.dll    <br />76f10000 76f3e000&#160;&#160; wldap32&#160; C:\WINDOWS\system32\wldap32.dll    <br />76f50000 76f63000&#160;&#160; secur32&#160; C:\WINDOWS\system32\secur32.dll    <br />76f70000 76f77000&#160;&#160; winrnr&#160;&#160; C:\WINDOWS\system32\winrnr.dll    <br />76f80000 76f85000&#160;&#160; rasadhlp C:\WINDOWS\system32\rasadhlp.dll    <br />77010000 770d6000&#160;&#160; comres&#160;&#160; C:\WINDOWS\system32\comres.dll    <br />77380000 77411000&#160;&#160; user32&#160;&#160; C:\WINDOWS\system32\user32.dll    <br />77420000 77523000&#160;&#160; comctl32 C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.3790.3959_x-ww_D8713E55\comctl32.dll    <br />77670000 777a9000&#160;&#160; ole32&#160;&#160;&#160; C:\WINDOWS\system32\ole32.dll    <br />777b0000 77833000&#160;&#160; clbcatq&#160; C:\WINDOWS\system32\clbcatq.dll    <br />77b70000 77b84000&#160;&#160; msacm32&#160; C:\WINDOWS\system32\msacm32.dll    <br />77b90000 77b98000&#160;&#160; version&#160; C:\WINDOWS\system32\version.dll    <br />77ba0000 77bfa000&#160;&#160; msvcrt&#160;&#160; C:\WINDOWS\system32\msvcrt.dll    <br />77c00000 77c48000&#160;&#160; gdi32&#160;&#160;&#160; C:\WINDOWS\system32\gdi32.dll    <br />77c50000 77cef000&#160;&#160; rpcrt4&#160;&#160; C:\WINDOWS\system32\rpcrt4.dll    <br />77d00000 77d8b000&#160;&#160; oleaut32 C:\WINDOWS\system32\oleaut32.dll    <br />77da0000 77df2000&#160;&#160; shlwapi&#160; C:\WINDOWS\system32\shlwapi.dll    <br />77e00000 77e21000&#160;&#160; ntmarta&#160; C:\WINDOWS\system32\ntmarta.dll    <br />77e40000 77f42000&#160;&#160; kernel32 C:\WINDOWS\system32\kernel32.dll    <br />77f50000 77feb000&#160;&#160; advapi32 C:\WINDOWS\system32\advapi32.dll    <br />78130000 781cb000&#160;&#160; msvcr80&#160; C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0DE06ACD\msvcr80.dll    <br />79000000 79045000&#160;&#160; mscoree&#160; C:\WINDOWS\system32\mscoree.dll    <br />79060000 790b3000&#160;&#160; mscorjit C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll    <br />790c0000 79b90000&#160;&#160; mscorlib_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\56cbcbd518a77421a852a37b61624936\mscorlib.ni.dll    <br />79e70000 7a3d6000&#160;&#160; mscorwks C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll    <br />7a440000 7ac06000&#160;&#160; System_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System\19aba12bb5350aa99107e93bafbb4f51\System.ni.dll    <br />7ade0000 7af6c000&#160;&#160; System_Drawing_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Drawing\e3104e1713757f14b54b7835be2a0e26\System.Drawing.ni.dll    <br />7c800000 7c8c0000&#160;&#160; ntdll&#160;&#160;&#160; C:\WINDOWS\system32\ntdll.dll    <br />7c8d0000 7d0ce000&#160;&#160; shell32&#160; C:\WINDOWS\system32\shell32.dll    <br />7e020000 7e02f000&#160;&#160; samlib&#160;&#160; C:\WINDOWS\system32\samlib.dll    <br />7f000000 7f009000&#160;&#160; lpk&#160;&#160;&#160;&#160;&#160; C:\WINDOWS\system32\lpk.dll </p>
<p>非常普通。也就这点DLL，根本没有导致内存碎片的潜力呀！不死心，看看是不是有很多线程被block住了。要是有个几百个线程，嘿嘿   <br />0:000&gt; ~    <br />.&#160; 0&#160; Id: 694.540 Suspend: 1 Teb: 7ffdd000 Unfrozen    <br />&#160;&#160; 1&#160; Id: 694.12a0 Suspend: 1 Teb: 7ffdb000 Unfrozen    <br />&#160;&#160; 2&#160; Id: 694.1040 Suspend: 1 Teb: 7ffda000 Unfrozen    <br />&#160;&#160; 3&#160; Id: 694.11f0 Suspend: 1 Teb: 7ffd9000 Unfrozen    <br />&#160;&#160; 4&#160; Id: 694.13d0 Suspend: 1 Teb: 7ffd7000 Unfrozen    <br />&#160;&#160; 5&#160; Id: 694.1338 Suspend: 1 Teb: 7ffd6000 Unfrozen    <br />&#160;&#160; 6&#160; Id: 694.10e4 Suspend: 1 Teb: 7ffd5000 Unfrozen    <br />&#160;&#160; 7&#160; Id: 694.e4c Suspend: 1 Teb: 7ffd4000 Unfrozen    <br />&#160;&#160; 8&#160; Id: 694.10a8 Suspend: 1 Teb: 7ffd3000 Unfrozen    <br />&#160;&#160; 9&#160; Id: 694.1144 Suspend: 1 Teb: 7ff9f000 Unfrozen    <br />&#160; 10&#160; Id: 694.1340 Suspend: 1 Teb: 7ff9e000 Unfrozen    <br />&#160; 11&#160; Id: 694.1484 Suspend: 1 Teb: 7ff9d000 Unfrozen    <br />&#160; 12&#160; Id: 694.1170 Suspend: 1 Teb: 7ff9c000 Unfrozen    <br />&#160; 13&#160; Id: 694.11d8 Suspend: 1 Teb: 7ff9b000 Unfrozen    <br />&#160; 14&#160; Id: 694.1768 Suspend: 1 Teb: 7ff9a000 Unfrozen    <br />&#160; 15&#160; Id: 694.173c Suspend: 1 Teb: 7ff99000 Unfrozen    <br />&#160; 16&#160; Id: 694.a80 Suspend: 1 Teb: 7ff98000 Unfrozen    <br />&#160; 17&#160; Id: 694.500 Suspend: 1 Teb: 7ff97000 Unfrozen    <br />&#160; 18&#160; Id: 694.1194 Suspend: 1 Teb: 7ff96000 Unfrozen    <br />&#160; 19&#160; Id: 694.16c8 Suspend: 1 Teb: 7ff95000 Unfrozen    <br />&#160; 20&#160; Id: 694.162c Suspend: 1 Teb: 7ff94000 Unfrozen    <br />&#160; 21&#160; Id: 694.a8c Suspend: 1 Teb: 7ff93000 Unfrozen    <br />&#160; 22&#160; Id: 694.ad4 Suspend: 1 Teb: 7ff92000 Unfrozen    <br />&#160; 23&#160; Id: 694.1098 Suspend: 1 Teb: 7ff2f000 Unfrozen    <br />&#160; 24&#160; Id: 694.b08 Suspend: 1 Teb: 7ff2e000 Unfrozen    <br />&#160; 25&#160; Id: 694.19c Suspend: 1 Teb: 7ff90000 Unfrozen    <br />&#160; 26&#160; Id: 694.fcc Suspend: 1 Teb: 7ff2d000 Unfrozen    <br />&#160; 27&#160; Id: 694.764 Suspend: 1 Teb: 7ff91000 Unfrozen    <br />&#160; 28&#160; Id: 694.1334 Suspend: 1 Teb: 7ff2b000 Unfrozen </p>
<p>。。。线程也这么少，怎么办 </p>
<p>还是不死心。从上面的DLL看到，程序中的模块要么系统的，要么CLR的，没有COM/COM+，问题应该还是在CLR相关的东西上。于是用!eeheap &#8211;loader看看loader heap的大小: </p>
<p>0:000&gt; !eeheap -loader   <br />Loader Heap:    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />System Domain: 7a38f918    <br />LowFrequencyHeap: Size: 0&#215;0(0)bytes.    <br />HighFrequencyHeap: 02e72000(8000:1000) Size: 0&#215;1000(4096)bytes.    <br />StubHeap: 02e7a000(2000:2000) 1b5b0000(10000:4000) Size: 0&#215;6000(24576)bytes.    <br />Virtual Call Stub Heap:    <br />&#160; IndcellHeap: Size: 0&#215;0(0)bytes.    <br />&#160; LookupHeap: Size: 0&#215;0(0)bytes.    <br />&#160; ResolveHeap: Size: 0&#215;0(0)bytes.    <br />&#160; DispatchHeap: Size: 0&#215;0(0)bytes.    <br />&#160; CacheEntryHeap: Size: 0&#215;0(0)bytes.    <br />Total size: 0&#215;7000(28672)bytes    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />Shared Domain: 7a38fef0    <br />LowFrequencyHeap: 02ea0000(2000:1000) 1b6d0000(10000:d000) Size: 0xe000(57344)bytes.    <br />Wasted: 0&#215;1000(4096)bytes.    <br />HighFrequencyHeap: 02ea2000(8000:5000) Size: 0&#215;5000(20480)bytes.    <br />StubHeap: 02eaa000(2000:1000) 1bc80000(10000:1000) Size: 0&#215;2000(8192)bytes.    <br />Wasted: 0&#215;1000(4096)bytes.    <br />Virtual Call Stub Heap:    <br />&#160; IndcellHeap: 02eb0000(2000:1000) Size: 0&#215;1000(4096)bytes.    <br />&#160; LookupHeap: 02eb5000(2000:1000) Size: 0&#215;1000(4096)bytes.    <br />&#160; ResolveHeap: 02ebb000(5000:5000) 1bc10000(10000:2000) Size: 0&#215;7000(28672)bytes.    <br />&#160; DispatchHeap: 02eb7000(4000:3000) Size: 0&#215;3000(12288)bytes.    <br />&#160; CacheEntryHeap: 02eb2000(3000:1000) Size: 0&#215;1000(4096)bytes.    <br />Total size: 0&#215;21000(135168)bytes    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />Domain 1: ded80    <br />LowFrequencyHeap: 02e80000(2000:1000) Size: 0&#215;1000(4096)bytes.    <br />HighFrequencyHeap: 02e82000(8000:4000) Size: 0&#215;4000(16384)bytes.    <br />StubHeap: Size: 0&#215;0(0)bytes.    <br />Virtual Call Stub Heap:    <br />&#160; IndcellHeap: Size: 0&#215;0(0)bytes.    <br />&#160; LookupHeap: Size: 0&#215;0(0)bytes.    <br />&#160; ResolveHeap: Size: 0&#215;0(0)bytes.    <br />&#160; DispatchHeap: Size: 0&#215;0(0)bytes.    <br />&#160; CacheEntryHeap: Size: 0&#215;0(0)bytes.    <br />Total size: 0&#215;5000(20480)bytes    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />Domain 2: 113b60    <br />LowFrequencyHeap: 1b550000(2000:2000) 1b760000(10000:f000) 1b830000(10000:10000) 1bcd0000(10000:f000) 1c150000(10000:10000) 1c260000(10000:10000) 1c300000(10000:10000) 1c380000(10000:10000) 1c430000(10000:10000) 1c510000(10000:10000) 1c5c0000(10000:10000) 1c6b0000(10000:10000) 1c750000(10000:10000) 1c800000(10000:f000) 1c8b0000(10000:f000) 1c920000(10000:10000) &#8230;&#8230;    <br />1db30000(10000:f000) 1dbc0000(10000:f000) 1dca0000(10000:f000) 1dd50000(10000:10000) 1de00000(10000:10000) 1de90000(10000:10000) 1df40000(10000:10000) 1dfb0000(10000:10000) 1df90000(10000:f000) 1e0e0000(10000:f000) 1e180000(10000:10000) 1e230000(10000:10000) 1e2d0000(10000:10000) 1e370000(10000:10000) 1e420000(10000:f000) 1e4b0000(10000:f000) 1e550000(10000:f000) 1e600000(10000:10000) 1e6b0000(10000:10000) 1e740000(10000:10000) 1e7f0000(10000:10000) 1e8e0000(10000:10000) 1eb60000(10000:f000) 1ec10000(10000:f000) 1ed30000(10000:10000) 1eda0000(10000:10000) 1ee40000(10000:c000) Size: 0&#215;447000(4485120)bytes.    <br />Wasted: 0&#215;17000(94208)bytes.    <br />HighFrequencyHeap: 1b552000(8000:8000) 1b820000(10000:f000) 1bb80000(10000:10000) 1c120000(10000:10000) 1c230000(10000:f000) 1c2d0000(10000:10000) 1c390000(10000:10000) 1c460000(10000:10000) 1c570000(10000:10000) 1c610000(10000:10000) 1c720000(10000:f000) 1c7d0000(10000:10000) &#8230;&#8230;    <br />1dd20000(10000:10000) 1ddf0000(10000:10000) 1dea0000(10000:10000) 1df20000(10000:f000) 1df30000(10000:10000) 1e080000(10000:10000) 1e150000(10000:10000) 1e220000(10000:10000) 1e2e0000(10000:10000) 1e3b0000(10000:f000) 1e450000(10000:10000) 1e500000(10000:10000) 1e5d0000(10000:10000) 1e6a0000(10000:10000) 1e750000(10000:10000) 1e860000(10000:f000) 1e910000(10000:10000) 1ebb0000(10000:10000) 1ec80000(10000:10000) 1ed90000(10000:10000) 1ee50000(10000:9000) Size: 0&#215;3b8000(3899392)bytes.    <br />Wasted: 0&#215;9000(36864)bytes.    <br />StubHeap: 1b55a000(2000:1000) Size: 0&#215;1000(4096)bytes.    <br />Virtual Call Stub Heap:    <br />&#160; IndcellHeap: 1b5a0000(3000:1000) Size: 0&#215;1000(4096)bytes.    <br />&#160; LookupHeap: 1b5a6000(3000:1000) Size: 0&#215;1000(4096)bytes.    <br />&#160; ResolveHeap: 1b5ac000(4000:1000) Size: 0&#215;1000(4096)bytes.    <br />&#160; DispatchHeap: 1b5a9000(3000:1000) Size: 0&#215;1000(4096)bytes.    <br />&#160; CacheEntryHeap: 1b5a3000(3000:1000) Size: 0&#215;1000(4096)bytes.    <br />Total size: 0&#215;804000(8404992)bytes    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />Jit code heap:    <br />LoaderCodeHeap: 1ee10000(10000:c000) Size: 0xc000(49152)bytes.    <br />LoaderCodeHeap: 1ed60000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1ebe0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1e8d0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1e7a0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1e690000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1e5a0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1e4a0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1e3a0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />&#8230;&#8230;    <br />LoaderCodeHeap: 1cb70000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1ca50000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c980000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c870000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c780000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c640000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c540000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c400000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c330000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1c1c0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1bce0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />LoaderCodeHeap: 1bc70000(10000:1000) Size: 0&#215;1000(4096)bytes.    <br />HostCodeHeap: 1bc60000 Size: 0xa000(40960)bytes.    <br />LoaderCodeHeap: 1b7d0000(10000:10000) Size: 0&#215;10000(65536)bytes.    <br />Total size: 0&#215;2d7000(2977792)bytes    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />Module Thunk heaps:    <br />Module 50224000: Size: 0&#215;0(0)bytes.    <br />Module 505c4000: Size: 0&#215;0(0)bytes.    <br />Module 648ec000: Size: 0&#215;0(0)bytes.    <br />Module 6638c000: Size: 0&#215;0(0)bytes.    <br />Module 7a71e000: Size: 0&#215;0(0)bytes.    <br />Module 502c2000: Size: 0&#215;0(0)bytes.    <br />Module 790c2000: Size: 0&#215;0(0)bytes.    <br />Module 02ea2380: Size: 0&#215;0(0)bytes.    <br />Module 02ea2010: Size: 0&#215;0(0)bytes.    <br />&#8230;&#8230;    <br />Module 1ed9705c: Size: 0&#215;0(0)bytes.    <br />Module 1ed9a884: Size: 0&#215;0(0)bytes.    <br />Module 1ed9e0ac: Size: 0&#215;0(0)bytes.    <br />Module 1ee51944: Size: 0&#215;0(0)bytes.    <br />Module 1ee5516c: Size: 0&#215;0(0)bytes.    <br />Total size: 0&#215;0(0)bytes    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />Module Lookup Table heaps:    <br />Module 50224000: Size: 0&#215;0(0)bytes.    <br />Module 505c4000: Size: 0&#215;0(0)bytes.    <br />Module 648ec000: Size: 0&#215;0(0)bytes.    <br />Module 6638c000: Size: 0&#215;0(0)bytes.    <br />Module 7a71e000: Size: 0&#215;0(0)bytes.    <br />Module 502c2000: Size: 0&#215;0(0)bytes.    <br />Module 790c2000: Size: 0&#215;0(0)bytes.    <br />Module 02ea2380: Size: 0&#215;0(0)bytes.    <br />Module 02ea2010: Size: 0&#215;0(0)bytes.    <br />Module 69670000: Size: 0&#215;0(0)bytes.    <br />&#8230;&#8230;    <br />Module 639ea000: Size: 0&#215;0(0)bytes.    <br />Module 50d5a000: Size: 0&#215;0(0)bytes.    <br />Module 653b4000: Size: 0&#215;0(0)bytes.    <br />Module 02ea27cc: Size: 0&#215;0(0)bytes.    <br />Module 1ed9705c: Size: 0&#215;0(0)bytes.    <br />Module 1ed9a884: Size: 0&#215;0(0)bytes.    <br />Module 1ed9e0ac: Size: 0&#215;0(0)bytes.    <br />Module 1ee51944: Size: 0&#215;0(0)bytes.    <br />Module 1ee5516c: Size: 0&#215;0(0)bytes.    <br />Total size: 0&#215;0(0)bytes    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />Total LoaderHeap size: 0xb08000(11567104)bytes    <br />======================================= </p>
<p>上面只是!eeheap &#8211;loader输出的5%左右。从上面的输出来看，loader heap占用了11MB的内存。这个数字没问题，问题在于这个module list上面。这里成千上万的module,势必导致内存碎片。   <br />前面lmvm命令可以检查加载的module。但是lmvm命令工作方式是Win32层面的。如果DLL通过LoadLibrary起来的，这个命令能看到。但是CLR的动态DLL,除了使用LoadLibrary外，CLR还可以直接用MapViewOfFile的方法直接把DLL弄到内存中操作。这种情况lmvm就没把法了。所以需要用!eeheap &#8211;loader从CLR层面检查。    <br />除了!eeheap外，用!dumpdomain命令，也可以从CLR层面列举出所有的assembly，包括动态的和静态的。    <br />找到内存碎片的原因后，接下来就是分析这些碎片的来源了。既然这里是module，那随便挑一个，用!dumpmodule检查详细信息:    <br />0:000&gt; !dumpmodule -mt 1ee5516c    <br />Name: cplxobsw, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null    <br />Attributes: PEFile     <br />Assembly: 1e929530    <br />LoaderHeap: 00000000    <br />TypeDefToMethodTableMap: 1ee47f18    <br />TypeRefToMethodTableMap: 1ee47fe4    <br />MethodDefToDescMap: 1ee48058    <br />FieldDefToDescMap: 1ee484f4    <br />MemberRefToDescMap: 1ee486e8    <br />FileReferencesMap: 1ee488a4    <br />AssemblyReferencesMap: 1ee488a8    <br />MetaData start address: 1ee8be8c (49668 bytes) </p>
<p>Types defined in this module </p>
<p>&#160;&#160;&#160;&#160;&#160; MT&#160;&#160;&#160; TypeDef Name   <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br />1ee57e5c 0&#215;02000002 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap    <br />1ee587ac 0&#215;02000003 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderI_UAC_WSSoap    <br />1ee55844 0&#215;02000004 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializer1    <br />1ee56fac 0&#215;02000005 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer    <br />1ee5745c 0&#215;02000006 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer1    <br />1ee579d4 0&#215;02000007 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer2    <br />1ee575ec 0&#215;02000008 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer3    <br />1ee55e7c 0&#215;02000009 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer4    <br />1ee559cc 0&#215;0200000a Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer5    <br />1ee55b5c 0&#215;0200000b Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer6    <br />1ee57a9c 0&#215;0200000c Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer7    <br />1ee55db4 0&#215;0200000d Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer8    <br />1ee56714 0&#215;0200000e Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer9    <br />1ee5777c 0&#215;0200000f Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer10    <br />1ee57524 0&#215;02000010 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer11    <br />1ee56d54 0&#215;02000011 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer12    <br />1ee57844 0&#215;02000012 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer13    <br />1ee568a4 0&#215;02000013 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer14    <br />1ee576b4 0&#215;02000014 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer15    <br />1ee55a94 0&#215;02000015 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer16    <br />1ee55cec 0&#215;02000016 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer17    <br />1ee57204 0&#215;02000017 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer18    <br />1ee5619c 0&#215;02000018 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer19    <br />1ee5632c 0&#215;02000019 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer20    <br />1ee55f44 0&#215;0200001a Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer21    <br />1ee572cc 0&#215;0200001b Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer22    <br />1ee57c2c 0&#215;0200001c Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer23    <br />1ee55c24 0&#215;0200001d Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer24    <br />1ee56c8c 0&#215;0200001e Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer25    <br />1ee567dc 0&#215;0200001f Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer26    <br />1ee56e1c 0&#215;02000020 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer27    <br />1ee56584 0&#215;02000021 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer28    <br />1ee56a34 0&#215;02000022 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer29    <br />1ee5713c 0&#215;02000023 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer30    <br />1ee5600c 0&#215;02000024 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer31    <br />1ee57074 0&#215;02000025 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer32    <br />1ee560d4 0&#215;02000026 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer33    <br />1ee564bc 0&#215;02000027 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer34    <br />1ee5696c 0&#215;02000028 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer35    <br />1ee57394 0&#215;02000029 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer36    <br />1ee56ee4 0&#215;0200002a Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer37    <br />1ee563f4 0&#215;0200002b Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer38    <br />1ee56264 0&#215;0200002c Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer39    <br />1ee56afc 0&#215;0200002d Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer40    <br />1ee56bc4 0&#215;0200002e Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer41    <br />1ee5790c 0&#215;0200002f Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer42    <br />1ee5664c 0&#215;02000030 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer43    <br />1ee57b64 0&#215;02000031 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer44    <br />1ee55904 0&#215;02000032 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer45    <br />1ee5575c 0&#215;02000033 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializerContract </p>
<p>Types referenced in this module </p>
<p>&#160;&#160;&#160;&#160;&#160; MT&#160;&#160;&#160; TypeRef Name   <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br />63a191a4 0&#215;01000001 System.Xml.Serialization.XmlSerializationWriter    <br />63a18ac0 0&#215;01000002 System.Xml.Serialization.XmlSerializationReader    <br />63a19804 0&#215;01000003 System.Xml.Serialization.XmlSerializer    <br />63a19798 0&#215;01000004 System.Xml.Serialization.XmlSerializerImplementation    <br />1bb88e8c 0&#215;01000005 t_UserInfo    <br />639f2988 0&#215;01000006 System.Xml.XmlReader    <br />790fd8b4 0&#215;01000007 System.Collections.Hashtable    <br />790ffe7c 0&#215;01000008 System.Type    <br />790f9244 0&#215;0100000e System.String    <br />790fdb60 0&#215;0100000f System.Int32    <br />639f3758 0&#215;01000010 System.Xml.XmlConvert    <br />790f8a7c 0&#215;01000014 System.Object    <br />79103c00 0&#215;01000019 System.Boolean    <br />639f59e0 0&#215;0100001a System.Xml.XmlQualifiedName    <br />639fa358 0&#215;0100001b System.Xml.XmlNameTable </p>
<p>上面的输入就非常明显了。程序明显是在做XmlSerialization。接下来看看是在Serialize什么类型的object，有了这个信息后，去看源代码就更有方向了.随便找一个method table来看: </p>
<p>0:000&gt; !dumpmt -md 1ee57e5c    <br />EEClass: 1ee4b428    <br />Module: 1ee5516c    <br />Name: Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap    <br />mdToken: 02000002&#160; (cplxobsw, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)    <br />BaseSize: 0&#215;44    <br />ComponentSize: 0&#215;0    <br />Number of IFaces in IFaceMap: 0    <br />Slots in VTable: 53    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;    <br />MethodDesc Table    <br />&#160;&#160; Entry MethodDesc&#160;&#160;&#160;&#160;&#160; JIT Name    <br />7934cdcc&#160;&#160; 79137ab8&#160;&#160; PreJIT System.Object.ToString()    <br />7934bba0&#160;&#160; 79137ac0&#160;&#160; PreJIT System.Object.Equals(System.Object)    <br />7934bb90&#160;&#160; 79137ad8&#160;&#160; PreJIT System.Object.GetHashCode()    <br />793424c0&#160;&#160; 79137ae0&#160;&#160; PreJIT System.Object.Finalize()    <br />1ee5802d&#160;&#160; 1ee57e38&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.InitCallbacks()    <br />1ee57f61&#160;&#160; 1ee57cc0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write3_UserReg(System.Object[])    <br />1ee57f65&#160;&#160; 1ee57cc8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write4_UserRegResponse(System.Object[])    <br />1ee57f69&#160;&#160; 1ee57cd0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write5_UserRegSimple(System.Object[])    <br />1ee57f6d&#160;&#160; 1ee57cd8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write6_UserRegSimpleResponse(System.Object[])    <br />1ee57f71&#160;&#160; 1ee57ce0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write7_UserRegPhone(System.Object[])    <br />1ee57f75&#160;&#160; 1ee57ce8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write8_UserRegPhoneResponse(System.Object[])    <br />1ee57f79&#160;&#160; 1ee57cf0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write9_ModifyUserInfo(System.Object[])    <br />1ee57f7d&#160;&#160; 1ee57cf8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write10_ModifyUserInfoResponse(System.Object[])    <br />1ee57f81&#160;&#160; 1ee57d00&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write11_UserLogin(System.Object[])    <br />1ee57f85&#160;&#160; 1ee57d08&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write12_UserLoginResponse(System.Object[])    <br />1ee57f89&#160;&#160; 1ee57d10&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write13_UserLogout(System.Object[])    <br />1ee57f8d&#160;&#160; 1ee57d18&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write14_UserLogoutResponse(System.Object[])    <br />1ee19d80&#160;&#160; 1ee57d20&#160;&#160;&#160;&#160;&#160; JIT Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write15_GetUserInfo(System.Object[])    <br />1ee57f95&#160;&#160; 1ee57d28&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write16_GetUserInfoResponse(System.Object[])    <br />1ee57f99&#160;&#160; 1ee57d30&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write17_FindUser(System.Object[])    <br />1ee57f9d&#160;&#160; 1ee57d38&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write18_FindUserResponse(System.Object[])    <br />1ee57fa1&#160;&#160; 1ee57d40&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write19_FindUserEx(System.Object[])    <br />1ee57fa5&#160;&#160; 1ee57d48&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write20_FindUserExResponse(System.Object[])    <br />1ee57fa9&#160;&#160; 1ee57d50&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write21_ModifyPassword(System.Object[])    <br />1ee57fad&#160;&#160; 1ee57d58&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write22_ModifyPasswordResponse(System.Object[])    <br />1ee57fb1&#160;&#160; 1ee57d60&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write23_ResetPassword(System.Object[])    <br />1ee57fb5&#160;&#160; 1ee57d68&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write24_ResetPasswordResponse(System.Object[])    <br />1ee57fb9&#160;&#160; 1ee57d70&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write25_ModifyPasswordPhone(System.Object[])    <br />1ee57fbd&#160;&#160; 1ee57d78&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write26_ModifyPasswordPhoneResponse(System.Object[])    <br />1ee57fc1&#160;&#160; 1ee57d80&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write27_CheckUserToken(System.Object[])    <br />1ee57fc5&#160;&#160; 1ee57d88&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write28_CheckUserTokenResponse(System.Object[])    <br />1ee57fc9&#160;&#160; 1ee57d90&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write29_SetUserStatus(System.Object[])    <br />1ee57fcd&#160;&#160; 1ee57d98&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write30_SetUserStatusResponse(System.Object[])    <br />1ee57fd1&#160;&#160; 1ee57da0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write31_ActivateUser(System.Object[])    <br />1ee57fd5&#160;&#160; 1ee57da8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write32_ActivateUserResponse(System.Object[])    <br />1ee57fd9&#160;&#160; 1ee57db0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write33_AppActivateUser(System.Object[])    <br />1ee57fdd&#160;&#160; 1ee57db8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write34_AppActivateUserResponse(System.Object[])    <br />1ee57ff1&#160;&#160; 1ee57dc0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write35_GetUserLoginHistory(System.Object[])    <br />1ee57ff5&#160;&#160; 1ee57dc8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write36_GetUserLoginHistoryResponse(System.Object[])    <br />1ee57ff9&#160;&#160; 1ee57dd0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write37_GetUnactiveUserNumber(System.Object[])    <br />1ee57ffd&#160;&#160; 1ee57dd8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write38_GetUnactiveUserNumberResponse(System.Object[])    <br />1ee58001&#160;&#160; 1ee57de0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write39_GetTtlUserNumber(System.Object[])    <br />1ee58005&#160;&#160; 1ee57de8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write40_GetTtlUserNumberResponse(System.Object[])    <br />1ee58009&#160;&#160; 1ee57df0&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write41_GetActiveUserNumber(System.Object[])    <br />1ee5800d&#160;&#160; 1ee57df8&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write42_GetActiveUserNumberResponse(System.Object[])    <br />1ee58011&#160;&#160; 1ee57e00&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write43_DailyRegisterCount(System.Object[])    <br />1ee58015&#160;&#160; 1ee57e08&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write44_DailyRegisterCountResponse(System.Object[])    <br />1ee58019&#160;&#160; 1ee57e10&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write45_GetDailyReport(System.Object[])    <br />1ee5801d&#160;&#160; 1ee57e18&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write46_GetDailyReportResponse(System.Object[])    <br />1ee58021&#160;&#160; 1ee57e20&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write47_Test(System.Object[])    <br />1ee58025&#160;&#160; 1ee57e28&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write48_TestResponse(System.Object[])    <br />1ee19eb8&#160;&#160; 1ee57e30&#160;&#160;&#160;&#160;&#160; JIT Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write2_t_UserInfo(System.String, System.String, t_UserInfo, Boolean, Boolean)    <br />1ee58031&#160;&#160; 1ee57e40&#160;&#160;&#160;&#160; NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap..ctor() </p>
<p>从上面的输出中，就能看到序列化类型的方法。有了这些方法，查找序列化的来源就容易多了。 </p>
<p>有了这些信息后，开发人员很容易地定位到问题跟WCF调用相关。实现WCF的时候选择了XML序列化方法。在下面这个blog的评论中，有人批评WCF XML序列化会导致这样的问题:   <br /><a href="http://blogs.msdn.com/tess/archive/2006/02/15/net-memory-leak-xmlserializing-your-way-to-a-memory-leak.aspx">http://blogs.msdn.com/tess/archive/2006/02/15/net-memory-leak-xmlserializing-your-way-to-a-memory-leak.aspx</a></p>
<p>这个问题在这里已经非常明显了。当然dump中还有其它可以挖掘的地方。比如用!dumpheap &#8211;stat看看CLR object的数量。用!dumpheap &#8211;mt寻找一些序列化object的地址，然后用!gcroot看看序列化object的引用关系。或者用!finalizequeue看看是否堆积了大量的object等待Dispose。由于篇幅的关系，这些细枝末节就不列举了。 </p>
<p>总的说来，!eeheap &#8211;gc隔离问题到loader heap和dynamic module, !dumpmodule &#8211;mt找到引发序列化的类型，!dumpmt &#8211;md找出类型的详细信息。三个命令就可以隔离出问题。   <br />该问题最后通过WCF object pool的方法缓存WCF client proxy，解决问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://panweizeng.com/document/archives/214/feed/</wfw:commentRss>
		</item>
		<item>
		<title>关于JavaScript中apply与call的用法意义及区别</title>
		<link>http://panweizeng.com/document/archives/212</link>
		<comments>http://panweizeng.com/document/archives/212#comments</comments>
		<pubDate>Tue, 15 Jan 2008 08:54:54 +0000</pubDate>
		<dc:creator>弗里曼·潘</dc:creator>
		
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://panweizeng.com/document/archives/212</guid>
		<description><![CDATA[http://www.cnblogs.com/beyondnet/archive/2007/12/06/985216.html
JavaScript中有一个call和apply方法，其作用基本相同，但也有略微的区别。
先来看看JS手册中对call的解释：call 方法调用一个对象的一个方法，以另... ]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cnblogs.com/beyondnet/archive/2007/12/06/985216.html">http://www.cnblogs.com/beyondnet/archive/2007/12/06/985216.html</a></p>
<p>JavaScript中有一个call和apply方法，其作用基本相同，但也有略微的区别。</p>
<p>先来看看JS手册中对call的解释：<br/>call 方法<br/>调用一个对象的一个方法，以另一个对象替换当前对象。</p>
<p>call([thisObj[,arg1[, arg2[, [,.argN]]]]])</p>
<p>参数<br/>thisObj<br/>可选项。将被用作当前对象的对象。</p>
<p>arg1, arg2, , argN<br/>可选项。将被传递方法参数序列。</p>
<p>说明<br/>call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。</p>
<p>如果没有提供 thisObj 参数，那么 Global 对象被用作 thisObj。</p>
<p>说明白一点其实就是更改对象的内部指针，即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。</p>
<p>引用网上一个代码段，运行后自然就明白其道理。<br/>&lt;input type=&#8221;text&#8221; id=&#8221;myText&#8221; value=&#8221;input text&#8221;&gt;<br/>&lt;script&gt;<br/>function Obj(){this.value=&#8221;对象！&#8221;;}<br/>var value=&#8221;global 变量&#8221;;<br/>function Fun1(){alert(this.value);}</p>
<p>window.Fun1(); //global 变量<br/>Fun1.call(window); //global 变量<br/>Fun1.call(document.getElementById(&#8217;myText&#8217;)); //input text<br/>Fun1.call(new Obj()); //对象！<br/>&lt;/script&gt;</p>
<p>call函数和apply方法的第一个参数都是要传入给当前对象的对象，及函数内部的this。后面的参数都是传递给当前对象的参数。<br/>运行如下代码：<br/>&lt;script&gt;<br/>var func=new function(){this.a=&#8221;func&#8221;}<br/>var myfunc=function(x){<br/>var a=&#8221;myfunc&#8221;;<br/>alert(this.a);<br/>alert(x);<br/>}<br/>myfunc.call(func,&#8221;var&#8221;);<br/>&lt;/script&gt;</p>
<p>可见分别弹出了func和var。到这里就对call的每个参数的意义有所了解了。</p>
<p>对于apply和call两者在作用上是相同的，但两者在参数上有区别的。<br/>对于第一个参数意义都一样，但对第二个参数：<br/>apply传入的是一个参数数组，也就是将多个参数组合成为一个数组传入，而call则作为call的参数传入（从第二个参数开始）。<br/>如 func.call(func1,var1,var2,var3)对应的apply写法为：func.apply(func1,[var1,var2,var3])</p>
<p>同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入。</p>
]]></content:encoded>
			<wfw:commentRss>http://panweizeng.com/document/archives/212/feed/</wfw:commentRss>
		</item>
		<item>
		<title>总有一种力量让我们泪流满面</title>
		<link>http://panweizeng.com/document/archives/211</link>
		<comments>http://panweizeng.com/document/archives/211#comments</comments>
		<pubDate>Sun, 13 Jan 2008 06:06:50 +0000</pubDate>
		<dc:creator>弗里曼·潘</dc:creator>
		
		<category><![CDATA[社会]]></category>

		<guid isPermaLink="false">http://panweizeng.com/document/archives/211</guid>
		<description><![CDATA[难忘《南方周末》1999年新年致词：总有一种力量让我们泪流满面这是新年的第一天，这是我们与你见面的第777次。祝愿阳光打在你的脸上。阳光打在你的脸上，温暖留在我们的心里。这是冬天... ]]></description>
			<content:encoded><![CDATA[<p>难忘《南方周末》1999年新年致词：总有一种力量让我们泪流满面<br/><br/>这是新年的第一天，这是我们与你见面的第777次。祝愿阳光打在你的脸上。<br/>阳光打在你的脸上，温暖留在我们的心里。这是冬天里平常的一天。北方的树叶已经落尽，南方的树叶还留在枝上，人们在大街上懒洋洋地走着，或者急匆匆地跑着，每个人都怀着自己的希望，每个人都握紧自己的心事。<br/><br/>没有什么可以轻易把人打动，除了正义的号角。当你面对蒙冤无助的弱者，当你面对专横跋扈的恶人，当你面对足以影响人们一生的社会不公，你就明白正义需要多少代价，正义需要多少勇气。<br/><br/>没有什么可以轻易把人打动，除了内心的爱。没有什么可以轻易把人打动，除了前进的脚步…… 这是新年的第一天，就象平常一样，我们与你再次见面，为逝去的一年而感怀，为新来的一年作准备。祝愿阳光打在你的脸上。<br/><br/>阳光打在你