﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-疯狂-随笔分类-java性能</title><link>http://www.blogjava.net/freeman1984/category/43783.html</link><description>STANDING ON THE SHOULDERS OF GIANTS
</description><language>zh-cn</language><lastBuildDate>Mon, 05 Jun 2017 07:53:49 GMT</lastBuildDate><pubDate>Mon, 05 Jun 2017 07:53:49 GMT</pubDate><ttl>60</ttl><item><title>oracle 索引字段包含date类型，使用spring jdbc更新时不走索引，而是走table access full的问题</title><link>http://www.blogjava.net/freeman1984/archive/2015/11/15/428197.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sat, 14 Nov 2015 16:04:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2015/11/15/428197.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/428197.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2015/11/15/428197.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/428197.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/428197.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: oracle 索引字段包含date类型，使用spring jdbc更新时不走索引，而是走table access full的问题&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2015/11/15/428197.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/428197.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2015-11-15 00:04 <a href="http://www.blogjava.net/freeman1984/archive/2015/11/15/428197.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>A/B测试(转载)</title><link>http://www.blogjava.net/freeman1984/archive/2012/08/28/386419.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Tue, 28 Aug 2012 03:41:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2012/08/28/386419.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/386419.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2012/08/28/386419.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/386419.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/386419.html</trackback:ping><description><![CDATA[<p>A / B测试不是一个时髦名词。现在很多有经验的营销和设计工作者用它来获得访客行为信息，来提高转换率。然而， A / B测试与SEO不同的是，人们都不太知道徒河进行网站分析和可用性分析。他们并不完全明白它是什么或如何更有效的使用它。本文将为你提供有史以来最好的A / B测试教程。</p>
<p><strong>什么是A/B测试?</strong></p>
<p>A / B测试的核心就是：确定两个元素或版本（A和B）哪个版本更好，你需要同时实验两个版本。最后，选择最好的版本使用。</p>
<p><img class="alignnone size-full wp-image-2227" title="ab-testing" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/3063eb0c3e2e6ef65e81e1fee7c885a3.png" width="498" height="381" /></p>
<p>网络上的A / B测试，即你设计的页面有两个版本（A和B），A为现行的设计（称为控制） ， B是新的设计。比较这两个版本之间你所关心的数据（转化率，业绩，跳出率等） 。最后，您选择效果最好的版本。</p>
<p><strong>测试哪些东西?</strong></p>
<p>你要选择什么去测试取决于你的目标。例如，如果你的目标是增加顾客数量，那么您可能测试下列内容：注册表单数量，字段类型要求，隐私政策等。在这种情况下A / B测试的目标是要弄清楚什么阻止了游客注册。需要填写的表单的数量？用户的隐私？还是该网站做了让游客不信任的事情？所有这些问题都可以通过一个个A/B 测试获得答案。</p>
<p>每一个A / B测试内容都是独一无二的，单通常测试一下这些内容：</p>
<ul><li>行动按钮的措辞，大小，颜色和位置，</li><li>标题或产品说明，</li><li>表单的数量和字段类型，</li><li>网站的布局和风格，</li><li>产品定价和促销活动，</li><li>着陆和产品页面上的图片，</li><li>页面上文字的长度（少Vs多）。</li></ul>
<p>一旦你决定要测试什么，下一步当然是要选择一个合适的测试工具。如果你想要一个基础的免费工具，可以使用<a href="http://www.google.com/websiteoptimizer">Google Website Optimizer</a>。如果你想要功能更加强大的工具，可以使用<a href="http://visualwebsiteoptimizer.com/">Visual Website Optimizer</a>&nbsp; 。其他的一些选择都是可以的，建立试验在所有工具中都很相似，所以我们只需讨论一种即可。</p>
<p>你可以通过两种方法建立A / B测试：</p>
<ul><li><strong>在页面测试加载前替换元素</strong><br />如果你测试的是页面上的单个元素，如注册按钮，然后需要在测试工具中设置按钮。当测试时，在A / B工具将在页面给用户前随机替换按钮。</li><li><strong>重定向到另一页面</strong><br />如果你想通过A / B测试整个页面，比如说，一个绿色的主题和一个红色主题，那么你就需要创建和上传新的页面。例如，如果您的主页是 http://www.example.com/index.html，那么你需要创建另外一个页面 http://www.example.com/index1.html。当测试运行时，您的测试工具将一部分访问者重定向到第二个网址。</li></ul>
<p>一旦您使用了上面的两种变换方法，下一步是建立您的转换目标。通常，你会得到一个JavaScript代码，您可以复制并粘贴到一个需要游客到达的目标网页。例如，如果您有一个电子商务网站，你正在测试的&#8220;立即购买&#8220;按钮的颜色，然后您的转换目标将是购买成功后的&#8220;谢谢您&#8220;页面。</p>
<p>在转换事件发生的同时，在A / B测试工具，记录了哪种页面显示给了访问者。经过足够数量的游客，您可以确定哪个页面带来了最多的转化！建立和运行的A / B测试，其实很简单。</p>
<p><strong>该做什么和不该做什么</strong></p>
<p>虽然A / B测试是超级简单的概念，但是请记住，以下这些都只是我自己的经验。</p>
<p><strong>注意事项</strong></p>
<ul><li>不要分开你的测试情况。始终两个版本同时进行测试。如果您第一星期测试第一版本，第二星期测试第二个版本，你就错了。有可能B版本带来的流量更糟糕，但是带来了更好的业绩，因为两个版本之间的流量始终存在不一样。</li><li>不要结束得太早。有一个概念叫做&#8220;统计信心&#8220; ，无论你的测试结果明显的。如果你只有少数转换或游客，它都无法确定最终的结果。大多数A / B测试工具都有报告统计，但如果你是手动测试，你可以使用 <a href="http://visualwebsiteoptimizer.com/ab-split-significance-calculator/">在线计算器</a>。</li><li>不要让常客惊讶。如果你正在测试网站的一部分。包括新访客和常客，不要使他们觉得震惊。尤其不要因为哪些可能不会最终实施变化。</li><li>不要让你的直觉推翻了测试结果。在A / B测试的结果往往是令人惊讶的或直观的。在一个绿色为主题的网站，一个明显的红色按钮有可能成为赢家。即使红色按钮不容易吸引注意。您要测试的目标是一个更好的转换率，而不是美学，所以在得到测试借过钱不要拒绝任何尝试。</li></ul>
<p><strong>需要做的</strong></p>
<ul><li>知道运行测试多久。结束太早，可能会使你花了时间但是没有得到有意义的结果。结束太晚也不好，因为效果不佳的页面可能影响你的转化和业绩。使用一个<a href="http://visualwebsiteoptimizer.com/ab-split-test-duration/">计算器</a>，来确定测试多久以后来结束它。</li><li>将相同的页面呈献给同一个访客。您的工具应该有一个记忆访问者已经看到的页面的功能。这样可以防止向同一用户显示一不同的价格或不同的促销优惠。</li><li>让您的A / B测试在整个网站保持一致。如果你正在测试的登录按钮在多个地点出现，然后一个访问者应在所有的地方看到同样的变化。在页面1显示一个样子，在页面2显示两外一个样子，会使试验结果被干扰。</li><li>做很多的A / B测试。让我们面对现实吧：你的第一个A / B测试可能会无效。但是不要绝望。一个A / B测试只能有三个结果：没有结果，不好的结果和好的结果。优化转换率的关键是要做大量的A / B测试，把所有的好的结果拼接起来，最终推动业绩。</li></ul>
<p><strong>经典A/B测试案例研究</strong></p>
<p>这里有一些如何进行A/B测试的案例研究。</p>
<p><a href="http://37signals.com/svn/posts/1525-writing-decisions-headline-tests-on-the-highrise-signup-page">Writing Decisions: Headline Tests on the Highrise Sign-Up Page</a>&nbsp;37Signals测试他们的价格页面的标题。最终发现， &#8220;30-Day Free Trial on All Accounts &#8220;比原来的&#8220;Start a Highrise Account. &#8220;多产生30 ％以上的订单。</p>
<p><img class="alignnone size-full wp-image-2228" title="hrhq-signuphead-30day60sec" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/66e534c4fe2b5c4e1483f27ffcf4d9d3.png" width="530" height="140" /></p>
<p><a href="http://dustincurtis.com/you_should_follow_me_on_twitter.html">&#8220;You Should Follow Me on Twitter Here&#8221;</a> (Dustin Curtis) 这是一个用来测试召唤用户在Twitter上关注自己的试验。. Dustin 发现提示文字是&#8220;You should follow me on Twitter here&#8221; 的效果是&#8220;I&#8217;m on Twitter.&#8221; 173%</p>
<p><span><img class="alignnone size-full wp-image-2229" title="dustin" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/4a6eb53aa4fd0052d5fc82a45b0f8c7b.png" width="488" height="59" /></span></p>
<p><a href="http://carsonified.com/blog/design/human-photos-double-your-conversion-rate/">Human Photos Double Conversion Rates</a>&nbsp;从两个不同的A / B测试将在网站上增加转换率的人的照片：一个令人令人惊讶的结论，A/B测试两张图片，将真人照片放在网站上会获得一倍的转化。研究说明，我们潜意识被照片吸引了。</p>
<p><img class="alignnone size-full wp-image-2230" title="human" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/7fcea0efd7ae306f97f3aec87097bce8.png" width="415" height="184" /></p>
<p><a href="http://www.fourhourworkweek.com/blog/2009/08/12/google-website-optimizer-case-study/">Google Website Optimizer Case Study: Daily Burn, 20%+ Improvement</a> (Tim Ferriss) 一个将用户选择减少的变化使转化提高了20%，最终的版本在细节和文字上更易吸引目光。</p>
<p><img class="alignnone size-full wp-image-2231" title="gymnii" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/ec7bb024417da83432775f01d6791cc7.jpeg" width="300" height="241" /></p>
<p><a href="http://visualwebsiteoptimizer.com/split-testing-blog/ab-test-case-study-how-two-magical-words-increased-conversion-rate-by-28/">Two Magical Words Increased Conversion Rate by 28%</a>&nbsp;&#8220;It&#8217;s free&#8221; 这个单词增加了注册按钮点击次数的28%, 测试结果表明，在行动召唤上一些很小的变化会带来令人惊讶的结果。</p>
<p><img class="alignnone size-full wp-image-2232" title="its-free-shot" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/3b795b7011cb5afb70c96d2e3f0f9332.png" width="440" height="70" /></p>
<p><a href="http://dmix.ca/2010/05/how-we-increased-our-conversion-rate-by-72/">Changing the Sign-Up Button from Green to Red</a>&nbsp;依靠A / B测试， CareLogger把注册按钮从绿色修改为红色增加了34％转换率！</p>
<p><img class="alignnone size-full wp-image-2233" title="get-started" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/e5668dadf2bd002d01684a1e745ca8a3.png" width="580" height="122" /></p>
<p><a href="http://www.getelastic.com/single-vs-two-page-checkout/">Single page vs. multi-step checkout</a>&nbsp;如果你有一个在线商店，很常见的就是支付流程。这个A / B测试发现，多个支付流程比单个支付流程完成的销售更好。</p>
<p><img class="alignnone size-full wp-image-2234" title="getelastic" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/d3a976fd670d3c1ebe8015d629ad0f3a.jpeg" width="300" height="283" /></p>
<p><a href="http://www.lukew.com/ff/entry.asp?1007">&#8220;Mad Libs&#8221; style form increases conversion 25-40%</a>&nbsp;打败传统的智慧，此A / B测试发现一<em>段风格</em>形式输入字段比传统形式的布局更好。</p>
<p><img class="alignnone size-full wp-image-2235" title="madlibs" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/c7c204f8c987200255542d3678ab8d48.gif" width="558" height="164" /></p>
<p><a href="http://carsonified.com/blog/business/the-business-case-for-ab-testing/">Complete redesign of product page increased sales by 20%</a>&nbsp;一个软件产品的公司重新设计他们的产品页给它一个现代的外观和增加信任模块。最终结果：他们成功地增加20 ％的总销售额。本案例研究证明了设计对销售的影响。</p>
<p><img class="alignnone size-full wp-image-2236" title="aquasoft" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/cbf9c7829abaaef547ac2fe2dbe2e879.png" width="450" height="291" /></p>
<p><a href="http://www.marketingexperiments.com/blog/research-topics/response-capture-case-study.html">Marketing Experiments response capture case study &#8211; triple digit increase in conversions</a>&nbsp;通过优化邮件地址获取提高了258 ％。重点是消除所有的干扰，并要求游客只需提供电子邮件地址。使用亚马逊礼品卡让他/她的完成个人资料。</p>
<p><img class="alignnone size-full wp-image-2237" title="marketing-experiments" alt="" src="http://img.ucdchina.com/upload/snap/2010-07/37b713d6f858ddd9bbd11d594b817b3b.jpeg" width="300" height="225" /></p>
<p><strong>A/B</strong><strong>测试工具</strong></p>
<p>有许多侧重点，价位和功能不同的A / B测试工具，这里是一些：</p>
<ul><li><a href="http://www.google.com/websiteoptimizer">Google Website Optimizer</a><br />搜索巨头提供的免费A/B测试工具。一个很好的入门级工具，但是没有一些先进的功能。</li><li><a href="http://www.bingocardcreator.com/abingo/">A/Bingo</a> and <a href="http://vanity.labnotes.org/">Vanity</a><br />基于Ruby on Rails开发的服务器组件。需要编程和代码集成。</li><li><a href="http://visualwebsiteoptimizer.com/">Visual Website Optimizer</a><br />一个易于使用的A / B测试工具，包含一些先进的功能，如所见即所得的编辑器，单击地图，访问者分割和标签等。</li><li><a href="http://unbounce.com/">Unbounce</a> and <a href="http://performable.com/">Performable</a><br />集成着陆页设计的A / B测试工具。</li><li><a href="http://vertster.com/">Vertster</a>, <a href="http://sitespect.com/">SiteSpect</a>, <a href="http://www.webtrends.com/products/optimize.aspx">Webtrends Optimize</a> and <a href="http://www.omniture.com/en/products/conversion/testandtarget">Omniture&#8217;s Test&amp;Target</a><br />企业级测试工具。</li></ul>
<p><strong>一些深入研究的A/B测试资料</strong></p>
<p>如果你已经读到这里，那么A / B测试大概已经激起你的兴趣。在这里，有一些非常好的A/B测试资源。</p>
<p><strong>寻找你下一个A/B测试的灵感</strong></p>
<ul><li><a href="http://whichtestwon.com/">Which Test Won?</a><br />一个猜测那种情况会最终胜利的游戏。</li><li><a href="http://www.conversion-rate-experts.com/articles/101-google-website-optimizer-tips/">101 A/B Testing Tips</a><br />大量的A/B测试技巧和方法。</li><li><a href="http://abtests.com/">ABtests.com</a><br />一个可以分享和阅读A/B测试结果的地方。</li><li><a href="http://visualwebsiteoptimizer.com/ideafox.php">A/B Ideafox</a><br />搜索引擎的A / B和多变量的案例研究。</li></ul>
<p><strong>一些介绍性文章</strong></p>
<ul><li><a href="http://elem.com/~btilly/effective-ab-testing/">Effective A/B Testing</a><br />By Ben Tilly.</li><li><a href="http://exp-platform.com/Documents/GuideControlledExperiments.pdf">Practical Guide to Controlled Experiments on the Web</a> (PDF)<br />From Microsoft Research.</li><li><a href="http://20bits.com/articles/an-introduction-to-ab-testing/">Introduction to A/B Testing</a><br />From the 20bits blog</li></ul>
<p><strong>A/B</strong><strong>测试中的数学</strong></p>
<ul><li><a href="http://20bits.com/articles/statistical-analysis-and-ab-testing/">Statistics for A/B Testing</a><br />From the 20bits blog.</li><li><a href="http://www.evanmiller.org/how-not-to-run-an-ab-test.html">How Not to Do A/B Testing</a></li><li><a href="http://visualwebsiteoptimizer.com/split-testing-blog/what-you-really-need-to-know-about-mathematics-of-ab-split-testing/">What You Should Know About the Mathematics of A/B Testing</a><br />From my own blog.</li><li><a href="http://blog.asmartbear.com/easy-statistics-for-adwords-ab-testing-and-hamsters.html">Easy Statistics for AdWords A/B Testing, and Hamsters</a></li><li><a href="http://www.cennydd.co.uk/2009/statistical-significance-other-ab-test-pitfalls/">Statistical Significance and Other A/B Test Pitfalls</a></li></ul>
<p>原文地址：<a href="http://www.smashingmagazine.com/2010/06/24/the-ultimate-guide-to-a-b-testing/">http://www.smashingmagazine.com/2010/06/24/the-ultimate-guide-to-a-b-testing/</a><br />转载自：<a href="http://ucdchina.com/snap/7203">http://ucdchina.com/snap/7203</a></p><img src ="http://www.blogjava.net/freeman1984/aggbug/386419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2012-08-28 11:41 <a href="http://www.blogjava.net/freeman1984/archive/2012/08/28/386419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>apache性能测试工具ab</title><link>http://www.blogjava.net/freeman1984/archive/2011/12/13/366235.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Tue, 13 Dec 2011 06:36:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/12/13/366235.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/366235.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/12/13/366235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/366235.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/366235.html</trackback:ping><description><![CDATA[Apache自带的测试工具ab(apache benchmark)在apache的bin目录下。<br />使用格式： ./ab [options] [http://]hostname[:port]/path<br />参数说明：<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -n requests&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Number of requests to perform<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">//在测试会话中所执行的请求个数。默认时，仅执行一个请求</font><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -c concurrency Number of multiple requests to make<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">//一次产生的请求个数。默认是一次一个。</font><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -t timelimit&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Seconds to max. wait for responses<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">//测试所进行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时，没有时间限制。<br /></font>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -p postfile&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> File containing data to POST<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">//包含了需要POST的数据的文件.</font><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -T content-type Content-type header for POSTing<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">//POST数据所使用的Content-type头信息。</font><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -v verbosity&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> How much troubleshooting info to print<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">//设置显示信息的详细程度 - 4或更大值会显示头信息， 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。 -V 显示版本号并退出。<br /></font>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -w&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Print out results in HTML tables<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">//以HTML表的格式输出结果。默认时，它是白色背景的两列宽度的一张表。<br /></font>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -i&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Use HEAD instead of GET<br />&nbsp;<wbr>&nbsp;<wbr> <font color="#ff0000">// 执行HEAD请求，而不是GET。</font><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -x attributes&nbsp;<wbr>&nbsp;<wbr> String to insert as table attributes<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -y attributes&nbsp;<wbr>&nbsp;<wbr> String to insert as tr attributes<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -z attributes&nbsp;<wbr>&nbsp;<wbr> String to insert as td or th attributes<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -C attribute&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Add cookie, eg. 'Apache=1234. (repeatable)<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //<font color="#ff0000">-C cookie-name=value 对请求附加一个Cookie:行。其典型形式是name=value的一个参数对。此参数可以重复。</font><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -H attribute&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Add Arbitrary header line, eg. 'Accept-Encoding: gzip'<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Inserted after all normal header lines. (repeatable)<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -A attribute&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Add Basic WWW Authentication, the attributes<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> are a colon separated username and password.<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -P attribute&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Add Basic Proxy Authentication, the attributes<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> are a colon separated username and password.<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //<font color="#ff0000">-P proxy-auth-username:password 对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开，并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码)，此字符串都会被发送。</font><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -X proxy:port&nbsp;<wbr>&nbsp;<wbr> Proxyserver and port number to use<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -V&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Print version number and exit<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -k&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Use HTTP KeepAlive feature<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -d&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Do not show percentiles served table.<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -S&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Do not show confidence estimators and warnings.<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -g filename&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Output collected data to gnuplot format file.<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -e filename&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Output CSV file with percentages served<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -h&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Display usage information (this message)<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //-attributes 设置 属性的字符串. 缺陷程序中有各种静态声明的固定长度的缓冲区。另外，对命令行参数、服务器的响应头和其他外部输入的解析也很简单，这可能会有不良后果。它没有完整地实现HTTP/1.x; 仅接受某些'预想'的响应格式。 strstr(3)的频繁使用可能会带来性能问题，即, 你可能是在测试ab而不是服务器的性能。 
<p>参数很多,一般我们用 -c 和 -n 参数就可以了. 例如:</p>
<p>./ab -c 1000 -n 1000 <a href="http://10.88.15.77/test.php"><font color="#0000ff">http://10.88.15.77/test.php</font></a></p>
<p>这个表示同时处理1000个请求并运行1000次index.php文件.<br />#ab -c 1000 -n 1000 <a href="http://10.88.15.77/test.php"><font color="#0000ff">http://10.88.15.77/test.php</font></a></p>
<p><br /><font color="#0000ff">Benchmarking 10.88.15.77 (be patient)</font></p>
<p>Completed 100 requests<br />Completed 200 requests<br />Completed 300 requests<br />Completed 400 requests<br />Completed 500 requests<br />Completed 600 requests<br />Completed 700 requests<br />Completed 800 requests<br />Completed 900 requests<br />Finished 1000 requests</p>
<p><br />Server Software:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Apache/2.2.8<br /><font color="#ff0000">//平台apache 版本2.2.8<br /></font>Server Hostname:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 10.88.15.77<br /><font color="#ff0000">//服务器主机名<br /></font>Server Port:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 80<br /><font color="#ff0000">//服务器端口</font></p>
<p>Document Path:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> /test.php</p>
<p><font color="#ff0000">//测试的页面文档</font><br />Document Length:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1018 bytes<br /><font color="#ff0000">//文档大小</font></p>
<p>Concurrency Level:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1000<br /><font color="#ff0000">//并发数<br /></font>Time taken for tests:&nbsp;<wbr>&nbsp;<wbr> 8.188731 seconds<br /><font color="#ff0000">//整个测试持续的时间</font><br />Complete requests:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1000<br /><font color="#ff0000">//完成的请求数量</font><br />Failed requests:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 0<br /><font color="#ff0000">//失败的请求数量</font><br />Write errors:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 0<br /><br />Total transferred:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1361581 bytes<br /><font color="#ff0000">//整个场景中的网络传输量</font><br />HTML transferred:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1055666 bytes<br /><font color="#ff0000">//整个场景中的HTML内容传输量<br /></font>Requests per second:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 122.12 [#/sec] (mean)<br /><font color="#ff0000">//<span style="color: red">大家最关心的指标之一，相当于</span> <span style="color: red">LR</span> <span style="color: red">中的</span> <strong><span style="color: red">每秒事务数</span></strong> <span style="color: red">，后面括号中的</span> <span style="color: red">mean</span> <span style="color: red">表示这是一个平均值</span></font><br />Time per request:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 8188.731 [ms] (mean)<br /><font color="#ff0000">//<span style="color: red">大家最关心的指标之二，相当于</span> <span style="color: red">LR</span> <span style="color: red">中的</span> <strong><span style="color: red">平均事务响应时间</span></strong> <span style="color: red">，后面括号中的</span> <span style="color: red">mean</span> <span style="color: red">表示这是一个平均值</span></font><br />Time per request:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 8.189 [ms] (mean, across all concurrent requests)<br /><font color="#ff0000">//每个请求实际运行时间的平均值</font><br />Transfer rate:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 162.30 [Kbytes/sec] received<br /><font color="#ff0000">//<span style="color: red">平均每秒网络上的流量，可以帮助排除是否存在网络流量过大导致响应时间延长的问题</span></font></p>
<p>Connection Times (ms)<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> min mean[+/-sd] median&nbsp;<wbr>&nbsp;<wbr> max<br />Connect:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 4 646 1078.7&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 89&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 3291<br />Processing:&nbsp;<wbr>&nbsp;<wbr> 165 992 493.1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 938&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 4712<br />Waiting:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 118 934 480.6&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 882&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 4554<br />Total:&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 813 1638 1338.9&nbsp;<wbr>&nbsp;<wbr> 1093&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 7785<br /><font color="#ff0000">//<span style="color: red">网络上消耗的时间的分解，各项数据的具体算法还不是很清楚</span></font></p>
<p>Percentage of the requests served within a certain time (ms)<br />50%&nbsp;<wbr>&nbsp;<wbr> 1093<br />66%&nbsp;<wbr>&nbsp;<wbr> 1247<br />75%&nbsp;<wbr>&nbsp;<wbr> 1373<br />80%&nbsp;<wbr>&nbsp;<wbr> 1493<br />90%&nbsp;<wbr>&nbsp;<wbr> 4061<br />95%&nbsp;<wbr>&nbsp;<wbr> 4398<br />98%&nbsp;<wbr>&nbsp;<wbr> 5608<br />99%&nbsp;<wbr>&nbsp;<wbr> 7368<br />100%&nbsp;<wbr>&nbsp;<wbr> 7785 (longest request)<br /><font color="#ff0000">//整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时间，其中50％的用户响应时间小于1093 毫秒，60％ 的用户响应时间小于1247 毫秒，最大的响应时间小于7785 毫秒</font></p>
<p><font color="#ff0000">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 由于对于并发请求，cpu实际上并不是同时处理的，而是按照每个请求获得的时间片逐个轮转处理的，所以基本上第一个Time per request时间约等于第二个Time per request时间乘以并发请求数<br />转自：<a href="http://blog.sina.com.cn/s/blog_3c9872d00100dbox.html">http://blog.sina.com.cn/s/blog_3c9872d00100dbox.html</a></font></p><img src ="http://www.blogjava.net/freeman1984/aggbug/366235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-12-13 14:36 <a href="http://www.blogjava.net/freeman1984/archive/2011/12/13/366235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>select, iocp, epoll,kqueue及各种I/O复用机制</title><link>http://www.blogjava.net/freeman1984/archive/2011/12/07/365746.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 07 Dec 2011 05:45:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/12/07/365746.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/365746.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/12/07/365746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/365746.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/365746.html</trackback:ping><description><![CDATA[<p><strong>首先，介绍几种常见的I/O模型及其区别</strong>，如下：</p>
<ul><li>
<p>blocking I/O</p></li><li>
<p>nonblocking I/O</p></li><li>
<p>I/O multiplexing (<tt>select</tt> and <tt>poll</tt>)</p></li><li>
<p>signal driven I/O (<tt>SIGIO</tt>)</p></li><li>
<p>asynchronous I/O (the POSIX <tt>aio_</tt>functions)</p></li></ul>
<p><strong>blocking I/O</strong> <br />这个不用多解释吧，阻塞套接字。下图是它调用过程的图示：</p>
<p><img src="http://hi.csdn.net/attachment/201001/28/156467_126466013140tA.jpg"  alt="" /> </p>
<p>重点解释下上图，下面例子都会讲到。首先application调用 recvfrom()转入kernel，注意kernel有2个过程，wait for data和copy data from kernel to user。直到最后copy complete后，recvfrom()才返回。此过程一直是阻塞的。</p>
<p><strong>nonblocking I/O：</strong> <br />与blocking I/O对立的，非阻塞套接字，调用过程图如下：</p>
<p><img src="http://hi.csdn.net/attachment/201001/28/156467_1264660132Vc0H.jpg"  alt="" /> </p>
<p>可以看见，如果直接操作它，那就是个轮询。。直到内核缓冲区有数据。</p>
<p><strong>I/O multiplexing (select and poll)</strong> <br />最常见的I/O复用模型，select。</p>
<p><img src="http://hi.csdn.net/attachment/201001/28/156467_126466013344Mb.jpg"  alt="" /> </p>
<p>select先阻塞，有活动套接字才返回。与<strong>blocking I/O</strong>相比，select会有两次系统调用，但是select能处理多个套接字。</p>
<p><strong>signal driven I/O (SIGIO)</strong> <br />只有UNIX系统支持，感兴趣的课查阅相关资料</p>
<p><img src="http://hi.csdn.net/attachment/201001/28/156467_1264660134r93R.jpg"  alt="" /> </p>
<p>与<strong>I/O multiplexing (select and poll)</strong>相比，它的优势是，免去了select的阻塞与轮询，当有活跃套接字时，由注册的handler处理。</p>
<p><font color="#ff0000"><strong>asynchronous I/O (the POSIX aio_functions)</strong> <br /></font>很少有*nix系统支持，windows的IOCP则是此模型</p>
<p><img src="http://hi.csdn.net/attachment/201001/28/156467_1264660135UGwy.jpg"  alt="" /> </p>
<p>完全异步的I/O复用机制，因为纵观上面其它四种模型，至少都会在由kernel copy data to appliction时阻塞。而该模型是当copy<font color="#ff0000">完成</font>后才通知application，可见是<font color="#ff0000">纯异步</font>的。好像只有windows的<font color="#ff0000">完成端口</font>是这个模型，效率也很出色。</p>
<p><strong>下面是以上五种模型的比较</strong></p>
<p><strong><img src="http://hi.csdn.net/attachment/201001/28/156467_1264660135Ow47.jpg"  alt="" /> </strong></p>
<p>可以看出，越往后，阻塞越少，理论上效率也是最优。</p>
<p>=====================分割线==================================</p>
<p>5种模型的比较比较清晰了，剩下的就是把select,epoll,iocp,kqueue按号入座那就OK了。</p>
<p>select和iocp分别对应第3种与第5种模型，那么epoll与kqueue呢？其实也于select属于同一种模型，只是更高级一些，可以看作有了第4种模型的某些特性，如callback机制。</p>
<p><strong>那么，为什么epoll,kqueue比select高级？ <br /></strong></p>
<p>答案是，他们无<font color="#ff0000"><strong>轮询</strong></font>。因为他们用callback取代了。想想看，当套接字比较多的时候，每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数，当他们活跃时，自动完成相关操作，那就避免了轮询，这正是epoll与kqueue做的。</p>
<p><strong>windows or *nix （IOCP or kqueue/epoll）？</strong></p>
<p>诚然，Windows的IOCP非常出色，目前很少有支持<strong>asynchronous I/O</strong>的系统，但是由于其系统本身的局限性，大型服务器还是在UNIX下。而且正如上面所述，kqueue/epoll 与 IOCP相比，就是多了一层从内核copy数据到应用层的阻塞，从而不能算作<strong>asynchronous I/O类。</strong>但是，这层小小的阻塞无足轻重，kqueue与epoll已经做得很优秀了。</p>
<p><strong>提供一致的接口，IO Design Patterns</strong></p>
<p>实际上，不管是哪种模型，都可以抽象一层出来，提供一致的接口，广为人知的有ACE,Libevent这些，他们都是跨平台的，而且他们自动选择最优的I/O复用机制，用户只需调用接口即可。说到这里又得说说2个设计模式，<strong>Reactor</strong> and <strong>Proactor。</strong>有一篇经典文章<a href="http://www.artima.com/articles/io_design_patterns.html"><font color="#336699">http://www.artima.com/articles/io_design_patterns.html</font></a>值得阅读，Libevent是<strong>Reactor</strong>模型，ACE提供<strong>Proactor</strong>模型。实际都是对各种I/O复用机制的封装。</p>
<p><strong>Java nio包是什么I/O机制？</strong></p>
<p>我曾天真的认为java nio封装的是IOCP。。现在可以确定，目前的java本质是select()模型，可以检查/jre/bin/nio.dll得知。至于java服务器为什么效率还不错。。我也不得而知，可能是设计得比较好吧。。-_-。</p>
<p>=====================分割线==================================</p>
<p><strong><font color="#ff0000">总结一些重点：</font></strong></p>
<ol><li>只有IOCP是asynchronous I/O，其他机制或多或少都会有一点阻塞。 </li><li>select低效是因为每次它都需要轮询。但低效也是相对的，视情况而定，也可通过良好的设计改善 </li><li>epoll, kqueue是Reacor模式，IOCP是Proactor模式。 </li><li>java nio包是select模型。。 </li></ol>
<p>转载自：<a href="http://blog.csdn.net/shallwake/article/details/5265287">http://blog.csdn.net/shallwake/article/details/5265287</a><br /></p><img src ="http://www.blogjava.net/freeman1984/aggbug/365746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-12-07 13:45 <a href="http://www.blogjava.net/freeman1984/archive/2011/12/07/365746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nginx和tomcat负载简单配置(windows环境)</title><link>http://www.blogjava.net/freeman1984/archive/2011/12/07/365726.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 07 Dec 2011 02:40:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/12/07/365726.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/365726.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/12/07/365726.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/365726.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/365726.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: nginx和tomcat负载简单配置(windows环境)&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2011/12/07/365726.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/365726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-12-07 10:40 <a href="http://www.blogjava.net/freeman1984/archive/2011/12/07/365726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>高性能JavaScript(来自高性能JavaScript一书)</title><link>http://www.blogjava.net/freeman1984/archive/2011/10/09/360260.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sun, 09 Oct 2011 03:56:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/10/09/360260.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/360260.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/10/09/360260.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/360260.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/360260.html</trackback:ping><description><![CDATA[<h1 class="postTitle"><a id="ctl02_TitleUrl" class="postTitle2" href="http://www.cnblogs.com/pansly/archive/2011/06/29/2093769.html"><font color="#1a8bc8">高性能JavaScript</font></a></h1>
<div id="cnblogs_post_body">
<p>一下内容是转载的，内容应该出自高性能JavaScript一书中，此书值得一读。<br /><br />学习过程中写的笔记，有误请指正。</p>
<p>性能并不是唯一的考虑因素，在对性能要求并非苛刻的环境中，性能也可让位于：团队编码规范，个人编码习惯，代码可读性，模块可扩展性等因素。</p>
<p>以下提到的对性能的优化，仅仅提供了从性能的角度去阐释一些设计思路，但实际上，浏览器本身会逐步优化自身的性能问题，而我们那些提高性能的hack，可能会因为浏览器的版本更新，导致成为一种无用的hack，甚至让性能更慢，所以不要无谓的使用一些hack，去优化一些执行次数很少的代码，而降低代码的可读性，或增加代码量，，一句话：如非必要，请勿hack。</p>
<p><strong>一 javascript加载和执行</strong></p>
<p>1 无论是外链还是内联，script标签都会阻塞页面的渲染，所以script标签的位置最好是&lt;/body&gt;前<br />2 减少http请求，合并多个script文件为一个，1个90k的文件比3个30k的文件载入速度要快<br />3 如何不阻塞页面，而载入一个脚本呢：<br />1）给script标签加defer属性：&lt;script src=&#8221;xxx&#8221; defer&gt;&lt;/script&gt;，这样不会使页面执行过程阻塞，但并不是所有浏览器都支持这个defer属性<br />2）xmlHttpRequest来请求脚本内容并eval，虽然这样可以灵活的控制脚本下载过程 及 何时执行，但不能跨域是个硬伤<br />3）createElement(&#8216;script&#8217;)然后append是个不错的方案，无阻塞，有onload用onload，IE没有就用onreadystatechange实现加载完成的事件，注意readyState属性的值是complete或者loaded都要执行回调函数并清除onreadystatechange，因为这两个状态值不稳定。</p>
<p>4 所以推荐的方式是第三种：在载入js-loader部分的少量代码后，就用loader去加载其他js吧，注意一些市面上流行的库如labjs实现了这些功能(广告下：<a href="http://www.qwrap.com/" target="_blank"><font color="#1a8bc8">qwrap实现了依赖管理及动态加载</font></a>)</p>
<p><strong>二 数据访问</strong><br />数据存储在：直接量，变量，数组元素，对象成员中。<br />这又让我想起了编译型的语言，直接量存在于pe文件的.rdata段中，变量在调用栈上，数组元素和对象成员的访问需要基址+偏移量来定位，多层对象嵌套需要多次计算基址+偏移量来定位。</p>
<p>这些在javascript中依然没有太大变化：</p>
<p>1 直接量的访问无疑是迅速的</p>
<p>2 变量的访问需要考虑javascript允许函数进行嵌套定义，也就形成了基于函数定义的作用域链，而变量的访问，可能需要跨作用域来访问，所以这里有一点性能损失，但先进的js引擎用空间换时间（猜测在子作用域中缓存了所有父层作用域链上变量的name和地址，所以不会进行上溯作用域链，直接执行hash定位即可，但一个函数中如果包含eval,with,catch块的话，通过静态代码分析就没办法知道该函数中声明了哪些变量，也就无法做到这个优化），，不过，从性能上来看，与我的实际测试，大家编码的时候不需要注意这种性能考虑，按团队编码规范和个人编码习惯来吧。</p>
<p>3 对象成员的访问要考虑上溯原型链，所以理论上来说访问实例本身上的成员比访问原型的成员速度要快。</p>
<p>4 多层对象的嵌套要慢，但是在对性能要求并非很苛刻的环境中不用关心这些。</p>
<p><strong>三 dom编程</strong></p>
<p>1 dom的访问和修改<br />1) 标准dom方式(createElement,createTextNode,appendChild) 和 字符串拼接后设置innerHTML 之间的性能相差无几，各个浏览器不同<br />2) 节点克隆速度快一些，先用createElement创建好需要用到的元素类型后，以后在循环中调用元素的cloneNode来克隆<br />3) getElementsByName,getElementsByClassName,getElementsByTagName以及.images,.links,.forms属性返回的都是html集合，是个类数组，没有数组的方法，但提供了length属性和索引器，，HTML集合处于&#8220;实时状态&#8221;，底层文档对象更新时后自动更新javascript中的集合，访问length时候也会去查询，所以遍历集合时候要缓存length来提高效率<br />4) 遍历集合前记录length，循环体中避免对集合中某相同元素进行多次索引，一次索引到局部变量中，因为对html集合的索引性能很差，特别在某些老浏览器中<br />5) 遍历dom节点的话，综合来说使用nextSibling性能会比childNodes快一点，如果只遍历element的话，children被所有浏览器支持，所以尽量用children而不要用childNodes再自行筛选，其他的如childElementCount,firstElementChild,lastElementChild,nextElementSibling,previousElementSibling不被全面支持，注意做特性检测及兼容处理<br />6) 注意所使用的类库是否支持原生的querySelectorAll优先规则，querySelectorAll返回NodeList而不会返回HTML集合，不存在实时文档结构的性能问题</p>
<p>2 重绘和重排</p>
<p>改变dom节点的几何属性会引起重排(reflow)，而后发生重绘(repaint)。</p>
<p>由于重排需要产生大量的计算，所以浏览器一般会通过队列化修改并批量执行来优化重排，获取最新布局信息的操作会导致强制触发队列的执行，如获取offsetTop,scrollTop,clientTop或调用getComputedStyle方法(currentStyle in IE)的时候，要返回诸如此类的最新的布局信息的时候，浏览器就会立即渲染队列中的变化，触发重排，然后返回正确的值。</p>
<p>由于动作的队列是基于页面的，所以，即使你获取的最新布局信息的节点没有待执行的动作，也会触发重排。</p>
<p>所以，尽量将修改元素样式的操作放在一起，然后再执行获取元素最新布局信息的操作，尽量不要交叉进行，因为每次获取元素的最新布局信息，都将触发重排和重绘操作。</p>
<p>虽然，现代浏览器进行了优化，并不会在每次设置元素的样式或改变dom的结构时都会重绘和重排，，但旧版浏览器仍会有性能问题，所以尽量用以下规则来最小化重绘和重排：<br />1） 设置样式：使用cssText属性来合并更新的样式信息： el.style.cssText=&#8221;padding-left:10px;border:1px&#8221;<br />2） 改变dom结构：将元素脱离文档流，然后进行一系列改变，然后再带回文档流中，方法如下：<br />(1) 隐藏元素，对元素的dom结构进行一系列更改，再显示元素<br />(2) 使用createDocumentFragment创建文档碎片，针对文档碎片进行批量操作，然后一次性添加到文档中<br />(3) 将原始元素clone到一个脱离文档流的节点中，修改这个副本后，替换原始元素<br />3） 缓存布局信息<br />尽量减少布局信息的获取次数，如果有针对布局信息的迭代操作，先将布局信息保存到局部变量中，对该局部变量进行迭代更新，然后将该局部变量更新到dom上<br />4） 动画效果时脱离文档流<br />&nbsp; 一个元素进行动画效果时：<br />(1) 将该元素脱离文档流，比如绝对定位该元素<br />(2) 对该元素进行动画操作，这样不会触发其他区域的重排和重绘<br />(3) 动画结束时，将元素恢复文档流位置，这样只会对其余区域进行一次重排和重绘</p>
<p>3 使用事件委托来减少dom树上的事件响应函数<br />对文档中大量的元素进行事件绑定会导致运行时效率下降，基于事件都会冒泡到父层，可以在父层上绑定一个事件，然后识别target(srcElement)来自行dispatch事件。</p>
<p><strong>四 算法和流程控制</strong><br />1 循环<br />1) while,for,do-while性能上基本没差别，不过while和do-while一般被用于基于某个条件的循环，而for用于数组的迭代或线性的工作，而for-in用于对象的枚举<br />2）减少循环次数或减少循环中的工作量都可以优化性能，如duff循环，但性能提升微乎其微，实际测试，在某些浏览器下duff循环不仅不会提升性能，还会降低性能，另外倒序循环可能会快一些，毕竟正序是与长度进行对比后的boolean值，而倒序循环是将表示当前循环进度的数值转换为boolean<br />3) 迭代器如js1.6的forEach方法等，性能比用for进行循环要慢一些，但更语义化<br />附(我写的一个duff循环的js版本)</p>
<div class="hl-surround">
<ol class="hl-main ln-show" title="Double click to hide line number."><li class="hl-firstline"><span style="color: #ffa500">//注:duff的原理是减少循环次数，从而减少对循环条件的判断，所以duff的性能优化只对超大数组(10万次条件判断会降低为10万/8次条件判断)有意义，与循环体中的语句数量无关，所以，duff只适用于循环体执行速度非常快，而循环规模非常大的状况，在js中只有略微的性能提升</span></li><li><span style="color: green">function</span><span style="color: gray"> </span><span style="color: blue">duff</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: gray">,</span><span style="color: blue">callback</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">i</span><span style="color: gray"> = </span><span style="color: blue">list</span><span style="color: gray">.</span><span style="color: blue">length</span><span style="color: gray"> % </span><span style="color: maroon">8</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">tails</span><span style="color: gray"> = </span><span style="color: blue">i</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">while</span><span style="color: olive">(</span><span style="color: blue">i</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">callback</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: gray">--</span><span style="color: blue">i</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray"></span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">greatest_factor</span><span style="color: gray"> = </span><span style="color: blue">list</span><span style="color: gray">.</span><span style="color: blue">length</span><span style="color: gray">-</span><span style="color: maroon">1</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">do</span><span style="color: olive">{</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: gray">-</span><span style="color: maroon">1</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: gray">-</span><span style="color: maroon">2</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: gray">-</span><span style="color: maroon">3</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: gray">-</span><span style="color: maroon">4</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: gray">-</span><span style="color: maroon">5</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: gray">-</span><span style="color: maroon">6</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">process</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: olive">[</span><span style="color: blue">greatest_factor</span><span style="color: gray">-</span><span style="color: maroon">7</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">greatest_factor</span><span style="color: gray">-=</span><span style="color: maroon">8</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span><span style="color: green">while</span><span style="color: olive">(</span><span style="color: blue">greatest_factor</span><span style="color: gray">&gt;</span><span style="color: blue">tails</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: olive">}</span> </li></ol></div>
<p>2 条件语句<br />1)switch比if-else快一些，但性能微乎其微，建议在数量较多的分支时使用switch，而进行范围判断或多重条件的时候使用if-else<br />2)if-else的排列从大概率向小概率<br />3)如果条件太多，建议使用查找表，而且查找表具有动态扩充的能力<br />3 递归<br />1) 由于调用栈的限制，递归是很危险的<br />2) 非自调用，而是交叉调用形成的&#8220;隐伏递归&#8221;是很危险的，出错之后很难排错<br />3) 尽量将递归转化为迭代，比如树的遍历，用非递归的dfs,bfs来实现就好<br />4) 很常用的函数，进行memoize,用空间换取时间</p>
<p><strong>五 字符串和正则表达式</strong></p>
<p>1 理解各个浏览器的js引擎字符串合并的内部机制：<br />1) 避免产生临时字符串，如用str+=&#8217;abc&#8217;;str+=&#8217;def&#8217;&nbsp; 而不要用 str+=&#8217;abc&#8217;+'def&#8217;<br />2) firefox会在编译期合并字符串常量，如str+= &#8216;abc&#8217;+'def&#8217;会被转化为str+=&#8217;abcdef&#8217;，yur-compressor也有这个功能<br />3) 数组的join方法，性能不会比+连接符更快，因为大多数浏览器的+连接符不会开辟新内存空间，而ie7,ie6却会开辟新空间，所以ie6,7中字符串连接应该用数组的join，而其他浏览器用+连接符，，concat方法是最慢的方式</p>
<p>2 正则表达式优化<br />基于各js引擎中正则表达式引擎的不同，以下某些方法会带来某引擎性能的提升但可能同样导致其他引擎性能的下降，所以原书原文也只是原理性阐述，实际开发时视具体情况而定。<br />1) 循环中使用的正则对象尽量在循环前初始化，并赋予一个变量<br />2) 编写正则表达式时，尽量考虑较少的回溯，比如编写分支时将大概率分支放在前面，在贪婪模式是从尾部向前回溯，懒惰模式从headPart向尾部逐字符回溯<br />3) 关于回溯失控，起因是太宽泛的匹配模式，如最后的part没能成功匹配，则会记住回溯位置，尝试修改前面的part的匹配方式，如尝试让前面的懒惰模式包含一次endPart，然后从新位置再尝试匹配，正则引擎会一直尝试，最终导致回溯失控<br />4) 在只是搜索确定的字面量，及字面量位置也确定如行首，行尾等，正则非最佳工具<br />(详细的正则优化先略过，等以后再回来写吧)</p>
<p><strong>六 快速响应用户界面</strong></p>
<p>1 浏览器UI线程和UI队列<br />UIThread:javascript和ui是共用同一个线程的，这样做的好处是无需考虑运行时的用户态或核心态的线程同步，也无需在语言层面实现临界区(critical section)，在我最初自己摸索javascript的时候，认为javascript也是多线程的，后来写代码测试后发现，javascript并非多线程，且javascript代码的执行会阻塞和ui共用的这唯一的线程，使用户的操作得不到ui的反馈。</p>
<p>UIQueue:上面的UIThread负责执行UIQueue中的task，无论用户对UI采取的动作触发的dom事件响应函数，还是javascript执行过程中用setTimeout或setInterval创建的定时器事件响应函数，都会被插入到UIQueue中，当UIThread处于busy状态时，可能会忽略掉一些task，不置入UIQueue，比如用户动作的产生的ui更新task和触发的dom-event两者，ui更新的task会被忽略不放入UIQueue，而dom-event会放入UIQueue等待UIThread处于idle状态时执行，而setInterval函数的周期性定时器事件，会视UIQueue中是否有相同的事件响应函数，如没有才会将该task置入UIQueue。<br />UIQueue的task来源：<br />1) 用户操作产生的ui更新重绘<br />2) 用户操作触发的绑定在dom上的javascript事件<br />3) dom节点自身状态改变触发的绑定在自身上的javascript事件，如<img  alt="" />的onload<br />4) setTimeout与setInterval设置的定时器事件<br />5) ajax过程中的onreadystatechange事件，这个javascript函数并非绑定在dom上，而是绑定在xmlHttpRequest对象上</p>
<p>浏览器限制：为了避免某个javascript事件函数执行时间过长，一直占据UIThread，从而导致用户操作触发的UIUpdate任务得不到执行，各个浏览器使用不同的方案限制了单个javascript事件函数的执行时间<br />1) ie:500万条，在注册表有设置<br />2) firefox: 10秒，在浏览器配置设置中(about:config-&gt;dom.max_script_run_time)<br />3) safari: 5秒，无法修改<br />4) chrome: 依赖通用崩溃检测系统<br />5) opera: 无</p>
<p>界面多久无反应会让用户无法忍受： <strong>最长100毫秒</strong>，用户的动作之后超过100毫秒界面没有做出响应，用户就会认为自己和界面失去了联系。</p>
<p>2 用定时器让出时间片断(分解任务)<br />任务分解过程：用户无法忍受一个10秒的任务占据UI线程，而自己的任何操作得不到反馈，于是我们可以将这个10秒的任务分为200次50毫秒的任务，每执行50毫秒，让出UI线程去执行UI队列中的界面更新的任务，让用户及时得到反馈，然后再执行50毫秒，直到执行完毕。<br />基于大多数长时间UI任务都是对数组的循环操作，于是我们可以将这个循环过程进行拆解，示例代码：</p>
<div class="hl-surround">
<ol class="hl-main ln-show" title="Double click to hide line number."><li class="hl-firstline"><span style="color: green">function</span><span style="color: gray"> </span><span style="color: blue">timedProcessArray</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: gray">, </span><span style="color: blue">callback</span><span style="color: gray">, </span><span style="color: blue">complete</span><span style="color: gray">, </span><span style="color: blue">progress</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">total</span><span style="color: gray"> = </span><span style="color: blue">list</span><span style="color: gray">.</span><span style="color: blue">length</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">curProgress</span><span style="color: gray"> = </span><span style="color: maroon">0</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">preProgress</span><span style="color: gray"> = </span><span style="color: maroon">0</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">(</span><span style="color: green">function</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: gray">, </span><span style="color: blue">iteration</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">fn</span><span style="color: gray"> = </span><span style="color: blue">arguments</span><span style="color: gray">.</span><span style="color: blue">callee</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">st</span><span style="color: gray"> = +</span><span style="color: green">new</span><span style="color: gray"> </span><span style="color: teal">Date</span><span style="color: olive">()</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">while</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: gray">.</span><span style="color: blue">length</span><span style="color: gray"> &amp;&amp; </span><span style="color: olive">(</span><span style="color: gray">+</span><span style="color: green">new</span><span style="color: gray"> </span><span style="color: teal">Date</span><span style="color: olive">()</span><span style="color: gray"> - </span><span style="color: blue">st</span><span style="color: gray"> &lt; </span><span style="color: maroon">50</span><span style="color: olive">)</span><span style="color: gray"> </span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">iteration</span><span style="color: gray"> = </span><span style="color: blue">callback</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: gray">.</span><span style="color: blue">shift</span><span style="color: olive">()</span><span style="color: gray">, </span><span style="color: blue">iteration</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">if</span><span style="color: olive">(</span><span style="color: blue">list</span><span style="color: gray">.</span><span style="color: blue">length</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">if</span><span style="color: olive">(</span><span style="color: blue">progress</span><span style="color: olive">){</span><span style="color: gray"> </span><span style="color: #ffa500">//如果需要对进度进行通知)</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">curProgress</span><span style="color: gray"> = </span><span style="color: maroon">100</span><span style="color: gray"> - </span><span style="color: olive">(</span><span style="color: maroon">100</span><span style="color: gray"> </span><span style="color: #8b0000">/</span><span style="color: red"> total * list.length ^ 0);</span></li><li><span style="color: red"></span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(curProgress != preProgress){</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; preProgress = curProgress;</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; progress(curProgress);</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setTimeout(function(){</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fn.call(null, list, iteration);</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, 25);</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }else{</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; progress &amp;&amp; progress(100);</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; complete &amp;&amp; complete(iteration);</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp; })(list.concat(),0);</span></li><li><span style="color: red">&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: red">}</span> </li></ol></div>
<p>阻塞和非阻塞(任务分割)方式的示例，:<a href="http://lichaosoft.net/case/progress.html" target="_blank"><font color="#1a8bc8">http://lichaosoft.net/case/progress.html</font></a></p>
<p>3 web-workers<br />在web-workers之前，javascript是没有多线程的，web-workers标准带来了真正的多线程，web-workers本来是html5的一部分，现在已经分离出去成为独立的规范：http://www.w3.org/TR/workers/</p>
<p>和web-workers之间仅能通过onmessage和postMessage交互。</p>
<p>使用web-workers以辅助线程进行计算并拥有进度通知的示例：<br /><a href="http://lichaosoft.net/case/worker.html" target="_blank"><font color="#1a8bc8">http://lichaosoft.net/case/worker.html</font></a>（请使用支持web-workers的chrome或safari浏览）</p>
<p>web-workers适用于那些无法拆解的任务，对数组的遍历是一个可以被拆解的任务，对树的遍历通过使用dfs或bfs将树平坦化为数组后也可以进行拆解，不能拆解的任务:<br />1) 编码/解码大字符串<br />2) 复杂数学运算<br />3) 大数组排序</p>
<p>超过100毫秒的任务，如浏览器支持web-workers，优先使用web-workers，如不支持则使用timedProcessArray进行分割运行。</p>
<p>没有任何javascript代码的重要度高于用户体验，用户体验是至高重要的，无论如何不能让用户觉得界面反应速度慢。</p>
<p><strong>七 AJAX</strong><br />从广义上来看，AJAX是指不重载整个页面的情况下，与服务端进行数据传输，解析数据，并局部刷新页面区域的改善用户体验的行为，那么我们下面介绍：数据传输，数据格式。</p>
<p>1 数据传输<br />1) XHR: 创建一个XMLHttpRequest对象与服务端通信<br />2) 动态脚本注入: 这是一个hack，创建一个script元素并设置src为任意uri-A(可跨域)，可在页面中先定义一个数据处理函数如function newsListProc(list){}，然后在该uri-A指向的script文件中调用newsListProc并将数据传入，这项技术也称为：JSON-P。<br />3) mXHR: 将多个资源文件使用XHR传输到浏览器端，js负责对数据流分割，然后dispath给不同类型资源文件的处理函数<br />4) 流式XHR: 在支持readyState为3时，可访问已解析好的部分xhr数据，既是支持流式XHR，可进行流式处理来优化执行效率，目前实际测试ff3.6支持，而ie6,7,8及chrome都不支持流式XHR。<br />5) iframes: 待续<br />6) comet: 待续</p>
<p>注1：关于mXHR和流式XHR，我写了一个demo用来演示多资源文件合并，由XHR向客户端传输，并在支持流式XHR的浏览器中使用流式XHR，DEMO地址：</p>
<p>注2：纯粹的发送数据而无需接受数据，可用beacons方式，类似动态脚本注入，不过创建的不是script元素，而是Image对象，并设置src为要请求的URI，所以这种方式只能使用GET方式，代码示例:</p>
<div class="hl-surround">
<ol class="hl-main ln-show" title="Double click to hide line number."><li class="hl-firstline"><span style="color: green">function</span><span style="color: gray"> </span><span style="color: blue">keepalive</span><span style="color: olive">(</span><span style="color: blue">uri</span><span style="color: gray">, </span><span style="color: blue">delay</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">beacon</span><span style="color: gray">, </span><span style="color: blue">delay</span><span style="color: gray"> = </span><span style="color: blue">delay</span><span style="color: gray"> || </span><span style="color: maroon">1000</span><span style="color: gray">,</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">timer</span><span style="color: gray"> = </span><span style="color: blue">setTimeout</span><span style="color: olive">(</span><span style="color: green">function</span><span style="color: olive">(){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">fn</span><span style="color: gray"> = </span><span style="color: blue">arguments</span><span style="color: gray">.</span><span style="color: blue">callee</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">beacon</span><span style="color: gray"> = </span><span style="color: green">new</span><span style="color: gray"> </span><span style="color: teal">Image</span><span style="color: olive">()</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">beacon</span><span style="color: gray">.</span><span style="color: blue">onload</span><span style="color: gray"> = </span><span style="color: blue">beacon</span><span style="color: gray">.</span><span style="color: blue">onerror</span><span style="color: gray"> = </span><span style="color: green">function</span><span style="color: olive">(){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">timer</span><span style="color: gray"> = </span><span style="color: blue">setTimeout</span><span style="color: olive">(</span><span style="color: blue">fn</span><span style="color: gray">, </span><span style="color: blue">delay</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">beacon</span><span style="color: gray">.</span><span style="color: blue">src</span><span style="color: gray"> = </span><span style="color: blue">uri</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span><span style="color: gray">, </span><span style="color: blue">delay</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">return</span><span style="color: gray"> </span><span style="color: green">function</span><span style="color: olive">(){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">console</span><span style="color: gray">.</span><span style="color: blue">log</span><span style="color: olive">(</span><span style="color: #8b0000">'</span><span style="color: red">stop</span><span style="color: #8b0000">'</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">clearTimeout</span><span style="color: olive">(</span><span style="color: blue">timer</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span><span style="color: gray">;</span></li><li><span style="color: olive">}</span> </li></ol></div>
<p>2 数据格式<br />1) XML: 使用responseXML对象的getElementsByTagName,getElementById,node.getAttribute等api对xml文档进行解析，也可以用XPath进行解析，性能更好些，硬伤是：<br />(1) &#8220;结构/数据&#8221;比 太高<br />(2) XPath在支持并不广泛<br />(3) 最重要的就是需要先知道内容的详细结构，针对每个数据结构编写特定的解析方法<br />2) JSON: 最广泛的数据格式，解析性能较之xml高，&#8221;结构/数据&#8221;比低，如使用缩略属性名或完全使用多层数组格式，结构数据比更低，传输性能更高<br />3) JSON-P: 无需解析，属于javascript的正常函数调用，性能最高<br />4) HTML: 无需解析，服务端已构造好用于局部更新的html数据，直接用innerHTML更新，数据结构比太高，压力被集中在服务端，网络传输数据量高<br />5) 自定义分隔符: 性能最高，结构数据比最低，对于性能要求比较苛刻的环境中使用</p>
<p>附:创建xhr对象的代码：</p>
<div class="hl-surround">
<ol class="hl-main ln-show" title="Double click to hide line number."><li class="hl-firstline"><span style="color: green">function</span><span style="color: gray"> </span><span style="color: blue">createXhrObject</span><span style="color: olive">(){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">if</span><span style="color: olive">(</span><span style="color: teal">window</span><span style="color: gray">.</span><span style="color: blue">XMLHttpRequest</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">return</span><span style="color: gray"> </span><span style="color: green">new</span><span style="color: gray"> </span><span style="color: blue">XMLHttpRequest</span><span style="color: olive">()</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span><span style="color: green">else</span><span style="color: olive">{</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">msxml_progid</span><span style="color: gray"> = </span><span style="color: olive">[</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #8b0000">'</span><span style="color: red">MSXML2.XMLHTTP.6.0</span><span style="color: #8b0000">'</span><span style="color: gray">, </span><span style="color: #ffa500">//支持readyState的3状态，但此状态时读取responseText为空，觉得似乎没意义。。</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #8b0000">'</span><span style="color: red">MSXML3.XMLHTTP</span><span style="color: #8b0000">'</span><span style="color: gray">,</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #8b0000">'</span><span style="color: red">Microsoft.XMLHTTP</span><span style="color: #8b0000">'</span><span style="color: gray">,</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #8b0000">'</span><span style="color: red">MSXML2.XMLHTTP.3.0</span><span style="color: #8b0000">'</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">]</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">req</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">for</span><span style="color: olive">(</span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">i</span><span style="color: gray">=</span><span style="color: maroon">0</span><span style="color: gray">;</span><span style="color: blue">i</span><span style="color: gray">&lt;</span><span style="color: blue">msxml_progid</span><span style="color: gray">.</span><span style="color: blue">length</span><span style="color: gray">;</span><span style="color: blue">i</span><span style="color: gray">++</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">try</span><span style="color: olive">{</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">req</span><span style="color: gray"> = </span><span style="color: green">new</span><span style="color: gray"> </span><span style="color: blue">ActiveXObject</span><span style="color: olive">(</span><span style="color: blue">msxml_progid</span><span style="color: olive">[</span><span style="color: blue">i</span><span style="color: olive">])</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">break</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span><span style="color: green">catch</span><span style="color: olive">(</span><span style="color: blue">ex</span><span style="color: olive">){}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">return</span><span style="color: gray"> </span><span style="color: blue">req</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: olive">}</span> </li></ol></div>
<p>从字符流中异步解析数据的工具类</p>
<div class="hl-surround">
<ol class="hl-main ln-show" title="Double click to hide line number."><li class="hl-firstline"><span style="color: #ffa500">/* </span></li><li><span style="color: #ffa500">* @method StringStreamParser 流式字符串异步解析类</span></li><li><span style="color: #ffa500">* @param onRow 解析出数据行的回调函数</span></li><li><span style="color: #ffa500">* @param RowSeperator 行分隔符,默认'u0001'</span></li><li><span style="color: #ffa500">* @param ColSeperator 列分隔符,默认'u0002'</span></li><li><span style="color: #ffa500">*/</span></li><li><span style="color: green">function</span><span style="color: gray"> </span><span style="color: blue">StringStreamParser</span><span style="color: olive">(</span><span style="color: blue">onRow</span><span style="color: gray">, </span><span style="color: blue">rowSeperator</span><span style="color: gray">, </span><span style="color: blue">colSeperator</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">if</span><span style="color: gray"> </span><span style="color: olive">(</span><span style="color: gray">!</span><span style="color: olive">(</span><span style="color: green">this</span><span style="color: gray"> </span><span style="color: green">instanceof</span><span style="color: gray"> </span><span style="color: blue">arguments</span><span style="color: gray">.</span><span style="color: blue">callee</span><span style="color: olive">)){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">return</span><span style="color: gray"> </span><span style="color: green">new</span><span style="color: gray"> </span><span style="color: blue">arguments</span><span style="color: gray">.</span><span style="color: blue">callee</span><span style="color: olive">(</span><span style="color: blue">onRow</span><span style="color: gray">, </span><span style="color: blue">rowSeperator</span><span style="color: gray">, </span><span style="color: blue">colSeperator</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray"></span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">stream</span><span style="color: gray"> = </span><span style="color: #8b0000">''</span><span style="color: gray">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">rowSeperator</span><span style="color: gray"> = </span><span style="color: blue">rowSeperator</span><span style="color: gray"> || </span><span style="color: #8b0000">'</span><span style="color: red">u0001</span><span style="color: #8b0000">'</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">colSeperator</span><span style="color: gray"> = </span><span style="color: blue">colSeperator</span><span style="color: gray"> || </span><span style="color: #8b0000">'</span><span style="color: red">u0002</span><span style="color: #8b0000">'</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: #ffa500">/* @method write 向字符流写入包</span></li><li><span style="color: #ffa500">&nbsp;&nbsp;&nbsp;&nbsp; * @param packet 写入的包</span></li><li><span style="color: #ffa500">&nbsp;&nbsp;&nbsp;&nbsp; * @param lastPacket 是否为最后一个包，默认false</span></li><li><span style="color: #ffa500">&nbsp;&nbsp;&nbsp;&nbsp; */</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: green">this</span><span style="color: gray">.</span><span style="color: blue">write</span><span style="color: gray"> = </span><span style="color: green">function</span><span style="color: olive">(</span><span style="color: blue">packet</span><span style="color: gray">, </span><span style="color: blue">lastPacket</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">stream</span><span style="color: gray"> += </span><span style="color: blue">packet</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">rowIdx</span><span style="color: gray"> = </span><span style="color: blue">stream</span><span style="color: gray">.</span><span style="color: blue">indexOf</span><span style="color: olive">(</span><span style="color: blue">rowSeperator</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">var</span><span style="color: gray"> </span><span style="color: blue">colIdx</span><span style="color: gray">,</span><span style="color: blue">strRow</span><span style="color: gray">, </span><span style="color: blue">dataRow</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">while</span><span style="color: olive">(</span><span style="color: blue">rowIdx</span><span style="color: gray">!==-</span><span style="color: maroon">1</span><span style="color: gray"> || </span><span style="color: blue">lastPacket</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">if</span><span style="color: olive">(</span><span style="color: blue">rowIdx</span><span style="color: gray">===-</span><span style="color: maroon">1</span><span style="color: olive">){</span><span style="color: gray">&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">strRow</span><span style="color: gray"> = </span><span style="color: blue">stream</span><span style="color: gray">.</span><span style="color: blue">substr</span><span style="color: olive">(</span><span style="color: maroon">0</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">lastPacket</span><span style="color: gray"> = </span><span style="color: green">false</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span><span style="color: green">else</span><span style="color: olive">{</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">strRow</span><span style="color: gray"> = </span><span style="color: blue">stream</span><span style="color: gray">.</span><span style="color: blue">substr</span><span style="color: olive">(</span><span style="color: maroon">0</span><span style="color: gray">,</span><span style="color: blue">rowIdx</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">stream</span><span style="color: gray"> = </span><span style="color: blue">stream</span><span style="color: gray">.</span><span style="color: blue">substr</span><span style="color: olive">(</span><span style="color: blue">rowIdx</span><span style="color: gray">+</span><span style="color: maroon">1</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">rowIdx</span><span style="color: gray"> = </span><span style="color: blue">stream</span><span style="color: gray">.</span><span style="color: blue">indexOf</span><span style="color: olive">(</span><span style="color: blue">rowSeperator</span><span style="color: olive">)</span><span style="color: gray">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">dataRow</span><span style="color: gray"> = </span><span style="color: olive">[]</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">while</span><span style="color: olive">(</span><span style="color: blue">colIdx</span><span style="color: gray"> = </span><span style="color: blue">strRow</span><span style="color: gray">.</span><span style="color: blue">indexOf</span><span style="color: olive">(</span><span style="color: blue">colSeperator</span><span style="color: olive">)){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">if</span><span style="color: olive">(</span><span style="color: blue">colIdx</span><span style="color: gray"> !== -</span><span style="color: maroon">1</span><span style="color: olive">){</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">dataRow</span><span style="color: gray">.</span><span style="color: blue">push</span><span style="color: olive">(</span><span style="color: blue">strRow</span><span style="color: gray">.</span><span style="color: blue">substr</span><span style="color: olive">(</span><span style="color: maroon">0</span><span style="color: gray">, </span><span style="color: blue">colIdx</span><span style="color: olive">))</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">strRow</span><span style="color: gray"> = </span><span style="color: blue">strRow</span><span style="color: gray">.</span><span style="color: blue">substr</span><span style="color: olive">(</span><span style="color: blue">colIdx</span><span style="color: gray">+</span><span style="color: maroon">1</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span><span style="color: green">else</span><span style="color: olive">{</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">dataRow</span><span style="color: gray">.</span><span style="color: blue">push</span><span style="color: olive">(</span><span style="color: blue">strRow</span><span style="color: gray">.</span><span style="color: blue">substr</span><span style="color: olive">(</span><span style="color: maroon">0</span><span style="color: olive">))</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: green">break</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">onRow</span><span style="color: gray">.</span><span style="color: blue">call</span><span style="color: olive">(</span><span style="color: green">null</span><span style="color: gray">, </span><span style="color: blue">dataRow</span><span style="color: olive">)</span><span style="color: gray">;</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: gray">&nbsp;&nbsp;&nbsp; </span><span style="color: olive">}</span></li><li><span style="color: olive">}</span> </li></ol></div>
<p>3 其他<br />在确定了合适的数据传输技术，和数据传输格式之后，还可以采取以下方式酌情优化ajax:<br />1) 缓存数据: 最快的请求，是不请求，有以下两种方式缓存:<br />&nbsp; (1) 对于GET请求，在response中，设置expires头信息，浏览器即会将此请求缓存，这种缓存是跨会话也是跨页面的<br />(2) 在javascript中，以url作为唯一标识符缓存请求到的数据，无法跨页面也无法跨会话，但可编程控制缓存过程（不能跨会话也不能跨页面，这种缓存基本上是无意义的）<br />2) 在必要的时候，直接使用XHR对象而非ajax库，如需要流式的数据处理</p>
<p>八 常见编码中的性能提高点<br />1 避免双重求值: eval,Function,setTimeout和setInterval都允许传入字符串，而此时会创建一个新的编译器的实例，将会导致很大的性能损失。(另外这些方式执行代码时，代码的作用域在各个浏览器也不尽相同，容易掉坑)<br />2 使用Object/Array的直接量进行定义(且直接量比new Object()然后设置属性更节省代码)<br />3 不要让代码重复运行<br />1) 延迟定义</p>
<div class="hl-surround">
<ol class="hl-main ln-show" title="Double click to hide line number."><li class="hl-firstline"></li></ol></div>
<p>2) 条件预定义<br />4 尽量使用原生javascript<br />转载自：<a href="http://www.cnblogs.com/pansly/archive/2011/06/29/2093769.html">http://www.cnblogs.com/pansly/archive/2011/06/29/2093769.html</a></p></div><script type="text/javascript">
if ($ != jQuery) {
	$ = jQuery.noConflict();
}
var isLogined = false;
var cb_blogId = 78100;
var cb_entryId = 2093769;
var cb_blogApp = "pansly";
var cb_blogUserGuid = "3bd23d3f-827b-df11-ba8f-001cf0cd104b";
var cb_entryCreatedDate = '2011/6/29 21:16:00';
</script><img src ="http://www.blogjava.net/freeman1984/aggbug/360260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-10-09 11:56 <a href="http://www.blogjava.net/freeman1984/archive/2011/10/09/360260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载一篇文章oracle的一些操作</title><link>http://www.blogjava.net/freeman1984/archive/2011/08/03/355643.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 03 Aug 2011 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/08/03/355643.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/355643.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/08/03/355643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/355643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/355643.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自:&nbsp;http://renjie120.iteye.com/ 注意:数据库版本是10g,不过大部分9i的也适用,闪回9i就没有. &nbsp;1.曾经不小心把开发库的数据库表全部删除，当时吓的要死。结果找到下面的语句恢复到了1个小时之前的数据！很简单。注意使用管理员登录系统：select * from 表名 as of timestamp sysdate-1/12&...&nbsp;&nbsp;<a href='http://www.blogjava.net/freeman1984/archive/2011/08/03/355643.html'>阅读全文</a><img src ="http://www.blogjava.net/freeman1984/aggbug/355643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-08-03 10:33 <a href="http://www.blogjava.net/freeman1984/archive/2011/08/03/355643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>过v$sqlarea,v$sql查询最占用资源的查询</title><link>http://www.blogjava.net/freeman1984/archive/2011/08/03/355634.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 03 Aug 2011 01:47:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/08/03/355634.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/355634.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/08/03/355634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/355634.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/355634.html</trackback:ping><description><![CDATA[<div><span style="color: #0000ff">从V$SQLAREA中查询最占用资源的查询</span></div>
<div>select b.username username,a.disk_reads reads,<br />&nbsp;&nbsp;&nbsp;&nbsp;a.executions exec,a.disk_reads/decode(a.executions,0,1,a.executions) rds_exec_ratio,<br />&nbsp;&nbsp;&nbsp;&nbsp;a.sql_text Statement<br />from &nbsp;v$sqlarea a,dba_users b<br />where a.parsing_user_id=b.user_id<br />&nbsp;and a.disk_reads &gt; 100000<br />order by a.disk_reads desc;</div>
<div>用buffer_gets列来替换disk_reads列可以得到占用最多内存的sql语句的相关信息。</div>
<div>&nbsp;</div>
<div>V$SQL是内存共享SQL区域中已经解析的SQL语句。</div>
<div><br /><span style="color: #0000ff">列出使用频率最高的5个查询：</span> </div>
<div>select sql_text,executions<br />from (select sql_text,executions,<br />&nbsp;&nbsp;&nbsp;rank() over<br />&nbsp;&nbsp;&nbsp;&nbsp;(order by executions desc) exec_rank<br />&nbsp;&nbsp;&nbsp;from v$sql)<br />where exec_rank &lt;=5;</div>
<div><span style="color: #0000ff">消耗磁盘读取最多的sql top5：<br /></span>select disk_reads,sql_text<br />from (select sql_text,disk_reads,<br />&nbsp;&nbsp;&nbsp;dense_rank() over<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(order by disk_reads desc) disk_reads_rank<br />&nbsp;&nbsp;&nbsp;from v$sql)<br />where disk_reads_rank &lt;=5;</div>
<div><br /><span style="color: #0000ff">找出需要大量缓冲读取（逻辑读）操作的查询：</span> </div>
<div>select buffer_gets,sql_text<br />from (select sql_text,buffer_gets,<br />&nbsp;&nbsp;&nbsp;dense_rank() over<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(order by buffer_gets desc) buffer_gets_rank<br />&nbsp;&nbsp;&nbsp;from v$sql)<br />where buffer_gets_rank&lt;=5;</div><img src ="http://www.blogjava.net/freeman1984/aggbug/355634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-08-03 09:47 <a href="http://www.blogjava.net/freeman1984/archive/2011/08/03/355634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JVM内存模型以及垃圾回收</title><link>http://www.blogjava.net/freeman1984/archive/2011/03/08/345929.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Tue, 08 Mar 2011 05:16:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/03/08/345929.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/345929.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/03/08/345929.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/345929.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/345929.html</trackback:ping><description><![CDATA[<p>JVM内存模型以及垃圾回收<br />
内存由 Perm 和 Heap 组成. 其中</p>
<p>Heap = {Old + NEW = { Eden , from, to } }<br />
具体可查看javavisualvm<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/freeman1984/vmvusual.JPG" /></p>
<p>JVM内存模型中分两大块，一块是 NEW Generation, 另一块是Old Generation. 在New Generation中，有一个叫Eden的空间，主要是用来存放新生的对象，还有两个Survivor Spaces（from,to）, 它们用来存放每次垃圾回收后存活下来的对象。在Old Generation中，主要存放应用程序中生命周期长的内存对象，还有个Permanent Generation，主要用来放JVM自己的反射对象，比如类对象和方法对象等。 <br />
&nbsp;</p>
<p>垃圾回收描述：</p>
<p><br />
在New Generation块中，垃圾回收一般用Copying的算法，速度快。每次GC的时候，存活下来的对象首先由Eden拷贝到某个Survivor Space, 当Survivor Space空间满了后, 剩下的live对象就被直接拷贝到Old Generation中去。因此，每次GC后，Eden内存块会被清空。在Old Generation块中，垃圾回收一般用mark-compact的算法，速度慢些，但减少内存要求.<br />
垃圾回收分多级，0级为全部(Full)的垃圾回收，会回收OLD段中的垃圾；1级或以上为部分垃圾回收，只会回收NEW中的垃圾，内存溢出通常发生于OLD段或Perm段垃圾回收后，仍然无内存空间容纳新的Java对象的情况。</p>
<p>当一个URL被访问时，内存申请过程如下：<br />
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域<br />
B. 当Eden空间足够时，内存申请结束。否则到下一步<br />
C. JVM试图释放在Eden中所有不活跃的对象（这属于1或更高级的垃圾回收）, 释放后若Eden空间仍然不足以放入新对象，则试图将部分Eden中活跃对象放入Survivor区<br />
D. Survivor区被用来作为Eden及OLD的中间交换区域，当OLD区空间足够时，Survivor区的对象会被移到Old区，否则会被保留在Survivor区<br />
E. 当OLD区空间不够时，JVM会在OLD区进行完全的垃圾收集（0级）<br />
F. 完全垃圾收集后，若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象，导致JVM无法在Eden区为新对象创建内存区域，则出现&#8221;out of memory错误&#8221;</p>
<p>JVM调优建议:</p>
<p>ms/mx：定义YOUNG+OLD段的总尺寸，ms为JVM启动时YOUNG+OLD的内存大小；mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同，以减少运行期间系统在内存申请上所花的开销。<br />
NewSize/MaxNewSize：定义YOUNG段的尺寸，NewSize为JVM启动时YOUNG的内存大小；MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同，以减少运行期间系统在内存申请上所花的开销。<br />
PermSize/MaxPermSize：定义Perm段的尺寸，PermSize为JVM启动时Perm的内存大小；MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同，以减少运行期间系统在内存申请上所花的开销。<br />
SurvivorRatio：设置Survivor空间和Eden空间的比例</p>
<p>内存溢出的可能性</p>
<p>1. OLD段溢出<br />
这种内存溢出是最常见的情况之一，产生的原因可能是：<br />
1) 设置的内存参数过小(ms/mx, NewSize/MaxNewSize)<br />
2) 程序问题<br />
单个程序持续进行消耗内存的处理，如循环几千次的字符串处理，对字符串处理应建议使用StringBuffer。此时不会报内存溢出错，却会使系统持续垃圾收集，无法处理其它请求，相关问题程序可通过Thread Dump获取（见系统问题诊断一章）单个程序所申请内存过大，有的程序会申请几十乃至几百兆内存，此时JVM也会因无法申请到资源而出现内存溢出，对此首先要找到相关功能，然后交予程序员修改，要找到相关程序，必须在Apache日志中寻找。<br />
当Java对象使用完毕后，其所引用的对象却没有销毁，使得JVM认为他还是活跃的对象而不进行回收，这样累计占用了大量内存而无法释放。由于目前市面上还没有对系统影响小的内存分析工具，故此时只能和程序员一起定位。</p>
<p><br />
2. Perm段溢出<br />
通常由于Perm段装载了大量的Servlet类而导致溢出，目前的解决办法：<br />
1) 将PermSize扩大，一般256M能够满足要求<br />
2) 若别无选择，则只能将servlet的路径加到CLASSPATH中，但一般不建议这么处理</p>
<p>3. C Heap溢出<br />
系统对C Heap没有限制，故C Heap发生问题时，Java进程所占内存会持续增长，直到占用所有可用系统内存</p>
<p>其他：</p>
<p>JVM有2个GC线程。第一个线程负责回收Heap的Young区。第二个线程在Heap不足时，遍历Heap，将Young 区升级为Older区。Older区的大小等于-Xmx减去-Xmn，不能将-Xms的值设的过大，因为第二个线程被迫运行会降低JVM的性能。</p>
<p>为什么一些程序频繁发生GC？有如下原因：<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 程序内调用了System.gc()或Runtime.gc()。<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一些中间件软件调用自己的GC方法，此时需要设置参数禁止这些GC。<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java的Heap太小，一般默认的Heap值都很小。<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 频繁实例化对象，Release对象。此时尽量保存并重用对象，例如使用StringBuffer()和String()。<br />
如果你发现每次GC后，Heap的剩余空间会是总空间的50%，这表示你的Heap处于健康状态。许多Server端的Java程序每次GC后最好能有65%的剩余空间。<br />
经验之谈：<br />
1．Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC，最好让-Xmn值约等于-Xmx的1/3[2]。 <br />
2．一个GUI程序最好是每10到20秒间运行一次GC，每次在半秒之内完成[2]。 <br />
注意：<br />
1．增加Heap的大小虽然会降低GC的频率，但也增加了每次GC的时间。并且GC运行时，所有的用户线程将暂停，也就是GC期间，Java应用程序不做任何工作。<br />
2．Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值，因为Java为其他任务分配内存，例如每个线程的Stack等。<br />
2．Stack的设定<br />
每个线程都有他自己的Stack。</p>
<p>-Xss 每个线程的Stack大小 </p>
<p>Stack的大小限制着线程的数量。如果Stack过大就好导致内存溢漏。-Xss参数决定Stack大小，例如-Xss1024K。如果Stack太小，也会导致Stack溢漏。<br />
3．硬件环境<br />
硬件环境也影响GC的效率，例如机器的种类，内存，swap空间，和CPU的数量。<br />
如果你的程序需要频繁创建很多transient对象，会导致JVM频繁GC。这种情况你可以增加机器的内存，来减少Swap空间的使用[2]。<br />
4．4种GC<br />
第一种为单线程GC，也是默认的GC。，该GC适用于单CPU机器。<br />
第二种为Throughput GC，是多线程的GC，适用于多CPU，使用大量线程的程序。第二种GC与第一种GC相似，不同在于GC在收集Young区是多线程的，但在Old区和第一种一样，仍然采用单线程。-XX:+UseParallelGC参数启动该GC。<br />
第三种为Concurrent Low Pause GC，类似于第一种，适用于多CPU，并要求缩短因GC造成程序停滞的时间。这种GC可以在Old区的回收同时，运行应用程序。-XX:+UseConcMarkSweepGC参数启动该GC。<br />
第四种为Incremental Low Pause GC，适用于要求缩短因GC造成程序停滞的时间。这种GC可以在Young区回收的同时，回收一部分Old区对象。-Xincgc参数启动该GC。</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/345929.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-03-08 13:16 <a href="http://www.blogjava.net/freeman1984/archive/2011/03/08/345929.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>提高AJAX客户端响应速度(转载)</title><link>http://www.blogjava.net/freeman1984/archive/2011/02/11/344056.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Fri, 11 Feb 2011 07:23:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2011/02/11/344056.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/344056.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2011/02/11/344056.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/344056.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/344056.html</trackback:ping><description><![CDATA[&nbsp;
<h1 style="text-align: left" align="left"><span style="font-family: 宋体">提高</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">客户端响应速度</span></h1>
<p>(<span style="font-family: 宋体">文：包一磊</span>)</p>
<p style="text-align: left; margin: 15.6pt 0cm" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">的出现极大的改变了</span><span style="font-family: 'Verdana', 'sans-serif'">Web</span><span style="font-family: 宋体">应用客户端的操作模式，它使的用户可以在全心工作时不必频繁的忍受那令人厌恶的页面刷新。理论上</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">技术在很大的程度上可以减少用户操作的等待时间，同时节约网络上的数据流量。而然，实际情况却并不总是这样。用户时常会抱怨用了</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">的系统响应速度反而降低了。</span></p>
<p style="text-align: left; margin: 15.6pt 0cm" class="MsoNormal" align="left"><span style="font-family: 宋体">笔者从事</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">方面的研发多年，参与开发了目前国内较为成熟的</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">平台</span><span style="font-family: 'Verdana', 'sans-serif'">-dorado</span><span style="font-family: 宋体">。根据笔者的经验，导致这种结果的根本原因并不在</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">。很多时候系统响应速度的降低都是由不够合理的界面设计和不够高效的编程习惯造成的。下面我们就来分析几个</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">开发过程中需要时刻注意的环节。</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 42pt; tab-stops: list 42.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">n&nbsp;</span><span style="font-family: 宋体">合理的使用客户端编程和远程过程调用。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">客户端的编程主要都是基于</span><span style="font-family: 'Verdana', 'sans-serif'">JavaScript</span><span style="font-family: 宋体">的。而</span><span style="font-family: 'Verdana', 'sans-serif'">JavaScript</span><span style="font-family: 宋体">是一种解释型的编程语言，它的运行效率相对于</span><span style="font-family: 'Verdana', 'sans-serif'">Java</span><span style="font-family: 宋体">等都要稍逊一筹。同时</span><span style="font-family: 'Verdana', 'sans-serif'">JavaScript</span><span style="font-family: 宋体">又是运行在浏览器这样一个严格受限的环境当中。因此开发人员对于哪些逻辑可以在客户端执行应该有一个清醒的认识。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">在实际的应用中究竟应该怎样使用</span><span style="font-family: 宋体">客户端编程，这依赖于开发人员的经验判断。这里很多问题是只可意会的。由于篇幅有限，在这里我们大致归纳出下面这几个注意事项：</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 63pt; tab-stops: list 63.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">u&nbsp;</span><span style="font-family: 宋体">尽可能避免频繁的使用远程过程调用，例如避免在循环体中使用远程过程调用。</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 63pt; tab-stops: list 63.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">u&nbsp;</span><span style="font-family: 宋体">如果可能的话尽可能使用</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">方式的远程过程调用（异步方式的远程过程调用）。</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 63pt; tab-stops: list 63.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">u&nbsp;</span><span style="font-family: 宋体">避免将重量级的数据操作放置在</span><span style="font-family: 宋体">客户端。例如：大批量的数据复制操作、需要通过大量的数据遍历完成的计算等。</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 42pt; tab-stops: list 42.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">n&nbsp;</span><span style="font-family: 宋体">改进对</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">对象的操作方式。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">客户端的编程中，对</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">对象的操作往往是最容易占用</span><span style="font-family: 'Verdana', 'sans-serif'">CPU</span><span style="font-family: 宋体">时间的。而对于</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">对象的操作，不同的编程方法之间的性能差异又往往是非常大的。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">以下是三段运行结果完全相同的代码，它们的作用是在网页中创建一个</span><span style="font-family: 'Verdana', 'sans-serif'">10x1000</span><span style="font-family: 宋体">的表格。然而它们的运行速度却有着天壤之别。</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">测试代码</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">1 - </span><span style="font-family: 宋体; font-size: 9pt">耗时</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">: 41</span><span style="font-family: 宋体; font-size: 9pt">秒</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">*/</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var table = document.createElement("TABLE");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">document.body.appendChild(table);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">for(var i = 0; i &lt; 1000; i++){</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;var row = table.insertRow(-1);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;for(var j = 0; j &lt; 10; j++){</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp; var cell = objRow.insertCell(-1);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp; cell.innerText = "( " + i + " , " + j + " )";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">测试代码</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">2 - </span><span style="font-family: 宋体; font-size: 9pt">耗时</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">: 7.6</span><span style="font-family: 宋体; font-size: 9pt">秒</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> */</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var table = document.getElementById("TABLE");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">document.body.appendChild(table);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var tbody = document.createElement("TBODY");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">table.appendChild(tbody);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">for(var i = 0; i &lt; 1000; i++){</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;var row = document.createElement("TR");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;tbody.appendChild(row);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;for(var j = 0; j &lt; 10; j++){</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp; var cell = document.createElement("TD");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp; row.appendChild(cell);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp; cell.innerText = "( " + i + " , " + j + " )";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">测试代码</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">3 - </span><span style="font-family: 宋体; font-size: 9pt">耗时</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">: 1.26</span><span style="font-family: 宋体; font-size: 9pt">秒</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> */</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var tbody = document.createElement("TBODY");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">for(var i = 0; i &lt; 1000; i++){&nbsp;&nbsp; </span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;var row = document.createElement("TR");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(var j = 0; j &lt; 10; j++){</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp; var cell = document.createElement("TD");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp; cell.innerText = "( " + i + " , " + j + " )";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp; row.appendChild(cell);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;tbody.appendChild(row);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var table = document.getElementById("TABLE");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">table.appendChild(tbody); </span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">document.body.appendChild(table);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">这里的&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">1</span><span style="font-family: 宋体">&#8221;和&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">2</span><span style="font-family: 宋体">&#8221;之间的差别在于在创建表格单元时使用了不同的</span><span style="font-family: 'Verdana', 'sans-serif'">API</span><span style="font-family: 宋体">方法。而&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">2</span><span style="font-family: 宋体">&#8221;和&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">3</span><span style="font-family: 宋体">&#8221;</span><span style="font-family: 宋体">之间的差别在于处理顺序的略微不同。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">1</span><span style="font-family: 宋体">&#8221;和&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">2</span><span style="font-family: 宋体">&#8221;之间如此大的性能差别我们无从分析，目前所知的是</span><span style="font-family: 'Verdana', 'sans-serif'">insertRow</span><span style="font-family: 宋体">和</span><span style="font-family: 'Verdana', 'sans-serif'">insertCell</span><span style="font-family: 宋体">是</span><span style="font-family: 'Verdana', 'sans-serif'">DHTML</span><span style="font-family: 宋体">中表格特有的</span><span style="font-family: 'Verdana', 'sans-serif'">API</span><span style="font-family: 宋体">，</span><span style="font-family: 'Verdana', 'sans-serif'">createElement</span><span style="font-family: 宋体">和</span><span style="font-family: 'Verdana', 'sans-serif'">appendChild</span><span style="font-family: 宋体">是</span><span style="font-family: 'Verdana', 'sans-serif'">W3C DOM</span><span style="font-family: 宋体">的原生</span><span style="font-family: 'Verdana', 'sans-serif'">API</span><span style="font-family: 宋体">。而前者应该是对后者的封装。不过，我们并不能因此而得出结论认为</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">的原生</span><span style="font-family: 'Verdana', 'sans-serif'">API</span><span style="font-family: 宋体">总是优于对象特有的</span><span style="font-family: 'Verdana', 'sans-serif'">API</span><span style="font-family: 宋体">。建议大家在需要频繁调用某一</span><span style="font-family: 'Verdana', 'sans-serif'">API</span><span style="font-family: 宋体">时，对其性能表现做一些基本的测试。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">2</span><span style="font-family: 宋体">&#8221;和&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">3</span><span style="font-family: 宋体">&#8221;之间的性能差异主要来自于他们的构建顺序不同。&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">2</span><span style="font-family: 宋体">&#8221;的做法是首先创建最外层的</span><span style="font-family: 'Verdana', 'sans-serif'">&lt;TABLE&gt;</span><span style="font-family: 宋体">对象，然后再在循环中依次创建</span><span style="font-family: 'Verdana', 'sans-serif'">&lt;TR&gt;</span><span style="font-family: 宋体">和</span><span style="font-family: 'Verdana', 'sans-serif'">&lt;TD&gt;</span><span style="font-family: 宋体">。而&#8220;测试代码</span><span style="font-family: 'Verdana', 'sans-serif'">3</span><span style="font-family: 宋体">&#8221;的做法是首先在内存中由内到外的构建好整个表格，最后再将它添加到网页中。这样做的目的是尽可能的减少浏览器重新计算页面布局的次数。每当我们将一个对象添加到网页中时，浏览器都会尝试对页面中的控件的布局进行重新计算。所以，<span style="color: blue">如果我们能够首先在内存中将整个要构造的对象全部创建好，然后再一次性的添加到网页中。那么，浏览器将只会做一次布局的重计算</span>。总结为一句话那就是越晚执行</span><span style="font-family: 'Verdana', 'sans-serif'">appendChild</span><span style="font-family: 宋体">越好。有时为了提高运行效率，我们甚至可以考虑先使用</span><span style="font-family: 'Verdana', 'sans-serif'">removeChild</span><span style="font-family: 宋体">将已存在的控件从页面中移除，然后构造完成后再重新将其放置回页面当中。</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 42pt; tab-stops: list 42.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">n&nbsp;</span><span style="font-family: 宋体">提高字符串累加的速度</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">在使用</span><span style="font-family: 'Verdana', 'sans-serif'">AJAX</span><span style="font-family: 宋体">提交信息时，我可能常常需要拼装一些比较大的字符串通过</span><span style="font-family: 'Verdana', 'sans-serif'">XmlHttp</span><span style="font-family: 宋体">来完成</span><span style="font-family: 'Verdana', 'sans-serif'">POST</span><span style="font-family: 宋体">提交。尽管提交这样大的信息的做法看起来并不优雅，但有时我们可能不得不面对这样的需求。那么</span><span style="font-family: 'Verdana', 'sans-serif'">JavaScript</span><span style="font-family: 宋体">中对字符串的累加速度如何呢？我们先来做下面的这个实验。累加一个长度为</span><span style="font-family: 'Verdana', 'sans-serif'">30000</span><span style="font-family: 宋体">的字符串。</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">测试代码</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">1 - </span><span style="font-family: 宋体; font-size: 9pt">耗时</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">: 14.325</span><span style="font-family: 宋体; font-size: 9pt">秒</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> */</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var str = "";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">for (var i = 0; i &lt; 50000; i++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str += "xxxxxx";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">这段代码耗时</span><span style="font-family: 'Verdana', 'sans-serif'">14.325</span><span style="font-family: 宋体">秒，结果并不理想。现在我们将代码改为如下的形式：</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">测试代码</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">2 - </span><span style="font-family: 宋体; font-size: 9pt">耗时</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">: 0.359</span><span style="font-family: 宋体; font-size: 9pt">秒</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> */</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var str = "";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">for (var i = 0; i &lt; 100; i++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var sub = "";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var j = 0; j &lt; 500; j++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub += "xxxxxx";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str += sub;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">这段代码耗时</span><span style="font-family: 'Verdana', 'sans-serif'">0.359</span><span style="font-family: 宋体">秒！同样的结果，我们做的只是首先拼装一些较小的字符串然后再组装成更大的字符串。这种做法可以有效的在字符串拼装的后期减小内存复制的数据量。知道了这一原理之后我们还可以把上面的代码进一步拆散以后进行测试。下面的代码仅耗时</span><span style="font-family: 'Verdana', 'sans-serif'">0.140</span><span style="font-family: 宋体">秒。</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">测试代码</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">3 - </span><span style="font-family: 宋体; font-size: 9pt">耗时</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">: 0.140</span><span style="font-family: 宋体; font-size: 9pt">秒</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> */</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var str = "";&nbsp;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">for (var i1 = 0; i1 &lt; 5; i1++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var str1 = "";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i2 = 0; i2 &lt; 10; i2++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var str2 = "";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i3 = 0; i3 &lt; 10; i3++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var str3 = "";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i4 = 0; i4 &lt; 10; i4++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var str4 = "";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i5 = 0; i5 &lt; 10; i5++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str4 += "xxxxxx";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str3 += str4;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str2 += str3;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str1 += str2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str += str1;&nbsp;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">不过，上面这种做法也许并不是最好的！如果我们需要提交的信息是</span><span style="font-family: 'Verdana', 'sans-serif'">XML</span><span style="font-family: 宋体">格式的（其实绝大多数情况下，我们都可以设法将要提交的信息组装成</span><span style="font-family: 'Verdana', 'sans-serif'">XML</span><span style="font-family: 宋体">格式），我们还能找到更高效更优雅的方法</span>—<span style="font-family: 宋体">利用</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">对象为我们组装字符串。下面这段代买组装一个长度为</span><span style="font-family: 'Verdana', 'sans-serif'">950015</span><span style="font-family: 宋体">的字符串仅须耗时</span><span style="font-family: 'Verdana', 'sans-serif'">0.890</span><span style="font-family: 宋体">秒。</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">利用</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">DOM</span><span style="font-family: 宋体; font-size: 9pt">对象组装信息</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> - </span><span style="font-family: 宋体; font-size: 9pt">耗时</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">: 0.890</span><span style="font-family: 宋体; font-size: 9pt">秒</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> */</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var xmlDoc;&nbsp;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">if (browserType == BROWSER_IE) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlDoc = new ActiveXObject("Msxml.DOMDocument");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">else {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlDoc = document.createElement("DOM");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var root = xmlDoc.createElement("root");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">for (var i = 0; i &lt; 50000; i++) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var node = xmlDoc.createElement("data");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (browserType == BROWSER_IE) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; node.text = "xxxxxx";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; node.innerText = "xxxxxx";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root.appendChild(node);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">xmlDoc.appendChild(root);</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">var str;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">if (browserType == BROWSER_IE) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str = xmlDoc.xml;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">else {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str = xmlDoc.innerHTML;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 42pt; tab-stops: list 42.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">n&nbsp;</span><span style="font-family: 宋体">避免</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">对象的内存泄漏。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">关于</span><span style="font-family: 'Verdana', 'sans-serif'">IE</span><span style="font-family: 宋体">中</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">对象的内存泄露是一个常常被开发人员忽略的问题。然而它带来的后果却是非常严重的！它会导致</span><span style="font-family: 'Verdana', 'sans-serif'">IE</span><span style="font-family: 宋体">的内存占用量持续上升，并且浏览器的整体运行速度明显下降。对于一些泄露比较严重的网页，甚至只要刷新几次，运行速度就会降低一倍。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">比较常见的内存泄漏的模型有&#8220;</span><span style="font-family: 'Verdana', 'sans-serif'"><a href="http://birdshome.cnblogs.com/archive/2006/05/28/IE_MemoryLeak.html"><span style="font-family: 宋体; color: windowtext; text-decoration: none; text-underline: none">循环引用</span></a></span><span style="font-family: 宋体">模型&#8221;、&#8220;</span><span style="font-family: 'Verdana', 'sans-serif'"><a href="http://birdshome.cnblogs.com/archive/2006/06/01/ClosureReferences.html"><span style="font-family: 宋体; color: windowtext; text-decoration: none; text-underline: none">闭包函数</span></a></span><span style="font-family: 宋体">模型&#8221;和&#8220;</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">插入顺序模型&#8221;</span><span style="font-family: 'Verdana', 'sans-serif'">,</span><span style="font-family: 宋体">对于前两种泄漏模型，我们都可以通过在网页析构时解除引用的方式来避免。而对于&#8220;</span><span style="font-family: 'Verdana', 'sans-serif'">DOM</span><span style="font-family: 宋体">插入顺序模型&#8221;则需要通过改变一些惯有的编程习惯的方式来避免。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">有关内存泄漏的模型的更多介绍可以通过</span><span style="font-family: 'Verdana', 'sans-serif'">Google</span><span style="font-family: 宋体">很快的查到，本文不做过多的阐述。不过，这里我向您推荐一个可用于查找和分析网页内存泄露的小工具</span>—<span style="font-family: 'Verdana', 'sans-serif'">Drip</span><span style="font-family: 宋体">，目前的较新版本是</span><span style="font-family: 'Verdana', 'sans-serif'">0.5</span><span style="font-family: 宋体">，下载地址是</span><span style="font-family: 'Verdana', 'sans-serif'">http://outofhanwell.com/ieleak/index.php</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 42pt; tab-stops: list 42.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">n&nbsp;</span><span style="font-family: 宋体">复杂页面的分段装载和初始化</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">对系统当中某些确实比较复杂而又不便使用</span><span style="font-family: 'Verdana', 'sans-serif'">IFrame</span><span style="font-family: 宋体">的界面，我们可以对其实施分段装载。例如对于多页标签的界面，我们可以首先下载和初始化多页标签的默认页，然后利用</span><span style="font-family: 'Verdana', 'sans-serif'">AJAH</span><span style="font-family: 宋体">（</span><span style="font-family: 'Verdana', 'sans-serif'">asynchronous JavaScript and HTML</span><span style="font-family: 宋体">）技术来异步的装载其他标签页中的内容。这样就能保证界面可以在第一时间首先展现给用户。把整个复杂界面的装载过程分散到用户的操作过程当中。</span></p>
<p style="text-align: left; text-indent: -21pt; margin: 7.8pt 0cm 7.8pt 42pt; tab-stops: list 42.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings">n&nbsp;</span><span style="font-family: 宋体">利用</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">压缩网络流量。</span></p>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">除了上面提到的这些代码级的改良之外，我们还可以利用</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">来有效的降低网络流量。目前常见的主流浏览器已经全部支持</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">算法，我们往往只需要编写少量的代码就可以支持</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">了。例如在</span><span style="font-family: 'Verdana', 'sans-serif'">J2EE</span><span style="font-family: 宋体">中我们可以在</span><span style="font-family: 'Verdana', 'sans-serif'">Filter</span><span style="font-family: 宋体">中通过下面的代码来判断客户端浏览器是否支持</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">算法，然后根据需要利用</span><span style="font-family: 'Verdana', 'sans-serif'">java.util.zip.GZIPOutputStream</span><span style="font-family: 宋体">来实现</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">的输出。</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; background: #f3f3f3; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">/* </span><span style="font-family: 宋体; font-size: 9pt">判断浏览器对</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">GZIP</span><span style="font-family: 宋体; font-size: 9pt">支持方式的代码</span><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt"> */</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="568">
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">private static String getGZIPEncoding(HttpServletRequest request) {</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;String acceptEncoding = request.getHeader("Accept-Encoding");</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;if (acceptEncoding == null) return null;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;acceptEncoding = acceptEncoding.toLowerCase();</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;if (acceptEncoding.indexOf("x-gzip") &gt;= 0) return "x-gzip";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;if (acceptEncoding.indexOf("gzip") &gt;= 0) return "gzip";</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">&nbsp;return null;</span></p>
            <p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 'Verdana', 'sans-serif'; font-size: 9pt">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-align: left; margin: 7.8pt 0cm 7.8pt 42pt" class="MsoNormal" align="left"><span style="font-family: 宋体">一般而言，</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">对于</span><span style="font-family: 'Verdana', 'sans-serif'">HTML</span><span style="font-family: 宋体">、</span><span style="font-family: 'Verdana', 'sans-serif'">JSP</span><span style="font-family: 宋体">的压缩比可以达到</span><span style="font-family: 'Verdana', 'sans-serif'">80%</span><span style="font-family: 宋体">左右，而它造成的服务端和客户端的性能损耗几乎是可以忽略的。结合其他因素，支持</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">的网站有可能为我们节约</span><span style="font-family: 'Verdana', 'sans-serif'">50%</span><span style="font-family: 宋体">的网络流量。因此</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">的使用可以为那些网络环境不是特别好的应用带来显著的性能提升。使用</span><span style="font-family: 'Verdana', 'sans-serif'">Http</span><span style="font-family: 宋体">的监视工具</span><span style="font-family: 'Verdana', 'sans-serif'">Fiddler</span><span style="font-family: 宋体">可以方便的检测出网页在使用</span><span style="font-family: 'Verdana', 'sans-serif'">GZIP</span><span style="font-family: 宋体">前后的通讯数据量。</span><span style="font-family: 'Verdana', 'sans-serif'">Fiddler</span><span style="font-family: 宋体">的下载地址是</span><span style="font-family: 'Verdana', 'sans-serif'">http://www.fiddlertool.com/fiddler/</span></p>
<p style="text-align: left; margin: 15.6pt 0cm" class="MsoNormal" align="left"><span style="font-family: 宋体">关于</span><span style="font-family: 'Verdana', 'sans-serif'">Web</span><span style="font-family: 宋体">应用的性能优化其实是一个非常大的话题。本文由于篇幅有限，只能涉及其中的几个细节，并且也无法将这些细节的优化方式全面的展现给大家。期望本文能够引起大家对</span><span style="font-family: 'Verdana', 'sans-serif'">Web</span><span style="font-family: 宋体">应用尤其是客户端性能优化的充分重视。毕竟服务端编程技巧已为大家熟知多年，在服务端挖掘性能的潜力已经不大了。而在客户端的方法改进往往能够得到令人惊奇的性能提升。</span></p>
 <img src ="http://www.blogjava.net/freeman1984/aggbug/344056.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2011-02-11 15:23 <a href="http://www.blogjava.net/freeman1984/archive/2011/02/11/344056.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>加速Javascript：DOM操作优化</title><link>http://www.blogjava.net/freeman1984/archive/2010/10/17/335395.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sun, 17 Oct 2010 15:53:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/10/17/335395.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/335395.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/10/17/335395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/335395.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/335395.html</trackback:ping><description><![CDATA[<p>原文：《Speeding up JavaScript: Working with the DOM》</p>
<p>作者： KeeKim Heng, Google Web Developer</p>
<p>在我们开发互联网富应用（RIA）时，我们经常写一些javascript脚本来修改或者增加页面元素，这些工作最终是DOM——或者说文档对象模型——来完成的，而我们的实现方式会影响到应用的响应速度。</p>
<p>DOM操作会导致浏览器重解析(reflow)，这是浏览器的一个决定页面元素如何展现的计算过程。直接修改DOM，修改元素的CSS样式，修改浏览器的窗口大小，都会触发重解析。读取元素的布局属性比如offsetHeithe或者offsetWidth也会触发重解析。重解析需要花费计算时间，因此重解析触发的越少，应用就会越快。</p>
<p>DOM操作通常要不就是修改已经存在的页面上的元素，要不就是创建新的页面元素。下面的4种优化方案覆盖了修改和创建DOM节点两种方式，帮助你减少触发浏览器重解析的次数。</p>
<p>方案一：通过CSS类名切换来修改DOM</p>
<p>&nbsp;</p>
<p>这个方案让我们可以一次性修改一个元素和它的子元素的多个样式属性而只触发一次重解析。</p>
<p>需求：</p>
<p>（emu注：原文作者写到这里的时候脑子显然短路了一下，把后面的Out-of-the-flow DOM Manipulation模式要解决的问题给摆到这里来了，不过从示范代码中很容易明白作者真正想描述的问题，因此emu就不照翻原文了）</p>
<p>我们现在需要写一个函数来修改一个超链接的几个样式规则。要实现很简单，把这几个规则对应的属性逐一改了就好了。但是带来的问题是，每修改一个样式属性，都会导致一次页面的重解析。</p>
<p>view plaincopy to clipboardprint?<br />
function selectAnchor(element) {&nbsp;&nbsp; <br />
&nbsp; element.style.fontWeight = 'bold';&nbsp;&nbsp; <br />
&nbsp; element.style.textDecoration = 'none';&nbsp;&nbsp; <br />
&nbsp; element.style.color = '#000';&nbsp;&nbsp; <br />
}&nbsp; <br />
function selectAnchor(element) {<br />
&nbsp; element.style.fontWeight = 'bold';<br />
&nbsp; element.style.textDecoration = 'none';<br />
&nbsp; element.style.color = '#000';<br />
} </p>
<p>解决方案</p>
<p>要解决这个问题，我们可以先创建一个样式名，并且把要修改的样式规则都放到这个类名上，然后我们给超链接添加上这个新类名，就可以实现添加几个样式规则而只触发一次重解析了。这个模式还有个好处是也实现了表现和逻辑相分离。</p>
<p>view plaincopy to clipboardprint?<br />
.selectedAnchor {&nbsp;&nbsp; <br />
&nbsp; font-weight: bold;&nbsp;&nbsp; <br />
&nbsp; text-decoration: none;&nbsp;&nbsp; <br />
&nbsp; color: #000;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
&nbsp; <br />
function selectAnchor(element) {&nbsp;&nbsp; <br />
&nbsp; element.className = 'selectedAnchor';&nbsp;&nbsp; <br />
}&nbsp; <br />
.selectedAnchor {<br />
&nbsp; font-weight: bold;<br />
&nbsp; text-decoration: none;<br />
&nbsp; color: #000;<br />
}</p>
<p>function selectAnchor(element) {<br />
&nbsp; element.className = 'selectedAnchor';<br />
}</p>
<p>&nbsp;方案二：在非渲染区修改DOM</p>
<p>（emu注：作者在这里再次脑子短路，把DocumentFragment DOM Generation模式的介绍提前到这里来了，emu只好再次发挥一下）<br />
上一个方案解决的是修改一个超链接的问题，当一次需要对很多个超链接进行相同修改的时候，这个方案就可以大显身手了。</p>
<p>需求</p>
<p>需求是这样的，我们要写一个函数来修改一个指定元素的子元素中所有的超链接的样式名（className）属性。要实现很简单，我们可以通过遍历每个超链接并且修改它们的样式名来完成任务。但是带来的问题就是，每修改一个超链接都会导致一次重解析。</p>
<p>view plaincopy to clipboardprint?<br />
function updateAllAnchors(element, anchorClass) {&nbsp;&nbsp; <br />
&nbsp; var anchors = element.getElementsByTagName('a');&nbsp;&nbsp; <br />
&nbsp; for (var i = 0, length = anchors.length; i &lt; length; i ++) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; anchors[i].className = anchorClass;&nbsp;&nbsp; <br />
&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
function updateAllAnchors(element, anchorClass) {<br />
&nbsp; var anchors = element.getElementsByTagName('a');<br />
&nbsp; for (var i = 0, length = anchors.length; i &lt; length; i ++) {<br />
&nbsp;&nbsp;&nbsp; anchors[i].className = anchorClass;<br />
&nbsp; }<br />
}<br />
&nbsp;</p>
<p>解决方案</p>
<p>要解决这个问题，我们可以把被修改的指定元素从DOM里面移除，再修改所有的超链接，然后在把这个元素插入回到它原来的位置上。为了完成这个复杂的操作，我们可以先写一个可重用的函数，它不但移除了这个DOM节点，还返回了一个把元素插回到原来的位置的函数。</p>
<p>view plaincopy to clipboardprint?<br />
/**&nbsp; <br />
&nbsp;* Remove an element and provide a function that inserts it into its original position&nbsp; <br />
&nbsp;* @param element {Element} The element to be temporarily removed&nbsp; <br />
&nbsp;* @return {Function} A function that inserts the element into its original position&nbsp; <br />
&nbsp;**/&nbsp; <br />
function removeToInsertLater(element) {&nbsp;&nbsp; <br />
&nbsp; var parentNode = element.parentNode;&nbsp;&nbsp; <br />
&nbsp; var nextSibling = element.nextSibling;&nbsp;&nbsp; <br />
&nbsp; parentNode.removeChild(element);&nbsp;&nbsp; <br />
&nbsp; return function() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; if (nextSibling) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parentNode.insertBefore(element, nextSibling);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; } else {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parentNode.appendChild(element);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; };&nbsp;&nbsp; <br />
}&nbsp; <br />
/**<br />
&nbsp;* Remove an element and provide a function that inserts it into its original position<br />
&nbsp;* @param element {Element} The element to be temporarily removed<br />
&nbsp;* @return {Function} A function that inserts the element into its original position<br />
&nbsp;**/<br />
function removeToInsertLater(element) {<br />
&nbsp; var parentNode = element.parentNode;<br />
&nbsp; var nextSibling = element.nextSibling;<br />
&nbsp; parentNode.removeChild(element);<br />
&nbsp; return function() {<br />
&nbsp;&nbsp;&nbsp; if (nextSibling) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parentNode.insertBefore(element, nextSibling);<br />
&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parentNode.appendChild(element);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; };<br />
} </p>
<p>有了上面这个函数，现在我们就可以在一个不需要解析渲染的元素上面修改那些超链接了。这样只在移除和插入元素的时候各触发一次重解析。</p>
<p>view plaincopy to clipboardprint?<br />
function updateAllAnchors(element, anchorClass) {&nbsp;&nbsp; <br />
&nbsp; var insertFunction = removeToInsertLater(element);&nbsp;&nbsp; <br />
&nbsp; var anchors = element.getElementsByTagName('a');&nbsp;&nbsp; <br />
&nbsp; for (var i = 0, length = anchors.length; i &lt; length; i ++) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; anchors[i].className = anchorClass;&nbsp;&nbsp; <br />
&nbsp; }&nbsp;&nbsp; <br />
&nbsp; insertFunction();&nbsp;&nbsp; <br />
}&nbsp; <br />
function updateAllAnchors(element, anchorClass) {<br />
&nbsp; var insertFunction = removeToInsertLater(element);<br />
&nbsp; var anchors = element.getElementsByTagName('a');<br />
&nbsp; for (var i = 0, length = anchors.length; i &lt; length; i ++) {<br />
&nbsp;&nbsp;&nbsp; anchors[i].className = anchorClass;<br />
&nbsp; }<br />
&nbsp; insertFunction();<br />
}<br />
&nbsp;</p>
<p>方案三：一次性的DOM元素生成</p>
<p>这个方案让我们创建一个元素的过程只触发一次重解析。在创建完元素以后，先进行所有需要的修改，最后才把它插入到DOM里面去就可以了</p>
<p>需求</p>
<p>需求是这样的，实现一个函数，往一个指定的父元素上插入一个超链接元素。这个函数要同时可以设置这个超链接的显示文字和样式类。我们可以这样做：创建元素，插入到DOM里面，然后设置相应的属性。这就要触发3次重解析。</p>
<p>view plaincopy to clipboardprint?<br />
function addAnchor(parentElement, anchorText, anchorClass) {&nbsp;&nbsp; <br />
&nbsp; var element = document.createElement('a');&nbsp;&nbsp; <br />
&nbsp; parentElement.appendChild(element);&nbsp;&nbsp; <br />
&nbsp; element.innerHTML = anchorText;&nbsp;&nbsp; <br />
&nbsp; element.className = anchorClass;&nbsp;&nbsp; <br />
}&nbsp; <br />
function addAnchor(parentElement, anchorText, anchorClass) {<br />
&nbsp; var element = document.createElement('a');<br />
&nbsp; parentElement.appendChild(element);<br />
&nbsp; element.innerHTML = anchorText;<br />
&nbsp; element.className = anchorClass;<br />
}<br />
&nbsp;</p>
<p>解决方案</p>
<p>很简单，我们只要把插入元素这个操作放到最后做，就可以只进行一次重解析了。</p>
<p>view plaincopy to clipboardprint?<br />
function addAnchor(parentElement, anchorText, anchorClass) {&nbsp;&nbsp; <br />
&nbsp; var element = document.createElement('a');&nbsp;&nbsp; <br />
&nbsp; element.innerHTML = anchorText;&nbsp;&nbsp; <br />
&nbsp; element.className = anchorClass;&nbsp;&nbsp; <br />
&nbsp; parentElement.appendChild(element);&nbsp;&nbsp; <br />
}&nbsp; <br />
function addAnchor(parentElement, anchorText, anchorClass) {<br />
&nbsp; var element = document.createElement('a');<br />
&nbsp; element.innerHTML = anchorText;<br />
&nbsp; element.className = anchorClass;<br />
&nbsp; parentElement.appendChild(element);<br />
} </p>
<p>不过，要是我们想要插入很多个超链接到一个元素里面的话，那么这个做法还是有问题：每插入一个超链接还是要触发一次重解析。下一个方案可以解决这个问题。</p>
<p>方案四：通过文档片段对象（DocumentFragment）创建一组元素</p>
<p>这个方案允许我们创建并插入很多个元素而只触发一次重解析。要实现这点需要用到所谓的文档片段对象（DocumentFragment）。我们先在DOM之外创建一个文档片段对象（这样它也就不需要解析和渲染），然后我们在文档片段对象中创建很多个元素，最后我们把这个文档片段对象中所有的元素一次性放到DOM里面去，只触发一次重解析。</p>
<p>需求</p>
<p><br />
我们要写一个函数，往一个指定的元素上面增加10个超链接。如果我们简单的直接插入10个超链接到元素上面，就会触发10次重解析。</p>
<p>view plaincopy to clipboardprint?<br />
function addAnchors(element) {&nbsp;&nbsp; <br />
&nbsp; var anchor;&nbsp;&nbsp; <br />
&nbsp; for (var i = 0; i &lt; 10; i ++) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; anchor = document.createElement('a');&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; anchor.innerHTML = 'test';&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; element.appendChild(anchor);&nbsp;&nbsp; <br />
&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
function addAnchors(element) {<br />
&nbsp; var anchor;<br />
&nbsp; for (var i = 0; i &lt; 10; i ++) {<br />
&nbsp;&nbsp;&nbsp; anchor = document.createElement('a');<br />
&nbsp;&nbsp;&nbsp; anchor.innerHTML = 'test';<br />
&nbsp;&nbsp;&nbsp; element.appendChild(anchor);<br />
&nbsp; }<br />
} </p>
<p>解决方案</p>
<p>要解决这个问题，我们要先创建一个文档片段对象，然后把每个新创建的超链接都插入到它里面去。当我们把文档片段对象用appendChild命令插入到指定的节点时，这个文档片段对象的所有子节点就一起被插入到指定的元素里面，而且只需要触发一次重解析。</p>
<p>view plaincopy to clipboardprint?<br />
function addAnchors(element) {&nbsp;&nbsp; <br />
&nbsp; var anchor, fragment = document.createDocumentFragment();&nbsp;&nbsp; <br />
&nbsp; for (var i = 0; i &lt; 10; i ++) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; anchor = document.createElement('a');&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; anchor.innerHTML = 'test';&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; fragment.appendChild(anchor);&nbsp;&nbsp; <br />
&nbsp; }&nbsp;&nbsp; <br />
&nbsp; element.appendChild(fragment);&nbsp;&nbsp; <br />
}&nbsp; </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/emu/archive/2010/03/01/5334583.aspx</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/335395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-10-17 23:53 <a href="http://www.blogjava.net/freeman1984/archive/2010/10/17/335395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat内存溢出的三种情况及解决办法分析 </title><link>http://www.blogjava.net/freeman1984/archive/2010/10/16/335295.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sat, 16 Oct 2010 05:28:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/10/16/335295.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/335295.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/10/16/335295.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/335295.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/335295.html</trackback:ping><description><![CDATA[<p>&nbsp;Tomcat内存溢出的原因 </p>
<p>&nbsp;&nbsp;&nbsp; 在生产环境中tomcat内存设置不好很容易出现内存溢出。造成内存原因是不一样的，当然处理方式也不一样。</p>
<p>&nbsp;&nbsp;&nbsp; 这里根据平时遇到的情况和相关资料进行一个总结。常见的一般会有下面三种情况：</p>
<p>&nbsp;&nbsp;&nbsp; 1.OutOfMemoryError： Java heap space</p>
<p>&nbsp;&nbsp;&nbsp; 2.OutOfMemoryError： PermGen space</p>
<p>&nbsp;&nbsp;&nbsp; 3.OutOfMemoryError： unable to create new native thread.</p>
<p>&nbsp;&nbsp;&nbsp; Tomcat内存溢出解决方案 </p>
<p>&nbsp;&nbsp;&nbsp; 对于前两种情况，在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。（-Xms -Xmx -XX：PermSize&nbsp; -XX：MaxPermSize）</p>
<p>&nbsp;&nbsp;&nbsp; 最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。</p>
<p>&nbsp;&nbsp;&nbsp; 第一种：是堆溢出。 </p>
<p>&nbsp;&nbsp;&nbsp; 在JVM中如果98％的时间是用于GC且可用的 Heap size 不足2％的时候将抛出此异常信息。</p>
<p>&nbsp;&nbsp;&nbsp; 没有内存泄露的情况下，调整-Xms -Xmx参数可以解决。</p>
<p>&nbsp;&nbsp;&nbsp; -Xms：初始堆大小</p>
<p>&nbsp;&nbsp;&nbsp; -Xmx：最大堆大小</p>
<p>&nbsp;&nbsp;&nbsp; 但堆的大小受下面三方面影响：</p>
<p>&nbsp;&nbsp;&nbsp; 1.相关操作系统的数据模型（32-bt还是64-bit）限制；（32位系统下，一般限制在1.5G~2G；我在2003 server 系统下（物理内存：4G和6G，jdk：1.6）测试 1612M，64为操作系统对内存无限制。）</p>
<p>&nbsp;&nbsp;&nbsp; 2.系统的可用虚拟内存限制；</p>
<p>&nbsp;&nbsp;&nbsp; 3.系统的可用物理内存限制。</p>
<p>&nbsp;&nbsp;&nbsp; 堆的大小可以使用 java -Xmx***M&nbsp; version 命令来测试 。支持的话会出现jdk的版本号，不支持会报错。</p>
<p>&nbsp;&nbsp;&nbsp; -Xms -Xmx一般配置成一样比较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m</p>
<p>&nbsp;&nbsp;&nbsp; 第二种：永久保存区域溢出 </p>
<p>&nbsp;&nbsp;&nbsp; PermGen space的全称是Permanent Generation space，是指内存的永久保存区域。这一部分用于存放Class和Meta的信息，Class在被 Load的时候被放入PermGen space区域，它和和存放Instance的Heap区域不同，GC（Garbage Collection）不会在主程序运行期对PermGen space进行清理，所以如果你的APP会LOAD很多CLASS的话，就很可能出现PermGen space错误。这种错误常见在web服务器 对JSP进行pre compile的时候。但目前的hibernate和spring项目中也很容易出现这样的问题。http://www.javaeye.com/topic/80620 ?page=1 的帖子有讨论的这个问题。可能是由于这些框架会动态class，而且jvm的gc是不会清理PemGen space的，导致内存溢出。</p>
<p>&nbsp;&nbsp;&nbsp; 这一个一般是加大-XX：PermSize&nbsp; -XX：MaxPermSize 来解决问题。</p>
<p>&nbsp;&nbsp;&nbsp; -XX：PermSize 永久保存区域初始大小</p>
<p>&nbsp;&nbsp;&nbsp; -XX：PermSize 永久保存区域初始最大值</p>
<p>&nbsp;&nbsp;&nbsp; 这一般结合第一条使用，比如 set JAVA_OPTS= -Xms1024m -Xmx1024m&nbsp; -XX：PermSize=128M -XX：PermSize=256M</p>
<p>&nbsp;&nbsp;&nbsp; 有一点需要注意：java -Xmx***M&nbsp; version 命令来测试的最大堆内存是 -Xmx与 -XX：PermSize的 和 比如系统支持最大的jvm堆大小事1.5G，那&nbsp; -Xmx1024m&nbsp; -XX：PermSize=768M 是无法运行的。</p>
<p>&nbsp;&nbsp;&nbsp; 第三种：无法创建新的线程。 </p>
<p>&nbsp;&nbsp;&nbsp; 这种现象比较少见，也比较奇怪，主要是和jvm与系统内存的比例有关。</p>
<p>&nbsp;&nbsp;&nbsp; 这种怪事是因为JVM已经被系统分配了大量的内存（比如1.5G），并且它至少要占用可用内存的一半。有人发现，在线程个数很多的情况下，你分配给JVM 的内存越多，那么，上述错误发生的可能性就越大。</p>
<p>&nbsp;&nbsp;&nbsp; 产生这种现象的原因如下（从这个blog中了解到原因：http://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html ）：</p>
<p>&nbsp;&nbsp;&nbsp; 每一个32位的进程最多可以使用2G的可用内存，因为另外2G被操作系统保留。这里假设使用1.5G给JVM，那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载，那么真正剩下的也许只有400M，现在关键的地方出现了：当你使用Java 创建一个线程，在JVM的内存里也会创建一个Thread对象，但是同时也会在操作系统里创建一个真正的物理线程（参考JVM规范），操作系统会在余下的400兆内存里创建这个物理线程，而不是在JVM的1500M的内存堆里创建。在jdk1.4里头，默认的栈大小是256KB，但是在jdk1.5里头，默认的栈大小为1M每线程，因此，在余下400M的可用内存里边我们最多也只能创建400个可用线程。</p>
<p>&nbsp;&nbsp;&nbsp; 这样结论就出来了，要想创建更多的线程，你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。</p>
<p>&nbsp;&nbsp;&nbsp; 给出一个有关能够创建线程的最大个数的估算公式：</p>
<p>&nbsp;&nbsp;&nbsp; （MaxProcessMemory - JVMMemory - ReservedOsMemory） / （ThreadStackSize） = Number of threads</p>
<p>&nbsp;&nbsp;&nbsp; 对于jdk1.5而言，假设操作系统保留120M内存：</p>
<p>&nbsp;&nbsp;&nbsp; 1.5GB JVM： （2GB-1.5Gb-120MB）/（1MB） = ~380 threads</p>
<p>&nbsp;&nbsp;&nbsp; 1.0GB JVM： （2GB-1.0Gb-120MB）/（1MB） = ~880 threads</p>
<p>&nbsp;&nbsp;&nbsp; 在2000/XP/2003的boot.ini里头有一个启动选项，好像是：/PAE /3G ，可以让用户进程最大内存扩充至3G，这时操作系统只能占用最多1G的虚存。那样应该可以让JVM创建更多的线程。</p>
<p>&nbsp;&nbsp;&nbsp; 因此这种情况需要结合操作系统进行相关调整。</p>
<p>&nbsp;&nbsp;&nbsp; 因此：我们需要结合不同情况对tomcat内存分配进行不同的诊断才能从根本上解决问题。</p>
<p>&nbsp;&nbsp;&nbsp; 以上就是针对Tomcat内存溢出的几种解决方案。本文来自George的博客：《tomcat内存溢出总结》</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/Senton/archive/2010/07/01/5707446.aspx</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/335295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-10-16 13:28 <a href="http://www.blogjava.net/freeman1984/archive/2010/10/16/335295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat启动分析server.xml </title><link>http://www.blogjava.net/freeman1984/archive/2010/10/11/334485.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Mon, 11 Oct 2010 15:13:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/10/11/334485.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/334485.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/10/11/334485.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/334485.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/334485.html</trackback:ping><description><![CDATA[<div>
<p><font color="#000080">1 - Tomcat Server的组成部分 <br />
1.1 - Server </font></p>
<p><font color="#000080">A Server element represents the entire Catalina servlet container. (Singleton) </font></p>
<p><font color="#000080">1.2 - Service </font></p>
<p><font color="#000080">A Service element represents the combination of one or more Connector components that share a single Engine<br />
Service是这样一个集合：它由一个或者多个Connector组成，以及一个Engine，负责处理所有Connector所获得的客户请求</font></p>
<p><font color="#000080">1.3 - Connector </font></p>
<p><font color="#000080">一个Connector将在某个指定端口上侦听客户请求，并将获得的请求交给Engine来处理，从Engine处获得回应并返回客户<br />
TOMCAT有两个典型的Connector，一个直接侦听来自browser的http请求，一个侦听来自其它WebServer的请求<br />
Coyote Http/1.1 Connector 在端口8080处侦听来自客户browser的http请求<br />
Coyote JK2 Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求</font></p>
<p><font color="#000080">1.4 - Engine </font></p>
<p><font color="#000080">The Engine element represents the entire request processing machinery associated with a particular Service<br />
It receives and processes all requests from one or more Connectors<br />
and returns the completed response to the Connector for ultimate transmission back to the client<br />
Engine下可以配置多个虚拟主机Virtual Host，每个虚拟主机都有一个域名<br />
当Engine获得一个请求时，它把该请求匹配到某个Host上，然后把该请求交给该Host来处理<br />
Engine有一个默认虚拟主机，当请求无法匹配到任何一个Host上的时候，将交给该默认Host来处理</font></p>
<p><font color="#000080">1.5 - Host </font></p>
<p><font color="#000080">代表一个Virtual Host，虚拟主机，每个虚拟主机和某个网络域名Domain Name相匹配<br />
每个虚拟主机下都可以部署(deploy)一个或者多个Web App，每个Web App对应于一个Context，有一个Context path<br />
当Host获得一个请求时，将把该请求匹配到某个Context上，然后把该请求交给该Context来处理<br />
匹配的方法是&#8220;最长匹配&#8221;，所以一个path==""的Context将成为该Host的默认Context<br />
所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配</font></p>
<p><br />
<font color="#000080">1.6 - Context </font></p>
<p><font color="#000080">一个Context对应于一个Web Application，一个Web Application由一个或者多个Servlet组成<br />
Context在创建的时候将根据配置文件＄CATALINA_HOME/conf/web.xml和＄WEBAPP_HOME/WEB-INF/web.xml载入Servlet类<br />
当Context获得请求时，将在自己的映射表(mapping table)中寻找相匹配的Servlet类<br />
如果找到，则执行该类，获得请求的回应，并返回</font></p>
<p><font color="#000080">2 - Tomcat Server的结构图 <br />
&nbsp;<br />
3 - 配置文件＄CATALINA_HOME/conf/server.xml的说明 <br />
该文件描述了如何启动Tomcat Server </font></p>
<p><br />
<font color="#000080">&lt;!-----------------------------------------------------------------------------------------------&gt;</font></p>
<p><br />
<font color="#000080">&lt;!-- 启动Server<br />
&nbsp;&nbsp;&nbsp;&nbsp; 在端口8005处等待关闭命令<br />
&nbsp;&nbsp;&nbsp;&nbsp; 如果接受到"SHUTDOWN"字符串则关闭服务器<br />
&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&lt;Server port="8005" shutdown="SHUTDOWN" debug="0"&gt;</font></p>
<p><br />
<font color="#000080">&nbsp; &lt;!-- Listener ???<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前没有看到这里<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp; &lt;Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" debug="0"/&gt;<br />
&nbsp; &lt;Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" debug="0"/&gt;</font></p>
<p><br />
<font color="#000080">&nbsp; &lt;!-- Global JNDI resources ???<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前没有看到这里，先略去<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp; &lt;GlobalNamingResources&gt;<br />
&nbsp;&nbsp;&nbsp; ... ... ... ...<br />
&nbsp; &lt;/GlobalNamingResources&gt;</font></p>
<p><font color="#000080">&nbsp; &lt;!-- Tomcat的Standalone Service<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Service是一组Connector的集合<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它们共用一个Engine来处理所有Connector收到的请求<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp; &lt;Service name="Tomcat-Standalone"&gt;</font></p>
<p><br />
<font color="#000080">&nbsp;&nbsp;&nbsp; &lt;!-- Coyote HTTP/1.1 Connector<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; className : 该Connector的实现类是org.apache.coyote.tomcat4.CoyoteConnector<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port : 在端口号8080处侦听来自客户browser的HTTP1.1请求<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minProcessors : 该Connector先创建5个线程等待客户请求，每个请求由一个线程负责<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxProcessors : 当现有的线程不够服务客户请求时，若线程总数不足75个，则创建新线程来处理请求<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acceptCount : 当现有线程已经达到最大数75时，为客户请求排队<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当队列中请求数超过100时，后来的请求返回Connection refused错误<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; redirectport : 当客户请求是https时，把该请求转发到端口8443去<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其它属性略<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; &lt;Connector className="org.apache.coyote.tomcat4.CoyoteConnector" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port="8080" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minProcessors="5" maxProcessors="75" acceptCount="100" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="true" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; redirectPort="8443" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; debug="0" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connectionTimeout="20000" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useURIValidationHack="false" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; disableUploadTimeout="true" /&gt;</font></p>
<p><br />
<font color="#000080">&nbsp;&nbsp;&nbsp; &lt;!-- Engine用来处理Connector收到的Http请求<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它将匹配请求和自己的虚拟主机，并把请求转交给对应的Host来处理<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 默认虚拟主机是localhost<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; &lt;Engine name="Standalone" defaultHost="localhost" debug="0"&gt;<br />
&nbsp;&nbsp;&nbsp; </font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 日志类，目前没有看到，略去先 --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Logger className="org.apache.catalina.logger.FileLogger" .../&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- Realm，目前没有看到，略去先 --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm" .../&gt;</font></p>
<p><br />
<font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 虚拟主机localhost<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appBase : 该虚拟主机的根目录是webapps/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它将匹配请求和自己的Context的路径，并把请求转交给对应的Context来处理<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 日志类，目前没有看到，略去先 --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Logger className="org.apache.catalina.logger.FileLogger" .../&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- Context，对应于一个Web App<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path : 该Context的路径名是""，故该Context是该Host的默认Context<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; docBase : 该Context的根目录是webapps/mycontext/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Context path="" docBase="mycontext" debug="0"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 另外一个Context，路径名是/wsota --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Context path="/wsota" docBase="wsotaProject" debug="0"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Host&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;/Engine&gt;</font></p>
<p><font color="#000080">&nbsp; &lt;/Service&gt;</font></p>
<p><font color="#000080">&lt;/Server&gt;</font></p>
<p><br />
<font color="#000080">&lt;!-----------------------------------------------------------------------------------------------&gt;</font></p>
<p><font color="#000080"></font>&nbsp;</p>
<p><font color="#000080">4 - Context的部署配置文件web.xml的说明 <br />
一个Context对应于一个Web App，每个Web App是由一个或者多个servlet组成的<br />
当一个Web App被初始化的时候，它将用自己的ClassLoader对象载入&#8220;部署配置文件web.xml&#8221;中定义的每个servlet类<br />
它首先载入在＄CATALINA_HOME/conf/web.xml中部署的servlet类<br />
然后载入在自己的Web App根目录下的WEB-INF/web.xml中部署的servlet类<br />
web.xml文件有两部分：servlet类定义和servlet映射定义<br />
每个被载入的servlet类都有一个名字，且被填入该Context的映射表(mapping table)中，和某种URL PATTERN对应<br />
当该Context获得请求时，将查询mapping table，找到被请求的servlet，并执行以获得请求回应</font></p>
<p><br />
<font color="#000080">　　分析一下所有的Context共享的web.xml文件，在其中定义的servlet被所有的Web App载入</font></p>
<p><font color="#000080"></font>&nbsp;</p>
<p><br />
<font color="#000080">&lt;!-----------------------------------------------------------------------------------------------&gt;</font></p>
<p><br />
<font color="#000080">&lt;web-app&gt;</font></p>
<p><br />
<font color="#000080">&nbsp; &lt;!-- 概述：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该文件是所有的WEB APP共用的部署配置文件，<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每当一个WEB APP被DEPLOY，该文件都将先被处理，然后才是WEB APP自己的/WEB-INF/web.xml<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080"></font>&nbsp;</p>
<p><font color="#000080">&nbsp; &lt;!--&nbsp; +-------------------------+&nbsp; --&gt;<br />
&nbsp; &lt;!--&nbsp; |&nbsp;&nbsp;&nbsp; servlet类定义部分&nbsp;&nbsp;&nbsp; |&nbsp; --&gt;<br />
&nbsp; &lt;!--&nbsp; +-------------------------+&nbsp; --&gt;</font></p>
<p><font color="#000080"></font></p>
<p><font color="#000080">&nbsp; &lt;!-- DefaultServlet<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当用户的HTTP请求无法匹配任何一个servlet的时候，该servlet被执行<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL PATTERN MAPPING : /<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;default&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.apache.catalina.servlets.DefaultServlet<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;debug&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;0&lt;/param-value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;listings&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;true&lt;/param-value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</font></p>
<p><br />
<font color="#000080">&nbsp; &lt;!-- InvokerServlet<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 处理一个WEB APP中的匿名servlet<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当一个servlet被编写并编译放入/WEB-INF/classes/中，却没有在/WEB-INF/web.xml中定义的时候<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该servlet被调用，把匿名servlet映射成/servlet/ClassName的形式<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL PATTERN MAPPING : /servlet/*<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.apache.catalina.servlets.InvokerServlet<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;debug&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;0&lt;/param-value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</font></p>
<p><br />
<font color="#000080">&nbsp; &lt;!-- JspServlet<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当请求的是一个JSP页面的时候（*.jsp）该servlet被调用<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它是一个JSP编译器，将请求的JSP页面编译成为servlet再执行<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL PATTERN MAPPING : *.jsp<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;jsp&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.apache.jasper.servlet.JspServlet&lt;/servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;logVerbosityLevel&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;WARNING&lt;/param-value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;3&lt;/load-on-startup&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</font></p>
<p><font color="#000080"></font>&nbsp;</p>
<p><font color="#000080">&nbsp; &lt;!--&nbsp; +---------------------------+&nbsp; --&gt;<br />
&nbsp; &lt;!--&nbsp; |&nbsp;&nbsp;&nbsp; servlet映射定义部分&nbsp;&nbsp;&nbsp; |&nbsp; --&gt;<br />
&nbsp; &lt;!--&nbsp; +---------------------------+&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;default&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;jsp&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</font></p>
<p><br />
<font color="#000080">&nbsp; &lt;!--&nbsp; +------------------------+&nbsp; --&gt;<br />
&nbsp; &lt;!--&nbsp; |&nbsp;&nbsp;&nbsp; 其它部分，略去先&nbsp;&nbsp;&nbsp; |&nbsp; --&gt;<br />
&nbsp; &lt;!--&nbsp; +------------------------+&nbsp; --&gt;</font></p>
<p><font color="#000080">&nbsp;&nbsp;&nbsp; ... ... ... ...</font></p>
<p><font color="#000080">&lt;/web-app&gt;</font></p>
<p><br />
<font color="#000080">&lt;!-----------------------------------------------------------------------------------------------&gt;</font></p>
<p><font color="#000080"></font>&nbsp;</p>
<p><font color="#000080">5 - Tomcat Server处理一个http请求的过程 <br />
假设来自客户的请求为：<br />
</font><a href="http://localhost:8080/wsota/wsota_index.jsp"><font color="#000080">http://localhost:8080/wsota/wsota_index.jsp</font></a></p>
<p><font color="#000080">1) 请求被发送到本机端口8080，被在那里侦听的Coyote HTTP/1.1 Connector获得</font></p>
<p><font color="#000080">2) Connector把该请求交给它所在的Service的Engine来处理，并等待来自Engine的回应</font></p>
<p><font color="#000080">3) Engine获得请求localhost/wsota/wsota_index.jsp，匹配它所拥有的所有虚拟主机Host</font></p>
<p><font color="#000080">4) Engine匹配到名为localhost的Host（即使匹配不到也把请求交给该Host处理，因为该Host被定义为该Engine的默认主机）</font></p>
<p><font color="#000080">5) localhost Host获得请求/wsota/wsota_index.jsp，匹配它所拥有的所有Context</font></p>
<p><font color="#000080">6) Host匹配到路径为/wsota的Context（如果匹配不到就把该请求交给路径名为""的Context去处理）</font></p>
<p><font color="#000080">7) path="/wsota"的Context获得请求/wsota_index.jsp，在它的mapping table中寻找对应的servlet</font></p>
<p><font color="#000080">8) Context匹配到URL PATTERN为*.jsp的servlet，对应于JspServlet类</font></p>
<p><font color="#000080">9) 构造HttpServletRequest对象和HttpServletResponse对象，作为参数调用JspServlet的doGet或doPost方法</font></p>
<p><font color="#000080">10)Context把执行完了之后的HttpServletResponse对象返回给Host</font></p>
<p><font color="#000080">11)Host把HttpServletResponse对象返回给Engine</font></p>
<p><font color="#000080">12)Engine把HttpServletResponse对象返回给Connector</font></p>
<p><font color="#000080">13)Connector把HttpServletResponse对象返回给客户browser</font></p>
</div>
转载自：http://www.360doc.com/content/05/1116/10/2689_31126.shtml
<img src ="http://www.blogjava.net/freeman1984/aggbug/334485.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-10-11 23:13 <a href="http://www.blogjava.net/freeman1984/archive/2010/10/11/334485.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java虚拟机参数 -XX等相关参数应用</title><link>http://www.blogjava.net/freeman1984/archive/2010/10/11/334483.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Mon, 11 Oct 2010 15:03:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/10/11/334483.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/334483.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/10/11/334483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/334483.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/334483.html</trackback:ping><description><![CDATA[<p><br />官方翻译文档见：<a href="http://www.cnblogs.com/z-zw/archive/2010/09/30/1839394.html#_Toc273607019">http://www.cnblogs.com/z-zw/archive/2010/09/30/1839394.html</a><br />通常，我们为了避免内存溢出等问题，需要设置环境变量<br />JAVA_OPTS&nbsp;&nbsp;&nbsp; -Xms256M -Xmx512M 等，【对于服务器，一般都设置成一样的】<br />但是有的时候可能这样的设置还会不行(比如，当Server应用程序加载较多类时，即jvm加载类时，永久域中的对象急剧增加，从而使jvm不断调整永久域大小，为了避免调整)，你可以使用更多的参数配置，如： java -Xms512m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=128m<br />其中，使用&nbsp;&nbsp; -XX:MaxPerSize标志来增加永久域的大小，-XX:PerSize标志设置初始值</p>
<p>-XX</p>
<p>基于 Sun 的 Java 2 Standard Edition（J2SE）5 有生成垃圾回收功能，这允许分隔内存池以包含不同时效的对象。垃圾回收循环根据时效收集与其他对象彼此独立的对象。使用其他参数，您可以单独设置内存池的 大小。为了实现更好的性能，您应该对包含短期存活对象的池的大小进行设置，以使该池中的对象的存活时间不会超过一个垃圾回收循环。新生成的池的大小由 NewSize 和 MaxNewSize 参数确定。</p>
<p>第一次垃圾回收循环中存活下来的对象转移到另一个池中。生还者池的大小由参数 SurvivorRatio 确定。 如果垃圾回收变成了瓶颈，您可以尝试定制生成池设置。要监控垃圾回收统计信息，使用 Tivoli Performance Viewer 中的对象统计信息或 verbose:gc 配置设置。 输入下列值： <br />-XX:NewSize (lower bound)<br />-XX:MaxNewSize (upper bound)<br />-XX:SurvivorRatio=NewRatioSize <br />-XX:NewSize 320m 此值设大可调大新对象区，减少Full GC次数<br />-XX:+UseParNewGC ：缩短minor收集的时间 可用来设置并行收集【多CPU】<br />-XX:+ParallelGCThreads 可用来增加并行度【多CPU】<br />-XX:+UseParallelGC 设置后可以使用并行清除收集器【多CPU】-Xss：每个线程的Stack大小</p>
<p>-verbose:gc 显示垃圾收集信息<br />-Xloggc:gc.log 指定垃圾收集日志文件<br />刚刚了解到的一些参数（待实践测试）<br />-Xmn：young generation的heap大小，一般设置为Xmx的3、4分之一<br />-XX:+UseConcMarkSweepGC ：缩短major收集的时间<br />提示：此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适</p>
<p>下面的命令把整个堆设置成128m，新域比率设置成3，即新域与旧域比例为1：3，新域为堆的1/4或32M：</p>
<p>java &#8211;Xms128m &#8211;Xmx128m &#8211;XX:NewRatio =3缺省值为：NewSize=2m MaxNewSize=32m SurvivorRatio=2。但是，如果 JVM 的堆大小大于 1GB，则应该使用值：-XX:newSize=640m -XX:MaxNewSize=640m -XX:SurvivorRatio=16，或者将堆的总大小的 50% 到 60% 分配给新生成的池。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 举例：永久域默认大小为4m。运行程序时，jvm会调整永久域的大小以满足需要。每次调整时，jvm会对堆进行一次完全的垃圾收集。</p>
<p>使用-XX:MaxPerSize标志来增加永久域的大小。在WebLogic Server应用程序加载较多类时，经常需要增加永久域的最大值。当jvm加载类时，永久域中的对象急剧增加，从而使jvm不断调整永久域大小。为了避免 调整，可使用-XX:PerSize标志设置初始值。<br />&nbsp;&nbsp; 下面把永久域初始值设置成32m，最大值设置成64m。<br />&nbsp;&nbsp;&nbsp; java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m</p>
<p>默认状态下，HotSpot在新域中使用复制收集器。该域一般分为三个部分。第一部分为Eden，用于生成新的对象。另两部分称为救助空间，当Eden充 满时，收集器停止应用程序，把所有可到达对象复制到当前的from救助空间，一旦当前的from救助空间充满，收集器则把可到达对象复制到当前的to救助 空间。From和to救助空间互换角色。维持活动的对象将在救助空间不断复制，直到它们获得使用期并转入旧域。使用-XX:SurvivorRatio可 控制新域子空间的大小。</p>
<p>目前，我的的开发环境 2G内存，tomcat+eclipse 大型应用程序<br />java -Xmx1024m -XX:PermSize=512m&nbsp;&nbsp; 基本就ok大部分应用了</p>
<p>&nbsp;</p>
<p>我的服务器参数配置:<br />MY_PARAMS="-Xmn340m -Xss128k -XX:NewSize=640m -XX:MaxNewSize=640m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+UseParNewGC -Xloggc:gc.log"</p>
<p>本文出处：http://hi.baidu.com/china8jie/blog/item/7c4ac1a2e25a9fa5caefd0d1.html</p>
<p>&nbsp;</p>
<ol><li><strong>常见配置汇总</strong> </li><li>堆设置 
<ul><li><strong>-Xms</strong> :初始堆大小 </li><li><strong>-Xmx</strong> :最大堆大小 </li><li><strong>-XX:NewSize=n</strong> :设置年轻代大小 </li><li><strong>-XX:NewRatio=n:</strong> 设置年轻代和年老代的比值。如:为3，表示年轻代与年老代比值为1：3，年轻代占整个年轻代年老代和的1/4 </li><li><strong>-XX:SurvivorRatio=n</strong> :年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如：3，表示Eden：Survivor=3：2，一个Survivor区占整个年轻代的1/5 </li><li><strong>-XX:MaxPermSize=n</strong> :设置持久代大小</li></ul></li><li>收集器设置 
<ul><li><strong>-XX:+UseSerialGC</strong> :设置串行收集器 </li><li><strong>-XX:+UseParallelGC</strong> :设置并行收集器 </li><li><strong>-XX:+UseParalledlOldGC</strong> :设置并行年老代收集器 </li><li><strong>-XX:+UseConcMarkSweepGC</strong> :设置并发收集器</li></ul></li><li>垃圾回收统计信息 
<ul><li><strong>-XX:+PrintGC</strong> </li><li><strong>-XX:+PrintGCDetails</strong> </li><li><strong>-XX:+PrintGCTimeStamps</strong> </li><li><strong>-Xloggc:filename</strong> </li></ul></li><li>并行收集器设置 
<ul><li><strong>-XX:ParallelGCThreads=n</strong> :设置并行收集器收集时使用的CPU数。并行收集线程数。 </li><li><strong>-XX:MaxGCPauseMillis=n</strong> :设置并行收集最大暂停时间 </li><li><strong>-XX:GCTimeRatio=n</strong> :设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)</li></ul></li><li>并发收集器设置 
<ul><li><strong>-XX:+CMSIncrementalMode</strong> :设置为增量模式。适用于单CPU情况。 </li><li><strong>-XX:ParallelGCThreads=n</strong> :设置并发收集器年轻代收集方式为并行收集时，使用的CPU数。并行收集线程数。</li></ul></li></ol>
<p><br /></p><img src ="http://www.blogjava.net/freeman1984/aggbug/334483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-10-11 23:03 <a href="http://www.blogjava.net/freeman1984/archive/2010/10/11/334483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle 10g SQL 优化再学习</title><link>http://www.blogjava.net/freeman1984/archive/2010/10/10/334235.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Sun, 10 Oct 2010 15:52:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/10/10/334235.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/334235.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/10/10/334235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/334235.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/334235.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p>从8i到10g，Oracle不断进化自己的SQL Tuning智能，一些秘籍级的优化口诀已经失效。<br />
&nbsp;&nbsp; 但我喜欢失效，不用记口诀，操个Toad for Oracle Xpert ，按照大方向舒舒服服的调优才是爱做的事情。</p>
<p>1.Excution Plan<br />
&nbsp;&nbsp;&nbsp;&nbsp; Excution Plan是最基本的调优概念，不管你的调优吹得如何天花乱堕，结果还是要由Excution plan来显示Oracle 最终用什么索引、按什么顺序连接各表，Full Table Scan还是Access by Rowid Index，瓶颈在什么地方。如果没有它的指导，一切调优都是蒙的。</p>
<p><br />
2.Toad for Oracle Xpert<br />
&nbsp;&nbsp;&nbsp; 用它来调优在真的好舒服。Quest 吞并了Lecco后，将它整合到了Toad 的SQL Tunning里面：最清晰的执行计划显示，自动生成N条等价SQL、给出优化建议，不同SQL执行计划的对比，还有实际执行的逻辑读、物理读数据等等一目了然。</p>
<p><br />
3.索引<br />
&nbsp;&nbsp; 大部分的性能问题其实都是索引应用的问题，Where子句、Order By、Group By 都要用到索引。<br />
&nbsp;&nbsp; 一般开发人员认为将索引建全了就可以下班回家了，实则还有颇多的思量和陷阱。</p>
<p>3.1 索引列上不要进行计算<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这是最最普遍的失效陷阱，比如where trunc(order_date)=trunc(sysdate), i+2&gt;4。索引失效的原因也简单，索引是针对原值建的二叉树，你将列值*3/4+2折腾一番后，原来的二叉树当然就用不上了。解决的方法:<br />
　 1.　换成等价语法，比如trunc(order_date) 换成</p>
<p>where order_date&gt;trunc(sysdate)-1 and order_date&lt;trunc(sysdate)+1　 2.&nbsp;&nbsp;&nbsp; 特别为计算建立函数索引</p>
<p>create index Ｉ_XXXX on shop_order(trunc(order_date))&nbsp;&nbsp;&nbsp; 3.&nbsp;&nbsp;&nbsp; 将计算从等号左边移到右边<br />
　这是针对某些无心之失的纠正，把a*2&gt;4　改为a&gt;4/2；把TO_CHAR(zip) = '94002' 改为zip = TO_NUMBER('94002');</p>
<p>3.2 CBO与索引选择性<br />
&nbsp;&nbsp;&nbsp;&nbsp; 建了索引也不一定会被Oracle用的，就像个挑食的孩子。基于成本的优化器(CBO, Cost-Based Optimizer)，会先看看表的大小，还有索引的重复度，再决定用还是不用。表中有100 条记录而其中有80 个不重复的索引键值. 这个索引的选择性就是80/100 = 0.8，留意Toad里显示索引的Selective和Cardinailty。实在不听话时，就要用hints来调教。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 另外，where语句存在多条索引可用时，只会选择其中一条。所以索引也不是越多越好：）</p>
<p>3.3 索引重建<br />
&nbsp;&nbsp;&nbsp;&nbsp; 传说中数据更新频繁导致有20%的碎片时，Oracle就会放弃这个索引。宁可信其有之下，应该时常alter index &lt;INDEXNAME&gt; rebuild一下。</p>
<p>3.4 其他要注意的地方<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不要使用Not，如goods_no != 2，要改为</p>
<p>where goods_no&gt;2 or goods_no&lt;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不要使用is null , 如WHERE DEPT_CODE IS NOT NULL 要改为</p>
<p>WHERE DEPT_CODE &gt;=0;3.5 select 的列如果全是索引列时<br />
&nbsp;&nbsp; 又如果没有where 条件，或者where条件全部是索引列时，Oracle 将直接从索引里获取数据而不去读真实的数据表，这样子理论上会快很多，比如</p>
<p>select order_no,order_time from shop_order where shop_no=4当order_no,order_time,shop_no 这三列全为索引列时，你将看到一个和平时完全不同的执行计划。</p>
<p>3.6 位图索引<br />
&nbsp;&nbsp;&nbsp;&nbsp; 传说中当数据值较少，比如某些表示分类、状态的列，应该建位图索引而不是普通的二叉树索引，否则效率低下。不过看执行计划，这些位图索引鲜有被Oracle临幸的。<br />
&nbsp; </p>
<p><br />
4.减少查询往返和查询的表<br />
这也是很简单的大道理，程序与Oracle交互的成本极高，所以一个查询能完成的不要分开两次查，如果一个循环执行１万条查询的，怎么都快不到哪里去了。</p>
<p>4.1 封装PL/SQL存储过程<br />
　 最高级的做法是把循环的操作封装到PL/SQL写的存储过程里，因为存储过程都在服务端执行，所以没有数据往返的消耗。</p>
<p><br />
4.2 封装PL/SQL内部函数<br />
&nbsp; 有机会，将一些查询封装到函数里，而在普通SQL里使用这些函数，同样是很有效的优化。</p>
<p>4.3 Decode/Case<br />
　 但存储过程也麻烦，所以有case/decode把几条条件基本相同的重复查询合并为一条的用法：</p>
<p>SELECT<br />
&nbsp;COUNT(CASE WHEN price &lt; 13 THEN 1 ELSE null END) low,<br />
&nbsp;COUNT(CASE WHEN price BETWEEN 13 AND 15 THEN 1 ELSE null END) med,<br />
&nbsp;COUNT(CASE WHEN price &gt; 15 THEN 1 ELSE null END) high<br />
FROM products;4.4 一种Where/Update语法</p>
<p>SELECT TAB_NAME　FROM TABLES<br />
WHERE (TAB_NAME,DB_VER) = （( SELECT TAB_NAME,DB_VER)<br />
FROM TAB_COLUMNS WHERE VERSION = 604)</p>
<p>UPDATE EMP<br />
SET (EMP_CAT, SAL_RANGE)<br />
= (SELECT MAX(CATEGORY)FROM EMP_CATEGORIES)<br />
5.其他优化<br />
5.1RowID和ROWNUM<br />
&nbsp;&nbsp;&nbsp;&nbsp; 连Hibernate 新版也支持ROWID了，证明它非常有用。比如号称删除重复数据的最快写法：</p>
<p>DELETE FROM EMP E<br />
WHERE E.ROWID &gt; (SELECT MIN(X.ROWID)<br />
FROM EMP X<br />
WHERE X.EMP_NO = E.EMP_NO);6.终极秘技 - Hints<br />
&nbsp;&nbsp; 这是Oracle DBA的玩具，也是终极武器，比如Oracle在CBO,RBO中所做的选择总不合自己心水时，可以用它来强力调教一下Oracle，结果经常让人喜出望外。<br />
&nbsp;&nbsp; 如果开发人员没那么多时间来专门学习它，可以依靠Toad SQL opmitzer 来自动生成这些提示，然后对比一下各种提示的实际效果。不过随着10g智能的进化，hints的惊喜少了。</p>
<p>7. 找出要优化的Top SQL<br />
&nbsp;&nbsp;&nbsp; 磨了这么久的枪，如果找不到敌人是件郁闷的事情。<br />
&nbsp;&nbsp;&nbsp; 幸亏10g这方面做得非常好。进入Web管理界面，就能看到当前或者任意一天的SQL列表，按性能排序。<br />
&nbsp;&nbsp;&nbsp; 有了它，SQL Trace和TKPROF都可以不用了。</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/calvinxiu/archive/2005/11/15/529756.aspx</p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/334235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-10-10 23:52 <a href="http://www.blogjava.net/freeman1984/archive/2010/10/10/334235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>google Analytics 初探</title><link>http://www.blogjava.net/freeman1984/archive/2010/09/16/332234.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Thu, 16 Sep 2010 13:37:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/09/16/332234.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/332234.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/09/16/332234.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/332234.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/332234.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;最近公司的在线运营网站要加大市场分析力度，因此公司想要网站的力量统计，包括用户来源分布统计，功能使用率统计等，为了这就来研究下google Analytics 了，一开始没做过，上网搜了搜，看见一篇不错的文章就照着整了，等过段时间看看统计效果咋样，这里转载文章大家看看，写的不错，自己也就先不写啥了，最近在啃他的api ，api地址：<br />
http://code.google.com/intl/zh-CN/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html<br />
当然要想用的更好就需要去研究下他的api，包扩一些新特新，和一些统计的api。这篇文章是关于豆瓣网的使用经验，后面还附加了点评网的代码。<br />
&nbsp;&nbsp;&nbsp;内容如下：
<p>豆瓣从今年开始也加入 Google Analytics 的统计阵营。让我们通过它加载的 Google Analytics 源码，简单分析一下它都是怎么应用的。</p>
<p>我们先从豆瓣的源码来看看它的Google Analytics统计代码</p>
<p class="entry_img"><img style="display: inline; filter: ; zoom: 1" alt="豆瓣 Google Analytics 代码" src="http://pic.fairyfish.com/2009/07/douban-ga.jpg" loaded="true" original="http://pic.fairyfish.com/2009/07/douban-ga.jpg" jquery1284642036359="40" /><br />
豆瓣 Google Analytics 代码 </p>
<p>我们知道一般默认的 Google Analytics代码如下：</p>
<p class="entry_img"><img style="display: inline; filter: ; zoom: 1" alt="默认  Google Analytics 统计代码" src="http://pic.fairyfish.com/2009/07/ga-default.jpg" loaded="true" original="http://pic.fairyfish.com/2009/07/ga-default.jpg" jquery1284642036359="41" /><br />
默认 Google Analytics 统计代码 </p>
<p>两相对比，我们就会发现豆瓣加载 <code>ga.js </code>的方式与默认的方式有些不太一样，由于豆瓣并没有采用 https 加密访问，所以撇弃了默认的ga.js加载方式。</p>
<p>默认的统计函数，<code>pageTracker </code>也被豆瓣改成了 <code>_ga</code> ，这个只是名称定义上的区别，并没有什么实质的改变。豆瓣的主要应用是下面两个函数：</p>
<h3>使用 _ga._addOrganic 识别非主流搜索引擎</h3>
<p>再来看豆瓣比默认 Google Analytics 代码增加的部分，那就是多了数个 <code>_ga._addOrganic </code>，这是 Google Analytics 添加自定义搜索引擎的代码。尽管 Google Analytics 对于主流的搜索引擎都能自动识别，但毕竟能识别的是国外的主流搜索引擎，在国内，像搜狐的 Sogou，QQ 的 soso，网易的有道等搜索引擎，<strong>都不能被 Google Analytics 正确识别，而被当作推荐来源</strong>。这时候我们就可以利用<code>_addOrganic</code> 参数来识别这些非主流搜索引擎，如豆瓣的做法。</p>
<h3>使用 _addIgnoredOrganic 忽略关键字</h3>
<p>除了添加自定义搜索引擎，豆瓣在最后还添加了如下这些代码:</p>
<pre>_ga._addIgnoredOrganic("豆瓣");
_ga._addIgnoredOrganic("douban");
_ga._addIgnoredOrganic("豆瓣网");
_ga._addIgnoredOrganic("www.douban.com");
</pre>
<p>这些代码用来把引号中的关键词从搜索引擎的关键词报告中排除，而当成直接点击量来源。</p>
<p>为什么要这么做？因为一个知名的大网站，来自这些品牌词的搜索流量都非常大，常常是排在前几位的搜索关键词来源，而这通常是因为搜索引擎养成现在的人都懒得记网址，直接搜索品牌名来记住域名。这些品牌词对于网站的关键词来源分析并没有很直接的帮助，所以在来自品牌词的流量很大的情况下，可以直接把这些关键词识别成直接点击量来源。</p>
<p>关于<strong>自定义 Google Analytics 搜索引擎</strong>和<strong>排除特定关键词为直接点击量来源</strong>的语法，可以参考<a class="external" title="_addOrganic() 与 _addIgnoredOrganic() 用法介绍" href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiSearchEngines.html" target="_blank"> Google Code 上关于这方面的详细介绍。</a></p>
<h2>通过 _setVar 识别用户</h2>
<p>当我们登录豆瓣后，再来分析豆瓣的源码，会发现多了一个<code>ga._setVar(&#8221;xxxx&#8221;)</code>的 Google Analytics 参数。</p>
<p class="entry_img"><img style="display: inline; filter: ; zoom: 1" alt="豆瓣使用 Google Analytics 的._setVar参数来跟踪登录用户行为" src="http://pic.fairyfish.com/2009/07/douban-set_var.jpg" loaded="true" original="http://pic.fairyfish.com/2009/07/douban-set_var.jpg" jquery1284642036359="44" /><br />
豆瓣使用 Google Analytics 的._setVar参数来跟踪登录用户行为 </p>
<p><code>_setVar()</code> 函数是 Google Analytics 的用户定义函数，主要用于对特定来源的用户行为进行分类，例如可以对登录浏览的用户设置一个数值，然后在 Google Analytics 后台的<strong>访问者/用户定义</strong> 中查看其浏览属性。</p>
<p class="entry_img"><img style="display: inline; filter: ; zoom: 1" alt="Google Analytics 访问者/用户定义报告" src="http://pic.fairyfish.com/2009/07/user-define.jpg" width="600" loaded="true" original="http://pic.fairyfish.com/2009/07/user-define.jpg" jquery1284642036359="45" /><br />
Google Analytics 访问者/用户定义报告 </p>
<p>分析豆瓣的源码可以知道，豆瓣对每一个登录后的用户，都赋以一个专门的 id 值，这样可以在用户定义报告里，看到整体的登录用户访问行为，乃至每个登录用户的浏览行为。通过这样设定后，豆瓣便可以轻易获取高忠诚度访问用户的访问行为。<a class="external" title="_setVar 设置说明" href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html#_gat.GA_Tracker_._setVar" target="_blank">关于_setVar()的更多说明，请参阅 Google Analytics的技术文档</a></p>
<p>如何根据访问者在我的网站上访问的页面或在表单上做出的响应对其进行分类？<a class="external" title=" 如何根据访问者在我的网站上访问的页面或在表单上做出的响应对其进行分类？" href="http://www.google.com/support/googleanalytics/bin/answer.py?hlrm=en&amp;answer=57045" target="_blank">在 Google Analytics 官方的帮助文件，也给出了另外一个应用案例</a></p>
<p>值得注意的是，原来在设置 <code>_setVar()</code> 函数的时候，整个网站的跳出率会出现重大的偏差，不过在<a class="external" title="Google Analytics修正_setVar函数对网站跳出率的影响" href="http://analytics.blogspot.com/2009/01/using-setvar-heres-update-on-bounce.html" target="_blank">最近的google analytics官方博客，指出该bug已经修正</a>，客户在进行这方面设置的时候，还是要注意对比前后数据是否有重大偏差。</p>
<h2>通过 _trackPageview 区分不同类型的评论</h2>
<p>豆瓣上的书评，影评和乐评可以说是豆瓣网站的核心价值所在。一般评论的URL格式如下：</p>
<p class="entry_img"><img style="display: inline; filter: ; zoom: 1" alt="豆瓣上单条评论的URL" src="http://pic.fairyfish.com/2009/07/douban-url.jpg" loaded="true" original="http://pic.fairyfish.com/2009/07/douban-url.jpg" jquery1284642036359="48" /><br />
豆瓣上单条评论的URL </p>
<p>当我们查看该页面的网页源代码时，会发现有趣的现象:</p>
<p class="entry_img"><img style="display: inline; filter: ; zoom: 1" alt="豆瓣单条评论页的 Google Analytics 代码" src="http://pic.fairyfish.com/2009/07/douban_trackpageview.jpg" loaded="true" original="http://pic.fairyfish.com/2009/07/douban_trackpageview.jpg" jquery1284642036359="49" /><br />
豆瓣单条评论页的 Google Analytics 代码 </p>
<p>我们知道，一般 Google Analytics 的<code>_trackPageview()</code> 括弧中的参数是留空的， Google Analytics 会自动捕获网址的 URL 参数，如果在 <code>_trackPageview()</code>括弧中输入特定的数值，那么在 Google Analytics 的报表中，URL 将是我们指定的参数，而不再是我们在地址栏看到的 URL。</p>
<p>如上面的例子，我们在 Google Analytics 中看到的URL将是<span style="color: #ff0000">/book/review/1946018/</span>，而不再是我们在浏览器地址栏看到的<span style="color: #ff0000">/review/1946018/</span></p>
<p>当所在频道是电影或者音乐时，<code>_trackPageview()</code> 中的参数将根据所在频道的属性，变为/movie/xxxxx 或者 /music/xxxxx的数值。</p>
<p>豆瓣通过对的参数进行重新指定，主要有以下的好处：</p>
<p>保证了用户和搜索引擎看到的 URL 比较简短，达到 URL 对用户友好和对搜索引擎友好的目的；而在 Google Analytics 报告中，通过 <span style="color: #ff0000">内容/内容细目/ </span>报告，又能了解到各个频道总的浏览情况。</p>
<p>在GA的<span style="color: #ff0000">内容细目</span>报告中，将会多出 <span style="color: #ff0000">/book/ /music/ /movie/</span> 这样的文件夹来，总而获得各个频道的合计浏览数据。</p>
<p>而如果只是使用默认 <code>_trackPageview()</code>，你将只能得到所有评论页面的浏览数据，而无法得到细分的各个频道的浏览数据。</p>
<p>关于<code>_trackPageview()</code>的具体的使用方法<a class="external" title="_trackPageview中参数的使用" href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApi.html#_gat.GA_Tracker_._trackPageview" target="_blank">可参照 Google Code 的说明</a></p>
<p>注意事项:使用 <code>_trackPageview()</code> 参数重新指定 URL 之后，网站覆盖图的数据将受到影响。<a class="external" href="http://www.google.com/support/analytics/bin/answer.py?hl=cn&amp;answer=66982" target="_blank">可参阅 Google Analytics 的官方帮助文件</a></p>
<p>除了豆瓣使用 <code>_trackPageview()</code> 来对URL进行重写，<a class="external" href="http://www.dianping.com/" target="_blank">大众点评网</a>也采用了类似的做法（应该是比豆瓣更早采用。。。因为是我在点评网任职时候实验的做法;那时候豆瓣还没有使用 Google Analytis 统计代码，呵呵），有兴趣的同学可以自己去研究点评的 Google Analytis 代码。<br />
</p>
<p>文章来自：http://fairyfish.net/2009/06/30/google-analytics-in-douban/<br />
<br />
----------------------------------------大众点评网的的代码，主页的<br />
&lt;script type="text/javascript"&gt;<br />
var pageTracker = _gat._getTracker("UA-464026-1");<br />
pageTracker._addOrganic("soso", "w");<br />
pageTracker._addOrganic("sogou", "query");<br />
pageTracker._addOrganic("yodao", "q");<br />
pageTracker._addOrganic("bing", "q");<br />
pageTracker._addOrganic("gougou", "search");<br />
pageTracker._initData();<br />
pageTracker._trackPageview("home/beijing_all");<br />
&lt;/script&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;这个是子页面search/category/2/10/g328<br />
&lt;script type="text/javascript"&gt;<br />
var pageTracker = _gat._getTracker("UA-464026-1");<br />
pageTracker._addOrganic("soso", "w");<br />
pageTracker._addOrganic("sogou", "query");<br />
pageTracker._addOrganic("yodao", "q");<br />
pageTracker._addOrganic("bing", "q");<br />
pageTracker._addOrganic("gougou", "search");<br />
pageTracker._initData();<br />
pageTracker._trackPageview("dp_searchpv_card");<br />
pageTracker._trackPageview("dp_searchpv_promo");<br />
pageTracker._trackPageview("search/beijing_food_category/g328");<br />
&lt;/script&gt;<br />
可以看出其中的pageTracker._trackPageview("。。。");是动态的也就是页面的，我们可以动态的赋值，这样就可以显示正确的地址了。</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;大家如果有什么这方面的经验可以一同分享下。<br />
<br />
&nbsp;&nbsp;&nbsp; </p>
<img src ="http://www.blogjava.net/freeman1984/aggbug/332234.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-09-16 21:37 <a href="http://www.blogjava.net/freeman1984/archive/2010/09/16/332234.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用tomcat的compression来提高网页加载速度</title><link>http://www.blogjava.net/freeman1984/archive/2010/09/15/332121.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Wed, 15 Sep 2010 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/09/15/332121.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/332121.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/09/15/332121.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/332121.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/332121.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当网站从服器端请求的数据较大时，在有限的带宽下就会造成浏览器加载缓慢，有时候会造成页面没有响应，使用户体验变得很差，tomcat为我们提供了有效的解决了办法，就是使用压缩来解决传输问题。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tomcat使用HTTP/1.1 GZIP&nbsp;来压缩，以减少带宽压力，<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先介绍下gzip：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40％.这样传输就快了,效果就是你点击网址后会很快的显示出来.当然这也会增加服务器的负载.&nbsp;一般服务器中都安装有这个功能模块的.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们使用简单的例子来介绍tomcat的压缩使用：（使用firebug查看请求情况）<br />
<br />
&nbsp;首先是一个简单的servlet：<br />
内容：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doPost(HttpServletRequest&nbsp;request,&nbsp;HttpServletResponse&nbsp;response)<br />
<img id="Codehighlighter1_117_696_Open_Image" onclick="this.style.display='none'; Codehighlighter1_117_696_Open_Text.style.display='none'; Codehighlighter1_117_696_Closed_Image.style.display='inline'; Codehighlighter1_117_696_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_117_696_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_117_696_Closed_Text.style.display='none'; Codehighlighter1_117_696_Open_Image.style.display='inline'; Codehighlighter1_117_696_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;ServletException,&nbsp;IOException&nbsp;</span><span id="Codehighlighter1_117_696_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_117_696_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(</span><span style="color: #000000">"</span><span style="color: #000000">text/html</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrintWriter&nbsp;out&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;response.getWriter();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.println(</span><span style="color: #000000">"</span><span style="color: #000000">&lt;!DOCTYPE&nbsp;HTML&nbsp;PUBLIC&nbsp;\</span><span style="color: #000000">"</span><span style="color: #000000">-</span><span style="color: #008000">//</span><span style="color: #008000">W3C</span><span style="color: #008000">//</span><span style="color: #008000">DTD&nbsp;HTML&nbsp;4.01&nbsp;Transitional</span><span style="color: #008000">//</span><span style="color: #008000">EN\"&gt;");</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(</span><span style="color: #000000">"</span><span style="color: #000000">&lt;HTML&gt;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;&lt;HEAD&gt;&lt;TITLE&gt;A&nbsp;Servlet&lt;/TITLE&gt;&lt;/HEAD&gt;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;&lt;BODY&gt;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.print(</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&lt;select&gt;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_465_581_Open_Image" onclick="this.style.display='none'; Codehighlighter1_465_581_Open_Text.style.display='none'; Codehighlighter1_465_581_Closed_Image.style.display='inline'; Codehighlighter1_465_581_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_465_581_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_465_581_Closed_Text.style.display='none'; Codehighlighter1_465_581_Open_Image.style.display='inline'; Codehighlighter1_465_581_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">100000</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_465_581_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_465_581_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.print(</span><span style="color: #000000">"</span><span style="color: #000000">&lt;option&gt;testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">i</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000">&lt;/option&gt;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(</span><span style="color: #000000">"</span><span style="color: #000000">&lt;/select&gt;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;&lt;/BODY&gt;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(</span><span style="color: #000000">"</span><span style="color: #000000">&lt;/HTML&gt;</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.flush();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.close();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
我们将输出一个十万个选项的下拉框，在不使用的压缩的时候：<br />
<img height="476" alt="" src="http://www.blogjava.net/images/blogjava_net/freeman1984/g1.JPG" width="821" border="0" /><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;请求数据达到9m ,大概的计算下我的下载用时（4m长城宽带）：9*1024/(4*1024/8)=18m&nbsp; ，加上多人共享带宽，也就是差不多20m。firebug显示20.96。<br />
<br />
&nbsp;&nbsp;&nbsp; 这个速度网站体验肯定是很差的，接下来使用tomcat的压缩以后看看：<br />
<br />
&nbsp;&nbsp; 当然是要对其进行配置：<br />
&nbsp;&nbsp; 有以下几个参数可以使用：<br />
<br />
&nbsp;&nbsp;&nbsp; compression="on"&nbsp;<br />
是否启用压缩 on为启用（文本数据压缩） off为不启用， force 压缩所有数据<br />
compressionMinSize1="2048"&nbsp;<br />
当超过最小数据大小才进行压缩<br />
&nbsp;noCompressionUserAgents="gozilla, traviata"&nbsp;<br />
哪些客户端发出的请求不压缩，默认是不限制<br />
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"<br />
配置想压缩的数据类型，默认是&nbsp;<code>text/html,text/xml,text/plain<br />
</code><br />
配置以后是这样的：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;</span><span style="color: #000000">Connector&nbsp;port</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">8088</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;protocol</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">HTTP/1.1</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectionTimeout</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">20000</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirectPort</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">8443</span><span style="color: #000000">"</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compression</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">on</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compressionMinSize1</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">2048</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;noCompressionUserAgents</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">gozilla,&nbsp;traviata</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compressableMimeType</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">text/html,text/xml,text/javascript,text/css,text/plain</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span></div>
<br />
启动后再看：<br />
<img height="523" alt="" src="http://www.blogjava.net/images/blogjava_net/freeman1984/g2.JPG" width="803" border="0" /><br />
&nbsp;<br />
这次数据被压缩到274.7k，响应速度也减少了一半，当然，服务器的数据压缩和浏览器的数据解压都需要使用时间。<br />
<br />
&nbsp; <br />
例子完毕，<br />
&nbsp;&nbsp; 当然tomcat的压缩技术还有很多其他的特性，然而对于大数据量的请求不光是要使用这种技术，还需要在其他地方下功夫，比如ajax技术，缓存等等，<br />
也希望大家补充学习，谢谢。<br />
&nbsp; <br />
<img src ="http://www.blogjava.net/freeman1984/aggbug/332121.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-09-15 23:39 <a href="http://www.blogjava.net/freeman1984/archive/2010/09/15/332121.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QQ 导致mysql 服务无法启动</title><link>http://www.blogjava.net/freeman1984/archive/2010/09/06/331173.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Mon, 06 Sep 2010 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/09/06/331173.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/331173.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/09/06/331173.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/331173.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/331173.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 今天启动mysql的时候，发现一起无法启动，然后就去检查3306是否被占用，结果使用netstat -ano 一看如下：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/freeman1984/qq.JPG" /><br />
<br />
结果一看竟然被qq进程占用着，并且处于close_wait状态。<br />
处理方法：直接干掉qq进程，然后启动mysql即可。<br />
<br />
以下是关于tcp 状态一些介绍 供大家参考：<br />
&nbsp;Close_Wait<span style="color: blue; font-size: 14pt">状态解释</span>
<p style="text-align: left; line-height: 17.25pt; margin: 0cm 0cm 0pt" class="MsoNormal" align="left">CLOSE_WAIT状态的生成原因<br />
通过TCP的状态图我们可以看出只有被动关闭的一端才有CLOSE_WAIT状态，当收到Fin并发送了Ack后<br />
服务器状态就变成了CLOSE_WAIT状态，如果我们的服务器一直处于CLOSE_WAIT状态的话，说明套接字是被动关闭的！，并且没有发送Fin信令，原因往往是没有调用TCP的CloseSocket。</p>
<p style="text-align: left; line-height: 17.25pt; margin: 0cm 0cm 0pt" class="MsoNormal" align="left">解决CLOSE_WAIT的方法:<br />
1 一般原因都是TCP连接没有调用关闭方法。需要应用来处理网络链接关闭。<br />
2 对于Web请求出现这个原因，经常是因为Response的BodyStream没有调用Close.<br />
比如Widnows下:<br />
使用HttpWebRequest 一定要保证GetRequestStream和GetResponse对象关闭，否则容易造成连接处于CLOSE_WAIT状态<br />
3 TCP的KeepLive功能，可以让操作系统替我们自动清理掉CLOSE_WAIT的连接。<br />
但是KeepLive在Windows操作系统下默认是7200秒，也就是2个小时才清理一次。往往满足不了要求。可以调小该数值。<br />
Windows下的调整方法为<br />
HKEY_LOCAL_MACHINE"CurrentControlSet"Services"Tcpip"Parameters下的以下三个参数： <br />
KeepAliveInterval,设置其值为1000 <br />
KeepAliveTime,设置其值为300000(单位为毫秒，300000代表5分钟) <br />
TcpMaxDataRetransmissions,设置其值为5</p>
<p style="text-align: left; line-height: 17.25pt; margin: 0cm 0cm 0pt" class="MsoNormal" align="left">Close_Wait引发的问题:<br />
Close_Wait会占用一个连接，网络可用连接小。数量过多，可能会引起网络性能下降，并占用系统非换页内存。 尤其是在有连接池的情况下(比如HttpRequest)<br />
会耗尽连接池的网络连接数，导致无法建立网络连接</p>
--------------------------------------------<br />
TCP状态转移要点<br />
&nbsp; &nbsp; TCP协议规定，对于已经建立的连接，网络双方要进行四次握手才能成功断开连接，如果缺少了其中某个步骤，将会使连接处于假死状态，连接本身占用的资源不会被释放。网络服务器程序要同时管理大量连接，所以很有必要保证无用连接完全断开，否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中，最值得注意的状态有两个：CLOSE_WAIT和TIME_WAIT。&nbsp;&nbsp;<br />
<br />
1、LISTENING状态<br />
　　FTP服务启动后首先处于侦听（LISTENING）状态。<br />
2、ESTABLISHED状态<br />
　　ESTABLISHED的意思是建立连接。表示两台机器正在通信。<br />
<font color="#ff0000">3、CLOSE_WAIT</font><br />
&nbsp; &nbsp; 对方主动关闭连接或者网络异常导致连接中断，这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭<br />
<font color="#ff0000">4、TIME_WAIT</font><br />
&nbsp; &nbsp; 我方主动调用close()断开连接，收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分段最大生存期)，以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放，所以作为服务器，在可能的情况下，尽量不要主动断开连接，以减少TIME_WAIT状态造成的资源浪费。 <br />
&nbsp; &nbsp; 目前有一种避免TIME_WAIT资源浪费的方法，就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的，在某些情况下这个操作可能会带来错误。 <br />
<br />
详细一点的文档：<br />
http://apps.hi.baidu.com/share/detail/10908121
<img src ="http://www.blogjava.net/freeman1984/aggbug/331173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-09-06 10:59 <a href="http://www.blogjava.net/freeman1984/archive/2010/09/06/331173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>尽可能使用堆栈变量</title><link>http://www.blogjava.net/freeman1984/archive/2010/01/29/311223.html</link><dc:creator>疯狂</dc:creator><author>疯狂</author><pubDate>Fri, 29 Jan 2010 06:56:00 GMT</pubDate><guid>http://www.blogjava.net/freeman1984/archive/2010/01/29/311223.html</guid><wfw:comment>http://www.blogjava.net/freeman1984/comments/311223.html</wfw:comment><comments>http://www.blogjava.net/freeman1984/archive/2010/01/29/311223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freeman1984/comments/commentRss/311223.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freeman1984/services/trackbacks/311223.html</trackback:ping><description><![CDATA[<p>如果您频繁存取变量，就需要考虑从何处存取这些变量。变量是
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">static</pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
变量，还是堆栈变量，或者是类的实例变量？变量的存储位置对存取它的代码的性能有明显的影响？例如，请考虑下面这段代码： </p>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">class StackVars
            {
            private int instVar;
            private static int staticVar;
            //存取堆栈变量
            void stackAccess(int val)
            {
            int j=0;
            for (int i=0; i&lt;val; i++)
            j += 1;
            }
            //存取类的实例变量
            void instanceAccess(int val)
            {
            for (int i=0; i&lt;val; i++)
            instVar += 1;
            }
            //存取类的 static 变量
            void staticAccess(int val)
            {
            for (int i=0; i&lt;val; i++)
            staticVar += 1;
            }
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>这段代码中的每个方法都执行相同的循环，并反复相同的次数。唯一的不同是每个循环使一个不同类型的变量递增。方法
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">stackAccess</pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
使一个局部堆栈变量递增， <code>instanceAccess</code> 使类的一个实例变量递增，而 <code>staticAccess</code> 使类的一个 <code>static</code> 变量递增。 </p>
<p><code>instanceAccess</code> 和 <code>staticAccess</code> 的执行时间基本相同。但是， <code>stackAccess</code> 要快两到三倍。存取堆栈变量如此快是因为，JVM 存取堆栈变量比它存取 <code>static</code> 变量或类的实例变量执行的操作少。请看一下为这三个方法生成的字节码： </p>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">Method void stackAccess(int)
            0 iconst_0         //将 0 压入堆栈。
            1 istore_2         //弹出 0 并将它存储在局部分变量表中索引为 2 的位置 (j)。
            2 iconst_0         //压入 0。
            3 istore_3         //弹出 0 并将它存储在局部变量表中索引为 3 的位置 (i)。
            4 goto 13          //跳至位置 13。
            7 iinc 2 1         //将存储在索引 2 处的 j 加 1。
            10 iinc 3 1         //将存储在索引 3 处的 i 加 1。
            13 iload_3          //压入索引 3 处的值 (i)。
            14 iload_1          //压入索引 1 处的值 (val)。
            15 if_icmplt 7      //弹出 i 和 val。如果 i 小于 val，则跳至位置 7。
            18 return           //返回调用方法。
            Method void instanceAccess(int)
            0 iconst_0         //将 0 压入堆栈。
            1 istore_2         //弹出 0 并将它存储在局部变量表中索引为 2 的位置 (i)。
            2 goto 18          //跳至位置 18。
            5 aload_0          //压入索引 0 (this)。
            6 dup              //复制堆栈顶的值并将它压入。
            7 getfield #19 &lt;Field int instVar&gt;
            //弹出 this 对象引用并压入 instVar 的值。
            10 iconst_1         //压入 1。
            11 iadd             //弹出栈顶的两个值，并压入它们的和。
            12 putfield #19 &lt;Field int instVar&gt;
            //弹出栈顶的两个值并将和存储在 instVar 中。
            15 iinc 2 1         //将存储在索引 2 处的 i 加 1。
            18 iload_2          //压入索引 2 处的值 (i)。
            19 iload_1          //压入索引 1 处的值 (val)。
            20 if_icmplt 5      //弹出 i 和 val。如果 i 小于 val，则跳至位置 5。
            23 return           //返回调用方法。
            Method void staticAccess(int)
            0 iconst_0         //将 0 压入堆栈。
            1 istore_2         //弹出 0 并将它存储在局部变量表中索引为 2 的位置 (i)。
            2 goto 16          //跳至位置 16。
            5 getstatic #25 &lt;Field int staticVar&gt;
            //将常数存储池中 staticVar 的值压入堆栈。
            8 iconst_1         //压入 1。
            9 iadd             //弹出栈顶的两个值，并压入它们的和。
            10 putstatic #25 &lt;Field int staticVar&gt;
            //弹出和的值并将它存储在 staticVar 中。
            13 iinc 2 1         //将存储在索引 2 处的 i 加 1。
            16 iload_2          //压入索引 2 处的值 (i)。
            17 iload_1          //压入索引 1 处的值 (val)。
            18 if_icmplt 5      //弹出 i 和 val。如果 i 小于 val，则跳至位置 5。
            21 return           //返回调用方法。
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>查看字节码揭示了堆栈变量效率更高的原因。JVM 是一种基于堆栈的虚拟机，因此优化了对堆栈数据的存取和处理。所有局部变量都存储在一个局部变量表中，在 Java 操作数堆栈中进行处理，并可被高效地存取。存取 <code>static</code> 变量和实例变量成本更高，因为 JVM 必须使用代价更高的操作码，并从常数存储池中存取它们。（常数存储池保存一个类型所使用的所有类型、字段和方法的符号引用。） </p>
<p>通常，在第一次从常数存储池中访问 <code>static</code> 变量或实例变量以后，JVM 将动态更改字节码以使用效率更高的操作码。尽管有这种优化，堆栈变量的存取仍然更快。 </p>
<p>考虑到这些事实，就可以重新构建前面的代码，以便通过存取堆栈变量而不是实例变量或 <code>static</code> 变量使操作更高效。请考虑修改后的代码： </p>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">class StackVars
            {
            //与前面相同...
            void instanceAccess(int val)
            {
            int j = instVar;
            for (int i=0; i&lt;val; i++)
            j += 1;
            instVar = j;
            }
            void staticAccess(int val)
            {
            int j = staticVar;
            for (int i=0; i&lt;val; i++)
            j += 1;
            staticVar = j;
            }
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>方法 <code>instanceAccess</code> 和 <code>staticAccess</code> 被修改为将它们的实例变量或 <code>static</code> 变量复制到局部堆栈变量中。当变量的处理完成以后，其值又被复制回实例变量或 <code>static</code> 变量中。这种简单的更改明显提高了 <code>instanceAccess</code> 和 <code>staticAccess</code> 的性能。这三个方法的执行时间现在基本相同， <code>instanceAccess</code> 和 <code>staticAccess</code> 的执行速度只比 <code>stackAccess</code> 的执行速度慢大约 4%。 </p>
<p>这并不表示您应该避免使用 <code>static</code> 变量或实例变量。您应该使用对您的设计有意义的存储机制。例如，如果您在一个循环中存取 <code>static</code> 变量或实例变量，则您可以临时将它们存储在一个局部堆栈变量中，这样就可以明显地提高代码的性能。这将提供最高效的字节码指令序列供 JVM 执行<br />
转载自ibm</p>
 <img src ="http://www.blogjava.net/freeman1984/aggbug/311223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freeman1984/" target="_blank">疯狂</a> 2010-01-29 14:56 <a href="http://www.blogjava.net/freeman1984/archive/2010/01/29/311223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>