??xml version="1.0" encoding="utf-8" standalone="yes"?>91亚洲精品视频,亚洲av无码专区在线播放,亚洲丝袜美腿视频http://www.tkk7.com/freeman1984/category/43783.htmlSTANDING ON THE SHOULDERS OF GIANTS zh-cnMon, 05 Jun 2017 07:53:49 GMTMon, 05 Jun 2017 07:53:49 GMT60oracle 索引字段包含datecdQ用spring jdbc更新时不走烦引,而是走table access full的问?/title><link>http://www.tkk7.com/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.tkk7.com/freeman1984/archive/2015/11/15/428197.html</guid><wfw:comment>http://www.tkk7.com/freeman1984/comments/428197.html</wfw:comment><comments>http://www.tkk7.com/freeman1984/archive/2015/11/15/428197.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/freeman1984/comments/commentRss/428197.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/freeman1984/services/trackbacks/428197.html</trackback:ping><description><![CDATA[     摘要: oracle 索引字段包含datecdQ用spring jdbc更新时不走烦引,而是走table access full的问?nbsp; <a href='http://www.tkk7.com/freeman1984/archive/2015/11/15/428197.html'>阅读全文</a><img src ="http://www.tkk7.com/freeman1984/aggbug/428197.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/freeman1984/" target="_blank">疯狂</a> 2015-11-15 00:04 <a href="http://www.tkk7.com/freeman1984/archive/2015/11/15/428197.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>A/B试(转蝲)http://www.tkk7.com/freeman1984/archive/2012/08/28/386419.html疯狂疯狂Tue, 28 Aug 2012 03:41:00 GMThttp://www.tkk7.com/freeman1984/archive/2012/08/28/386419.htmlhttp://www.tkk7.com/freeman1984/comments/386419.htmlhttp://www.tkk7.com/freeman1984/archive/2012/08/28/386419.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/386419.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/386419.htmlA / B试不是一个时髦名词。现在很多有l验的营销和设计工作者用它来获得访客行ؓ信息Q来提高转换率。然而, A / B试与SEO不同的是Qh们都不太知道徒河q行|站分析和可用性分析。他们ƈ不完全明白它是什么或如何更有效的使用它。本文将Z提供有史以来最好的A / B试教程?/p>

什么是A/B试?

A / B试的核心就是:定两个元素或版本(A和BQ哪个版本更好,你需要同时实验两个版本。最后,选择最好的版本使用?/p>

|络上的A / B试Q即你设计的面有两个版本(A和BQ,A为现行的设计Q称为控Ӟ Q?B是新的设计。比较这两个版本之间你所兛_的数据(转化率,业WQ蟩出率{) 。最后,您选择效果最好的版本?/p>

试哪些东西?

你要选择什么去试取决于你的目标。例如,如果你的目标是增加顾客数量,那么您可能测试下列内容:注册表单数量Q字D늱型要求,隐私政策{。在q种情况下A / B试的目标是要弄清楚什么阻止了游客注册。需要填写的表单的数量?用户的隐U?q是该网站做了让游客不信ȝ事情Q所有这些问题都可以通过一个个A/B 试获得{案?/p>

每一个A / B试内容都是独一无二的,单通常试一下这些内容:

  • 行动按钮的措辞,大小Q颜色和位置Q?/li>
  • 标题或品说明,
  • 表单的数量和字段cdQ?/li>
  • |站的布局和风|
  • 产品定h和促销zdQ?/li>
  • 着陆和产品面上的囄Q?/li>
  • 面上文字的长度Q少Vs多)?/li>

一旦你军_要测试什么,下一步当然是要选择一个合适的试工具。如果你惌一个基的免费工P可以使用Google Website Optimizer。如果你惌功能更加强大的工P可以使用Visual Website Optimizer  。其他的一些选择都是可以的,建立试验在所有工具中都很怼Q所以我们只需讨论一U即可?/p>

你可以通过两种Ҏ建立A / B试Q?/p>

  • 在页面测试加载前替换元素
    如果你测试的是页面上的单个元素,如注册按钮,然后需要在试工具中设|按钮。当试Ӟ在A / B工具在面l用户前随机替换按钮?/li>
  • 重定向到另一面
    如果你想通过A / B试整个面Q比如说Q一个绿色的主题和一个红色主题,那么你就需要创建和上传新的面。例如,如果您的主页?http://www.example.com/index.htmlQ那么你需要创建另外一个页?http://www.example.com/index1.html。当试q行Ӟ您的试工具一部分讉K者重定向到第二个|址?/li>

一旦您使用了上面的两种变换ҎQ下一步是建立您的转换目标。通常Q你会得C个JavaScript代码Q您可以复制q粘贴到一个需要游客到辄目标|页。例如,如果您有一个电子商务网站,你正在测试的“立即购买“按钮的颜Ԍ然后您的转换目标是购买成功后的“谢谢?#8220;面?/p>

在{换事件发生的同时Q在A / B试工具Q记录了哪种面昄l了讉K者。经q够数量的游客Q您可以定哪个面带来了最多的转化Q徏立和q行的A / B试Q其实很单?/p>

该做什么和不该做什?/strong>

虽然A / B试是超U简单的概念Q但是请CQ以下这些都只是我自ql验?/p>

注意事项

需要做?/strong>

  • 知道q行试多久。结束太早,可能会你花了时间但是没有得到有意义的结果。结束太晚也不好Q因为效果不佳的面可能影响你的转化和业l。用一?a href="http://visualwebsiteoptimizer.com/ab-split-test-duration/">计算?/a>Q来定试多久以后来结束它?/li>
  • 相同的面呈献l同一个访客。您的工具应该有一个记忆访问者已l看到的面的功能。这样可以防止向同一用户昄一不同的h格或不同的促销优惠?/li>
  • 让您的A / B试在整个网站保持一致。如果你正在试的登录按钮在多个地点出现Q然后一个访问者应在所有的地方看到同样的变化。在面1昄一个样子,在页?昄两外一个样子,会试验l果被干扰?/li>
  • 做很多的A / B试。让我们面对现实吧:你的W一个A / B试可能会无效。但是不要绝望。一个A / B试只能有三个结果:没有l果Q不好的l果和好的结果。优化{换率的关键是要做大量的A / B试Q把所有的好的l果拼接hQ最l推动业l?/li>

l典A/B试案例研究

q里有一些如何进行A/B试的案例研I?/p>

Writing Decisions: Headline Tests on the Highrise Sign-Up Page 37Signals试他们的h格页面的标题。最l发玎ͼ “30-Day Free Trial on All Accounts “比原来的“Start a Highrise Account. “多?0 Q以上的订单?/p>

“You Should Follow Me on Twitter Here” (Dustin Curtis) q是一个用来测试召唤用户在Twitter上关注自q试验? Dustin 发现提示文字?#8220;You should follow me on Twitter here” 的效果是“I’m on Twitter.” 173%

Human Photos Double Conversion Rates 从两个不同的A / B试在|站上增加{换率的h的照片:一个oZo人惊讶的l论QA/B试两张囄Q将真h照片攑֜|站上会获得一倍的转化。研I说明,我们潜意识被照片吸引了?/p>

Google Website Optimizer Case Study: Daily Burn, 20%+ Improvement (Tim Ferriss) 一个将用户选择减少的变化转化提高?0%Q最l的版本在细节和文字上更易吸引目光?/p>

Two Magical Words Increased Conversion Rate by 28% “It’s free” q个单词增加了注册按钮点L数的28%, 试l果表明Q在行动召唤上一些很的变化会带来o人惊讶的l果?/p>

Changing the Sign-Up Button from Green to Red 依靠A / B试Q?CareLogger把注册按钮从l色修改为红色增加了34Q{换率Q?/p>

Single page vs. multi-step checkout 如果你有一个在U商店,很常见的是支付程。这个A / B试发现Q多个支付流E比单个支付程完成的销售更好?/p>

“Mad Libs” style form increases conversion 25-40% 打|传统的智慧,此A / B试发现一D风?/em>形式输入字段比传lŞ式的布局更好?/p>

Complete redesign of product page increased sales by 20% 一个Y件品的公司重新设计他们的品页l它一个现代的外观和增加信L块。最l结果:他们成功地增?0 Q的总销售额。本案例研究证明了设计对销售的影响?/p>

Marketing Experiments response capture case study – triple digit increase in conversions 通过优化邮g地址获取提高?58 Q。重Ҏ消除所有的q扰Qƈ要求游客只需提供电子邮g地址。用亚马逊礼品卡让他/她的完成个h资料?/p>

A/B试工具

有许多侧重点Qh位和功能不同的A / B试工具Q这里是一些:

一些深入研I的A/B试资料

如果你已l读到这里,那么A / B试大概已经Ȁ起你的兴。在q里Q有一些非常好的A/B试资源?/p>

L你下一个A/B试的灵?/strong>

一些介l性文?/strong>

A/B试中的数学

原文地址Q?a >http://www.smashingmagazine.com/2010/06/24/the-ultimate-guide-to-a-b-testing/
转蝲自:http://ucdchina.com/snap/7203



疯狂 2012-08-28 11:41 发表评论
]]>
apache性能试工具abhttp://www.tkk7.com/freeman1984/archive/2011/12/13/366235.html疯狂疯狂Tue, 13 Dec 2011 06:36:00 GMThttp://www.tkk7.com/freeman1984/archive/2011/12/13/366235.htmlhttp://www.tkk7.com/freeman1984/comments/366235.htmlhttp://www.tkk7.com/freeman1984/archive/2011/12/13/366235.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/366235.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/366235.html使用格式Q?./ab [options] [http://]hostname[:port]/path
参数说明Q?br />    -n requests     Number of requests to perform
    //在测试会话中所执行的请求个数。默认时Q仅执行一个请?/font>
    -c concurrency Number of multiple requests to make
    //一ơ生的h个数。默认是一ơ一个?/font>
    -t timelimit    Seconds to max. wait for responses
    //试所q行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的试限制在一个固定的L间以内。默认时Q没有时间限制?br />    -p postfile     File containing data to POST
    //包含了需要POST的数据的文g.
    -T content-type Content-type header for POSTing
    //POST数据所使用的Content-type头信息?/font>
    -v verbosity    How much troubleshooting info to print
    //讄昄信息的详l程?- 4或更大g昄头信息, 3或更大值可以显C响应代?404, 200{?, 2或更大值可以显C告和其他信息?-V 昄版本号ƈ退出?br />    -w              Print out results in HTML tables
    //以HTML表的格式输出l果。默认时Q它是白色背景的两列宽度的一张表?br />    -i              Use HEAD instead of GET
   // 执行HEADhQ而不是GET?/font>
    -x attributes   String to insert as table attributes
    //
    -y attributes   String to insert as tr attributes
    //
    -z attributes   String to insert as td or th attributes
    //
    -C attribute    Add cookie, eg. 'Apache=1234. (repeatable)
    //-C cookie-name=value 对请求附加一个Cookie:行。其典型形式是name=value的一个参数对。此参数可以重复?/font>
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    //-P proxy-auth-username:password 对一个中转代理提供BASIC认证信Q。用户名和密码由一?隔开Qƈ以base64~码形式发送。无论服务器是否需?? 是否发送了401认证需求代?Q此字符串都会被发送?/font>
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -h              Display usage information (this message)
    //-attributes 讄 属性的字符? ~陷E序中有各种静态声明的固定长度的缓冲区。另外,对命令行参数、服务器的响应头和其他外部输入的解析也很单,q可能会有不良后果。它没有完整地实现HTTP/1.x; 仅接受某?预想'的响应格式?strstr(3)的频J用可能会带来性能问题Q即, 你可能是在测试ab而不是服务器的性能?

参数很多,一般我们用 -c ?-n 参数可以了. 例如:

./ab -c 1000 -n 1000 http://10.88.15.77/test.php

q个表示同时处理1000个请求ƈq行1000ơindex.php文g.
#ab -c 1000 -n 1000 http://10.88.15.77/test.php


Benchmarking 10.88.15.77 (be patient)

Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests


Server Software:        Apache/2.2.8
//q_apache 版本2.2.8
Server Hostname:        10.88.15.77
//服务器主机名
Server Port:            80
//服务器端?/font>

Document Path:          /test.php

//试的页面文?/font>
Document Length:        1018 bytes
//文档大小

Concurrency Level:      1000
//q发?br />Time taken for tests:   8.188731 seconds
//整个试持箋的时?/font>
Complete requests:      1000
//完成的请求数?/font>
Failed requests:        0
//p|的请求数?/font>
Write errors:           0

Total transferred:      1361581 bytes
//整个场景中的|络传输?/font>
HTML transferred:       1055666 bytes
//整个场景中的HTML内容传输?br />Requests per second:    122.12 [#/sec] (mean)
//大家最兛_的指标之一Q相当于 LR 中的 每秒事务?/span> Q后面括号中?/span> mean 表示q是一个^均?/span>
Time per request:       8188.731 [ms] (mean)
//大家最兛_的指标之二,相当?/span> LR 中的 q_事务响应旉 Q后面括号中?/span> mean 表示q是一个^均?/span>
Time per request:       8.189 [ms] (mean, across all concurrent requests)
//每个h实际q行旉的^均?/font>
Transfer rate:          162.30 [Kbytes/sec] received
//q_每秒|络上的量Q可以帮助排除是否存在网l流量过大导致响应时间g长的问题

Connection Times (ms)
              min mean[+/-sd] median   max
Connect:        4 646 1078.7     89    3291
Processing:   165 992 493.1    938    4712
Waiting:      118 934 480.6    882    4554
Total:        813 1638 1338.9   1093    7785
//|络上消耗的旉的分解,各项数据的具体算法还不是很清?/span>

Percentage of the requests served within a certain time (ms)
50%   1093
66%   1247
75%   1373
80%   1493
90%   4061
95%   4398
98%   5608
99%   7368
100%   7785 (longest request)
//整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时_其中50Q的用户响应旉于1093 毫秒Q?0Q?的用户响应时间小?247 毫秒Q最大的响应旉于7785 毫秒

      ׃对于q发hQcpu实际上ƈ不是同时处理的,而是按照每个h获得的时间片逐个轮{处理的,所以基本上W一个Time per request旉U等于第二个Time per request旉乘以q发h?br />转自Q?a >http://blog.sina.com.cn/s/blog_3c9872d00100dbox.html



疯狂 2011-12-13 14:36 发表评论
]]>
select, iocp, epoll,kqueue及各UI/O复用机制http://www.tkk7.com/freeman1984/archive/2011/12/07/365746.html疯狂疯狂Wed, 07 Dec 2011 05:45:00 GMThttp://www.tkk7.com/freeman1984/archive/2011/12/07/365746.htmlhttp://www.tkk7.com/freeman1984/comments/365746.htmlhttp://www.tkk7.com/freeman1984/archive/2011/12/07/365746.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/365746.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/365746.html首先Q介l几U常见的I/O模型及其区别Q如下:

  • blocking I/O

  • nonblocking I/O

  • I/O multiplexing (select and poll)

  • signal driven I/O (SIGIO)

  • asynchronous I/O (the POSIX aio_functions)

blocking I/O
q个不用多解释吧Q阻塞套接字。下图是它调用过E的囄Q?/p>

重点解释下上图,下面例子都会讲到。首先application调用 recvfrom()转入kernelQ注意kernel?个过E,wait for data和copy data from kernel to user。直到最后copy complete后,recvfrom()才返回。此q程一直是d的?/p>

nonblocking I/OQ?/strong>
与blocking I/O对立的,非阻塞套接字Q调用过E图如下Q?/p>

可以看见Q如果直接操作它Q那是个轮询。。直到内核缓冲区有数据?/p>

I/O multiplexing (select and poll)
最常见的I/O复用模型Qselect?/p>

select先阻塞,有活动套接字才返回。与blocking I/O相比Qselect会有两次pȝ调用Q但是select能处理多个套接字?/p>

signal driven I/O (SIGIO)
只有UNIXpȝ支持Q感兴趣的课查阅相关资料

?strong>I/O multiplexing (select and poll)相比Q它的优势是Q免Mselect的阻塞与轮询Q当有活跃套接字Ӟ由注册的handler处理?/p>

asynchronous I/O (the POSIX aio_functions)
很少?nixpȝ支持Qwindows的IOCP则是此模?/p>

完全异步的I/O复用机制Q因为纵观上面其它四U模型,臛_都会在由kernel copy data to appliction旉塞。而该模型是当copy完成后才通知applicationQ可见是U异?/font>的。好像只有windows?font color="#ff0000">完成端口是这个模型,效率也很?/p>

下面是以上五U模型的比较

可以看出Q越往后,d少Q理Z效率也是最优?/p>

=====================分割U?=================================

5U模型的比较比较清晰了,剩下的就是把select,epoll,iocp,kqueue按号入那就OK了?/p>

select和iocp分别对应W?U与W?U模型,那么epoll与kqueue呢?其实也于select属于同一U模型,只是更高U一些,可以看作有了W?U模型的某些Ҏ,如callback机制?/p>

那么Qؓ什么epoll,kqueue比select高Q?

{案是,他们?font color="#ff0000">轮询。因Z们用callback取代了。想想看Q当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调?不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU旉。如果能l套接字注册某个回调函数Q当他们z跃Ӟ自动完成相关操作Q那避免了轮询Q这正是epoll与kqueue做的?/p>

windows or *nix QIOCP or kqueue/epollQ?

诚然QWindows的IOCP非常Q目前很有支持asynchronous I/O的系l,但是׃其系l本w的局限性,大型服务器还是在UNIX下。而且正如上面所qͼkqueue/epoll ?IOCP相比Q就是多了一层从内核copy数据到应用层的阻塞,从而不能算?strong>asynchronous I/OcR?/strong>但是Q这层小的d无轻重Qkqueue与epoll已经做得很优U了?/p>

提供一致的接口QIO Design Patterns

实际上,不管是哪U模型,都可以抽象一层出来,提供一致的接口Q广Zh知的有ACE,Libeventq些Q他们都是跨q_的,而且他们自动选择最优的I/O复用机制Q用户只需调用接口卛_。说到这里又得说?个设计模式,Reactor and Proactor?/strong>有一经典文?a >http://www.artima.com/articles/io_design_patterns.html值得阅读QLibevent?strong>Reactor模型QACE提供Proactor模型。实际都是对各种I/O复用机制的封装?/p>

Java nio包是什么I/O机制Q?/strong>

我曾天真的认为java nio装的是IOCP。。现在可以确定,目前的java本质是select()模型Q可以检?jre/bin/nio.dll得知。至于java服务器ؓ什么效率还不错。。我也不得而知Q可能是设计得比较好吧。?_-?/p>

=====================分割U?=================================

ȝ一些重点:

  1. 只有IOCP是asynchronous I/OQ其他机制或多或都会有一炚w塞?
  2. select低效是因为每ơ它都需要轮询。但低效也是相对的,视情况而定Q也可通过良好的设计改?
  3. epoll, kqueue是Reacor模式QIOCP是Proactor模式?
  4. java nio包是select模型。?

转蝲自:http://blog.csdn.net/shallwake/article/details/5265287



疯狂 2011-12-07 13:45 发表评论
]]>nginx和tomcat负蝲单配|?windows环境)http://www.tkk7.com/freeman1984/archive/2011/12/07/365726.html疯狂疯狂Wed, 07 Dec 2011 02:40:00 GMThttp://www.tkk7.com/freeman1984/archive/2011/12/07/365726.htmlhttp://www.tkk7.com/freeman1984/comments/365726.htmlhttp://www.tkk7.com/freeman1984/archive/2011/12/07/365726.html#Feedback2http://www.tkk7.com/freeman1984/comments/commentRss/365726.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/365726.html阅读全文

疯狂 2011-12-07 10:40 发表评论
]]>
高性能JavaScript(来自高性能JavaScript一?http://www.tkk7.com/freeman1984/archive/2011/10/09/360260.html疯狂疯狂Sun, 09 Oct 2011 03:56:00 GMThttp://www.tkk7.com/freeman1984/archive/2011/10/09/360260.htmlhttp://www.tkk7.com/freeman1984/comments/360260.htmlhttp://www.tkk7.com/freeman1984/archive/2011/10/09/360260.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/360260.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/360260.html高性能JavaScript

一下内Ҏ转蝲的,内容应该高性能JavaScript一书中Q此书值得一诅R?br />
学习q程中写的笔讎ͼ有误h正?/p>

性能q不是唯一的考虑因素Q在Ҏ能要求q苛刻的环境中Q性能也可让位于:团队~码规范Q个人编码习惯,代码可读性,模块可扩展性等因素?/p>

以下提到的对性能的优化,仅仅提供了从性能的角度去阐释一些设计思\Q但实际上,览器本w会逐步优化自n的性能问题Q而我们那些提高性能的hackQ可能会因ؓ览器的版本更新Q导致成ZU无用的hackQ甚臌性能更慢Q所以不要无谓的使用一些hackQ去优化一些执行次数很的代码Q而降低代码的可读性,或增加代码量Q,一句话Q如非必要,请勿hack?/p>

一 javascript加蝲和执?/strong>

1 无论是外链还是内联,script标签都会d面的渲染,所以script标签的位|最好是</body>?br />2 减少httphQ合q多个script文gZ个,1?0k的文件比3?0k的文件蝲入速度要快
3 如何不阻塞页面,而蝲入一个脚本呢Q?br />1Q给script标签加defer属性:<script src=”xxx” defer></script>Q这样不会ə面执行q程dQ但q不是所有浏览器都支持这个defer属?br />2QxmlHttpRequest来请求脚本内容ƈevalQ虽然这样可以灵zȝ控制脚本下蝲q程 ?何时执行Q但不能跨域是个伤
3QcreateElement(‘script’)然后append是个不错的方案,无阻塞,有onload用onloadQIE没有qonreadystatechange实现加蝲完成的事Ӟ注意readyState属性的值是complete或者loaded都要执行回调函数q清除onreadystatechangeQ因两个状态gE_?/p>

4 所以推荐的方式是第三种Q在载入js-loader部分的少量代码后Q就用loaderd载其他js吧,注意一些市面上行的库如labjs实现了这些功?q告下:qwrap实现了依赖管理及动态加?/font>)

?数据讉K
数据存储在:直接量,变量Q数l元素,对象成员中?br />q又让我惌v了编译型的语aQ直接量存在于pe文g?rdataD中Q变量在调用栈上Q数l元素和对象成员的访问需要基址+偏移量来定位Q多层对象嵌套需要多ơ计基址+偏移量来定位?/p>

q些在javascript中依然没有太大变化:

1 直接量的讉K无疑是迅速的

2 变量的访问需要考虑javascript允许函数q行嵌套定义Q也Ş成了Z函数定义的作用域链,而变量的讉KQ可能需要跨作用域来讉KQ所以这里有一Ҏ能损失Q但先进的js引擎用空间换旉Q猜在子作用域中缓存了所有父层作用域链上变量的name和地址Q所以不会进行上溯作用域链,直接执行hash定位卛_Q但一个函C如果包含eval,with,catch块的话,通过静态代码分析就没办法知道该函数中声明了哪些变量Q也无法做到这个优化)Q,不过Q从性能上来看,与我的实际测试,大家~码的时候不需要注意这U性能考虑Q按团队~码规范和个人编码习惯来吧?/p>

3 对象成员的访问要考虑上溯原型链,所以理Z来说讉K实例本n上的成员比访问原型的成员速度要快?/p>

4 多层对象的嵌套要慢,但是在对性能要求q很苛ȝ环境中不用关心这些?/p>

?dom~程

1 dom的访问和修改
1) 标准dom方式(createElement,createTextNode,appendChild) ?字符串拼接后讄innerHTML 之间的性能相差无几Q各个浏览器不同
2) 节点克隆速度快一些,先用createElement创徏好需要用到的元素cd后,以后在@环中调用元素的cloneNode来克?br />3) getElementsByName,getElementsByClassName,getElementsByTagName以及.images,.links,.forms属性返回的都是html集合Q是个类数组Q没有数l的ҎQ但提供了length属性和索引器,QHTML集合处于“实时状?#8221;Q底层文档对象更新时后自动更新javascript中的集合Q访问length时候也会去查询Q所以遍历集合时候要~存length来提高效?br />4) 遍历集合前记录lengthQ@环体中避免对集合中某相同元素q行多次索引Q一ơ烦引到局部变量中Q因为对html集合的烦引性能很差Q特别在某些老浏览器?br />5) 遍历dom节点的话Q综合来说用nextSibling性能会比childNodes快一点,如果只遍历element的话Qchildren被所有浏览器支持Q所以尽量用children而不要用childNodes再自行筛选,其他的如childElementCount,firstElementChild,lastElementChild,nextElementSibling,previousElementSibling不被全面支持Q注意做Ҏ检及兼容处理
6) 注意所使用的类库是否支持原生的querySelectorAll优先规则QquerySelectorAllq回NodeList而不会返回HTML集合Q不存在实时文档l构的性能问题

2 重绘和重?/p>

改变dom节点的几何属性会引v重排(reflow)Q而后发生重绘(repaint)?/p>

׃重排需要生大量的计算Q所以浏览器一般会通过队列化修改ƈ扚w执行来优化重排,获取最新布局信息的操作会D强制触发队列的执行,如获取offsetTop,scrollTop,clientTop或调用getComputedStyleҎ(currentStyle in IE)的时候,要返回诸如此cȝ最新的布局信息的时候,览器就会立x染队列中的变化,触发重排Q然后返回正的倹{?/p>

׃动作的队列是Z面的,所以,即你获取的最新布局信息的节Ҏ有待执行的动作,也会触发重排?/p>

所以,量修改元素样式的操作攑֜一P然后再执行获取元素最新布局信息的操作,量不要交叉q行Q因为每ơ获取元素的最新布局信息Q都触发重排和重绘操作?/p>

虽然Q现代浏览器q行了优化,q不会在每次讄元素的样式或改变dom的结构时都会重绘和重排,Q但旧版览器仍会有性能问题Q所以尽量用以下规则来最化重绘和重排:
1Q?讄样式Q用cssText属性来合ƈ更新的样式信息: el.style.cssText=”padding-left:10px;border:1px”
2Q?改变doml构Q将元素q文档,然后q行一pd改变Q然后再带回文档中Q方法如下:
(1) 隐藏元素Q对元素的doml构q行一pd更改Q再昄元素
(2) 使用createDocumentFragment创徏文档片Q针Ҏ档碎片进行批量操作,然后一ơ性添加到文档?br />(3) 原始元素cloneC个脱L档流的节点中Q修改这个副本后Q替换原始元?br />3Q?~存布局信息
量减少布局信息的获取次敎ͼ如果有针对布局信息的P代操作,先将布局信息保存到局部变量中Q对该局部变量进行P代更斎ͼ然后该局部变量更新到dom?br />4Q?动画效果时脱L档流
  一个元素进行动L果时Q?br />(1) 该元素q文档,比如l对定位该元?br />(2) 对该元素q行动画操作Q这样不会触发其他区域的重排和重l?br />(3) 动画l束Ӟ元素恢复文档流位置Q这样只会对其余区域q行一ơ重排和重绘

3 使用事g委托来减dom树上的事件响应函?br />Ҏ档中大量的元素进行事件绑定会Dq行时效率下降,Z事g都会冒到父层,可以在父层上l定一个事Ӟ然后识别target(srcElement)来自行dispatch事g?/p>

?法和流E控?/strong>
1 循环
1) while,for,do-while性能上基本没差别Q不qwhile和do-while一般被用于Z某个条g的@环,而for用于数组的P代或U性的工作Q而for-in用于对象的枚?br />2Q减@环次数或减少循环中的工作量都可以优化性能Q如duff循环Q但性能提升微乎其微Q实际测试,在某些浏览器下duff循环不仅不会提升性能Q还会降低性能Q另外倒序循环可能会快一些,毕竟正序是与长度q行Ҏ后的boolean|而倒序循环是将表示当前循环q度的数D{换ؓboolean
3) q代器如js1.6的forEachҎ{,性能比用forq行循环要慢一些,但更语义?br />?我写的一个duff循环的js版本)

  1. //?duff的原理是减少循环ơ数Q从而减对循环条g的判断,所以duff的性能优化只对大数组(10万次条g判断会降低ؓ10?8ơ条件判?有意义,与@环体中的语句数量无关Q所以,duff只适用于@环体执行速度非常快,而@环规模非常大的状况,在js中只有略微的性能提升
  2. function duff(list,callback){
  3.     var i = list.length % 8;
  4.     var tails = i;
  5.     while(i){
  6.         callback(list[--i]);
  7.     }
  8.     var greatest_factor = list.length-1;
  9.     do{
  10.         process(list[greatest_factor]);
  11.         process(list[greatest_factor-1]);
  12.         process(list[greatest_factor-2]);
  13.         process(list[greatest_factor-3]);
  14.         process(list[greatest_factor-4]);
  15.         process(list[greatest_factor-5]);
  16.         process(list[greatest_factor-6]);
  17.         process(list[greatest_factor-7]);
  18.         greatest_factor-=8;
  19.     }while(greatest_factor>tails);
  20. }

2 条g语句
1)switch比if-else快一些,但性能微乎其微Q徏议在数量较多的分支时使用switchQ而进行范围判断或多重条g的时候用if-else
2)if-else的排列从大概率向概?br />3)如果条g太多Q徏议用查找表Q而且查找表具有动态扩充的能力
3 递归
1) ׃调用栈的限制Q递归是很危险?br />2) 非自调用Q而是交叉调用形成?#8220;隐伏递归”是很危险的,出错之后很难排错
3) 量递归转化P代,比如树的遍历Q用非递归的dfs,bfs来实现就?br />4) 很常用的函数Q进行memoize,用空间换取时?/p>

?字符串和正则表达?/strong>

1 理解各个览器的js引擎字符串合q的内部机制Q?br />1) 避免产生临时字符Ԍ如用str+=’abc’;str+=’def’  而不要用 str+=’abc’+'def’
2) firefox会在~译期合q字W串帔RQ如str+= ‘abc’+'def’会被转化为str+=’abcdef’Qyur-compressor也有q个功能
3) 数组的joinҎQ性能不会?q接W更快,因ؓ大多数浏览器?q接W不会开辟新内存I间Q而ie7,ie6却会开辟新I间Q所以ie6,7中字W串q接应该用数l的joinQ而其他浏览器?q接W,QconcatҎ是最慢的方式

2 正则表达式优?br />Z各js引擎中正则表辑ּ引擎的不同,以下某些Ҏ会带来某引擎性能的提升但可能同样D其他引擎性能的下降,所以原书原文也只是原理性阐qͼ实际开发时视具体情况而定?br />1) 循环中用的正则对象量在@环前初始化,q赋予一个变?br />2) ~写正则表达式时Q尽量考虑较少的回溯,比如~写分支时将大概率分支放在前面,在贪婪模式是从尾部向前回溯,懒惰模式从headPart向尾部逐字W回?br />3) 关于回溯失控Qv因是太宽泛的匚w模式Q如最后的part没能成功匚wQ则会记住回溯位|,试修改前面的part的匹配方式,如尝试让前面的懒惰模式包含一ơendPartQ然后从C|再试匚wQ正则引擎会一直尝试,最l导致回溯失?br />4) 在只是搜索确定的字面量,及字面量位置也确定如行首Q行Q正则非最佛_?br />(详细的正则优化先略过Q等以后再回来写?

?快速响应用L?/strong>

1 览器UIU程和UI队列
UIThread:javascript和ui是共用同一个线E的Q这样做的好处是无需考虑q行时的用户态或核心态的U程同步Q也无需在语a层面实现临界?critical section)Q在我最初自己摸索javascript的时候,认ؓjavascript也是多线E的Q后来写代码试后发玎ͼjavascriptq多线E,且javascript代码的执行会d和uiq的这唯一的线E,使用L操作得不到ui的反馈?/p>

UIQueue:上面的UIThread负责执行UIQueue中的taskQ无论用户对UI采取的动作触发的dom事g响应函数Q还是javascript执行q程中用setTimeout或setInterval创徏的定时器事g响应函数Q都会被插入到UIQueue中,当UIThread处于busy状态时Q可能会忽略掉一些taskQ不|入UIQueueQ比如用户动作的产生的ui更新task和触发的dom-event两者,ui更新的task会被忽略不放入UIQueueQ而dom-event会放入UIQueue{待UIThread处于idle状态时执行Q而setInterval函数的周期性定时器事gQ会视UIQueue中是否有相同的事件响应函敎ͼ如没有才会将该task|入UIQueue?br />UIQueue的task来源Q?br />1) 用户操作产生的ui更新重绘
2) 用户操作触发的绑定在dom上的javascript事g
3) dom节点自n状态改变触发的l定在自w上的javascript事gQ如的onload
4) setTimeout与setInterval讄的定时器事g
5) ajaxq程中的onreadystatechange事gQ这个javascript函数ql定在dom上,而是l定在xmlHttpRequest对象?/p>

览器限ӞZ避免某个javascript事g函数执行旉q长Q一直占据UIThreadQ从而导致用h作触发的UIUpdated得不到执行,各个览器用不同的Ҏ限制了单个javascript事g函数的执行时?br />1) ie:500万条Q在注册表有讄
2) firefox: 10U,在浏览器配置讄?about:config->dom.max_script_run_time)
3) safari: 5U,无法修改
4) chrome: 依赖通用崩溃系l?br />5) opera: ?/p>

界面多久无反应会让用h法忍受: 最?00毫秒Q用L动作之后过100毫秒界面没有做出响应Q用户就会认己和界面失去了联pR?/p>

2 用定时器让出旉片断(分解d)
d分解q程Q用h法忍受一?0U的d占据UIU程Q而自qM操作得不到反馈,于是我们可以这?0U的d分ؓ200?0毫秒的Q务,每执?0毫秒Q让出UIU程L行UI队列中的界面更新的Q务,让用户及时得到反馈,然后再执?0毫秒Q直到执行完毕?br />Z大多数长旉UId都是Ҏl的循环操作Q于是我们可以将q个循环q程q行拆解Q示例代码:

  1. function timedProcessArray(list, callback, complete, progress){
  2.     var total = list.length;
  3.     var curProgress = 0;
  4.     var preProgress = 0;
  5.    
  6.     (function(list, iteration){
  7.         var fn = arguments.callee;
  8.         var st = +new Date();
  9.         while(list.length && (+new Date() - st < 50) ){
  10.             iteration = callback(list.shift(), iteration);
  11.         }
  12.         if(list.length){
  13.             if(progress){ //如果需要对q度q行通知)
  14.                 curProgress = 100 - (100 / total * list.length ^ 0);
  15.                 if(curProgress != preProgress){
  16.                     preProgress = curProgress;
  17.                     progress(curProgress);
  18.                 }
  19.             }
  20.             setTimeout(function(){
  21.                 fn.call(null, list, iteration);
  22.             }, 25);
  23.         }else{
  24.             progress && progress(100);
  25.             complete && complete(iteration);
  26.         }
  27.     })(list.concat(),0);
  28.    
  29. }

d和非d(d分割)方式的示例,:http://lichaosoft.net/case/progress.html

3 web-workers
在web-workers之前Qjavascript是没有多U程的,web-workers标准带来了真正的多线E,web-workers本来是html5的一部分Q现在已l分dL为独立的规范Qhttp://www.w3.org/TR/workers/

和web-workers之间仅能通过onmessage和postMessage交互?/p>

使用web-workers以辅助线E进行计ƈ拥有q度通知的示例:
http://lichaosoft.net/case/worker.htmlQ请使用支持web-workers的chrome或safari览Q?/p>

web-workers适用于那些无法拆解的dQ对数组的遍历是一个可以被拆解的Q务,Ҏ的遍历通过使用dfs或bfs树q_化ؓ数组后也可以q行拆解Q不能拆解的d:
1) ~码/解码大字W串
2) 复杂数学q算
3) 大数l排?/p>

过100毫秒的Q务,如浏览器支持web-workersQ优先用web-workersQ如不支持则使用timedProcessArrayq行分割q行?/p>

没有Mjavascript代码的重要度高于用户体验Q用户体验是至高重要的,无论如何不能让用戯得界面反应速度慢?/p>

?AJAX
从广义上来看QAJAX是指不重载整个页面的情况下,与服务端q行数据传输Q解析数据,q局部刷新页面区域的改善用户体验的行为,那么我们下面介绍Q数据传输,数据格式?/p>

1 数据传输
1) XHR: 创徏一个XMLHttpRequest对象与服务端通信
2) 动态脚本注? q是一个hackQ创Z个script元素q设|srcZQ意uri-A(可跨?Q可在页面中先定义一个数据处理函数如function newsListProc(list){}Q然后在该uri-A指向的script文g中调用newsListProcq将数据传入Q这Ҏ术也UCؓQJSON-P?br />3) mXHR: 多个资源文件用XHR传输到浏览器端,js负责Ҏ据流分割Q然后dispathl不同类型资源文件的处理函数
4) 式XHR: 在支持readyState?Ӟ可访问已解析好的部分xhr数据Q既是支持流式XHRQ可q行式处理来优化执行效率,目前实际试ff3.6支持Q而ie6,7,8及chrome都不支持式XHR?br />5) iframes: 待箋
6) comet: 待箋

?Q关于mXHR和流式XHRQ我写了一个demo用来演示多资源文件合qӞ由XHR向客L传输Qƈ在支持流式XHR的浏览器中用流式XHRQDEMO地址Q?/p>

?Q纯_的发送数据而无需接受数据Q可用beacons方式Q类似动态脚本注入,不过创徏的不是script元素Q而是Image对象Qƈ讄srch的URIQ所以这U方式只能用GET方式Q代码示?

  1. function keepalive(uri, delay){
  2.     var beacon, delay = delay || 1000,
  3.     timer = setTimeout(function(){
  4.         var fn = arguments.callee;
  5.         beacon = new Image();
  6.         beacon.onload = beacon.onerror = function(){
  7.             timer = setTimeout(fn, delay);
  8.         }
  9.         beacon.src = uri;
  10.     }, delay);
  11.     return function(){
  12.         console.log('stop');
  13.         clearTimeout(timer);
  14.     };
  15. }

2 数据格式
1) XML: 使用responseXML对象的getElementsByTagName,getElementById,node.getAttribute{api对xml文档q行解析Q也可以用XPathq行解析Q性能更好些,伤是:
(1) “l构/数据”?太高
(2) XPath在支持ƈ不广?br />(3) 最重要的就是需要先知道内容的详l结构,针对每个数据l构~写特定的解析方?br />2) JSON: 最q泛的数据格式,解析性能较之xml高,”l构/数据”比低Q如使用~略属性名或完全用多层数l格式,l构数据比更低,传输性能更高
3) JSON-P: 无需解析Q属于javascript的正常函数调用,性能最?br />4) HTML: 无需解析Q服务端已构造好用于局部更新的html数据Q直接用innerHTML更新Q数据结构比太高Q压力被集中在服务端Q网l传输数据量?br />5) 自定义分隔符: 性能最高,l构数据比最低,对于性能要求比较苛刻的环境中使用

?创徏xhr对象的代码:

  1. function createXhrObject(){
  2.     if(window.XMLHttpRequest){
  3.         return new XMLHttpRequest();
  4.     }else{
  5.         var msxml_progid = [
  6.             'MSXML2.XMLHTTP.6.0', //支持readyState?状态,但此状态时dresponseText为空Q觉得似乎没意义。?/span>
  7.             'MSXML3.XMLHTTP',
  8.             'Microsoft.XMLHTTP',
  9.             'MSXML2.XMLHTTP.3.0'
  10.         ];
  11.         var req;
  12.         for(var i=0;i<msxml_progid.length;i++){
  13.             try{
  14.                 req = new ActiveXObject(msxml_progid[i]);
  15.                 break;
  16.             }catch(ex){}
  17.         }
  18.         return req;
  19.     }
  20. }

从字W流中异步解析数据的工具c?/p>

  1. /*
  2. * @method StringStreamParser 式字符串异步解析类
  3. * @param onRow 解析出数据行的回调函?/span>
  4. * @param RowSeperator 行分隔符,默认'u0001'
  5. * @param ColSeperator 列分隔符,默认'u0002'
  6. */
  7. function StringStreamParser(onRow, rowSeperator, colSeperator){
  8.     if (!(this instanceof arguments.callee)){
  9.         return new arguments.callee(onRow, rowSeperator, colSeperator);
  10.     }
  11.     var stream = '';                               
  12.     rowSeperator = rowSeperator || 'u0001';
  13.     colSeperator = colSeperator || 'u0002';
  14.    
  15.     /* @method write 向字W流写入?/span>
  16.      * @param packet 写入的包
  17.      * @param lastPacket 是否为最后一个包Q默认false
  18.      */
  19.     this.write = function(packet, lastPacket){
  20.         stream += packet;
  21.         var rowIdx = stream.indexOf(rowSeperator);
  22.         var colIdx,strRow, dataRow;
  23.        
  24.         while(rowIdx!==-1 || lastPacket){
  25.        
  26.             if(rowIdx===-1){   
  27.                 strRow = stream.substr(0);
  28.                 lastPacket = false;
  29.             }else{
  30.                 strRow = stream.substr(0,rowIdx);
  31.                 stream = stream.substr(rowIdx+1);
  32.                 rowIdx = stream.indexOf(rowSeperator);                   
  33.             }
  34.            
  35.             dataRow = [];
  36.             while(colIdx = strRow.indexOf(colSeperator)){
  37.                 if(colIdx !== -1){
  38.                     dataRow.push(strRow.substr(0, colIdx));
  39.                     strRow = strRow.substr(colIdx+1);
  40.                 }else{
  41.                     dataRow.push(strRow.substr(0));
  42.                     break;
  43.                 }
  44.             }
  45.             onRow.call(null, dataRow);
  46.            
  47.         }
  48.     }
  49. }

3 其他
在确定了合适的数据传输技术,和数据传输格式之后,q可以采取以下方式酌情优化ajax:
1) ~存数据: 最快的hQ是不请求,有以下两U方式缓?
  (1) 对于GEThQ在response中,讄expires头信息,览器即会将此请求缓存,q种~存是跨会话也是跨页面的
(2) 在javascript中,以url作ؓ唯一标识W缓存请求到的数据,无法跨页面也无法跨会话,但可~程控制~存q程Q不能跨会话也不能跨面Q这U缓存基本上是无意义的)
2) 在必要的时候,直接使用XHR对象而非ajax库,如需要流式的数据处理

?常见~码中的性能提高?br />1 避免双重求? eval,Function,setTimeout和setInterval都允怼入字W串Q而此时会创徏一个新的编译器的实例,会D很大的性能损失?另外q些方式执行代码Ӟ代码的作用域在各个浏览器也不相同,Ҏ掉坑)
2 使用Object/Array的直接量q行定义(且直接量比new Object()然后讄属性更节省代码)
3 不要让代码重复运?br />1) 延迟定义

2) 条g预定?br />4 量使用原生javascript
转蝲自:http://www.cnblogs.com/pansly/archive/2011/06/29/2093769.html



疯狂 2011-10-09 11:56 发表评论
]]>
转蝲一文章oracle的一些操?/title><link>http://www.tkk7.com/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.tkk7.com/freeman1984/archive/2011/08/03/355643.html</guid><wfw:comment>http://www.tkk7.com/freeman1984/comments/355643.html</wfw:comment><comments>http://www.tkk7.com/freeman1984/archive/2011/08/03/355643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/freeman1984/comments/commentRss/355643.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/freeman1984/services/trackbacks/355643.html</trackback:ping><description><![CDATA[     摘要: 转自: http://renjie120.iteye.com/ 注意:数据库版本是10g,不过大部?i的也适用,闪回9i没?   1.曄不小心把开发库的数据库表全部删除,当时吓的要死。结果找C面的语句恢复C1个小时之前的数据Q很单?注意使用理员登录系l: select * from 表名 as of timestamp sysdate-1/12&...  <a href='http://www.tkk7.com/freeman1984/archive/2011/08/03/355643.html'>阅读全文</a><img src ="http://www.tkk7.com/freeman1984/aggbug/355643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/freeman1984/" target="_blank">疯狂</a> 2011-08-03 10:33 <a href="http://www.tkk7.com/freeman1984/archive/2011/08/03/355643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>qv$sqlarea,v$sql查询最占用资源的查?/title><link>http://www.tkk7.com/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.tkk7.com/freeman1984/archive/2011/08/03/355634.html</guid><wfw:comment>http://www.tkk7.com/freeman1984/comments/355634.html</wfw:comment><comments>http://www.tkk7.com/freeman1984/archive/2011/08/03/355634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/freeman1984/comments/commentRss/355634.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/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 />    a.executions exec,a.disk_reads/decode(a.executions,0,1,a.executions) rds_exec_ratio,<br />    a.sql_text Statement<br />from  v$sqlarea a,dba_users b<br />where a.parsing_user_id=b.user_id<br /> and a.disk_reads > 100000<br />order by a.disk_reads desc;</div> <div>用buffer_gets列来替换disk_reads列可以得到占用最多内存的sql语句的相关信息?/div> <div> </div> <div>V$SQL是内存共享SQL区域中已l解析的SQL语句?/div> <div><br /><span style="color: #0000ff">列出使用频率最高的5个查询:</span> </div> <div>select sql_text,executions<br />from (select sql_text,executions,<br />   rank() over<br />    (order by executions desc) exec_rank<br />   from v$sql)<br />where exec_rank <=5;</div> <div><span style="color: #0000ff">消耗磁盘读取最多的sql top5Q?br /></span>select disk_reads,sql_text<br />from (select sql_text,disk_reads,<br />   dense_rank() over<br />     (order by disk_reads desc) disk_reads_rank<br />   from v$sql)<br />where disk_reads_rank <=5;</div> <div><br /><span style="color: #0000ff">扑և需要大量缓冲读取(逻辑读)操作的查询:</span> </div> <div>select buffer_gets,sql_text<br />from (select sql_text,buffer_gets,<br />   dense_rank() over<br />     (order by buffer_gets desc) buffer_gets_rank<br />   from v$sql)<br />where buffer_gets_rank<=5;</div><img src ="http://www.tkk7.com/freeman1984/aggbug/355634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/freeman1984/" target="_blank">疯狂</a> 2011-08-03 09:47 <a href="http://www.tkk7.com/freeman1984/archive/2011/08/03/355634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JVM内存模型以及垃圾回收http://www.tkk7.com/freeman1984/archive/2011/03/08/345929.html疯狂疯狂Tue, 08 Mar 2011 05:16:00 GMThttp://www.tkk7.com/freeman1984/archive/2011/03/08/345929.htmlhttp://www.tkk7.com/freeman1984/comments/345929.htmlhttp://www.tkk7.com/freeman1984/archive/2011/03/08/345929.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/345929.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/345929.htmlJVM内存模型以及垃圾回收
内存?Perm ?Heap l成. 其中

Heap = {Old + NEW = { Eden , from, to } }
具体可查看javavisualvm

JVM内存模型中分两大块,一块是 NEW Generation, 另一块是Old Generation. 在New Generation中,有一个叫Eden的空_主要是用来存放新生的对象Q还有两个Survivor SpacesQfrom,toQ? 它们用来存放每次垃圾回收后存zM来的对象。在Old Generation中,主要存放应用E序中生命周期长的内存对象,q有个Permanent GenerationQ主要用来放JVM自己的反对象,比如cd象和Ҏ对象{?
 

垃圾回收描述Q?/p>


在New Generation块中Q垃圑֛收一般用Copying的算法,速度快。每ơGC的时候,存活下来的对象首先由Eden拯到某个Survivor Space, 当Survivor SpaceI间满了? 剩下的live对象p直接拯到Old Generation中去。因此,每次GC后,Eden内存块会被清I。在Old Generation块中Q垃圑֛收一般用mark-compact的算法,速度慢些Q但减少内存要求.
垃圾回收分多U,0Uؓ全部(Full)的垃圑֛Ӟ会回收OLDD中的垃圾;1U或以上为部分垃圑֛Ӟ只会回收NEW中的垃圾Q内存溢出通常发生于OLDD|PermD垃圑֛收后Q仍然无内存I间容纳新的Java对象的情c?/p>

当一个URL被访问时Q内存申误E如下:
A. JVM会试图ؓ相关Java对象在Eden中初始化一块内存区?br /> B. 当EdenI间_Ӟ内存甌l束。否则到下一?br /> C. JVM试图释放在Eden中所有不z跃的对象(q属?或更高的垃圑֛Ӟ, 释放后若EdenI间仍然不以放入新对象Q则试图部分Eden中活跃对象放入Survivor?br /> D. Survivor用来作ؓEden及OLD的中间交换区域,当OLD区空间够时QSurvivor区的对象会被UdOld区,否则会被保留在Survivor?br /> E. 当OLD区空间不够时QJVM会在OLD行完全的垃圾攉Q?U)
F. 完全垃圾攉后,若Survivor及OLDZ然无法存放从Eden复制q来的部分对象,DJVM无法在EdenZؓ新对象创建内存区域,则出?#8221;out of memory错误”

JVM调优:

ms/mxQ定义YOUNG+OLDD늚d寸,ms为JVM启动时YOUNG+OLD的内存大;mx为最大可占用的YOUNG+OLD内存大小。在用户生环境上一般将q两个D为相同,以减运行期间系l在内存甌上所q开销?br /> NewSize/MaxNewSizeQ定义YOUNGD늚寸QNewSize为JVM启动时YOUNG的内存大;MaxNewSize为最大可占用的YOUNG内存大小。在用户生环境上一般将q两个D为相同,以减运行期间系l在内存甌上所q开销?br /> PermSize/MaxPermSizeQ定义PermD늚寸QPermSize为JVM启动时Perm的内存大;MaxPermSize为最大可占用的Perm内存大小。在用户生环境上一般将q两个D为相同,以减运行期间系l在内存甌上所q开销?br /> SurvivorRatioQ设|SurvivorI间和EdenI间的比?/p>

内存溢出的可能?/p>

1. OLDD|?br /> q种内存溢出是最常见的情况之一Q生的原因可能是:
1) 讄的内存参数过?ms/mx, NewSize/MaxNewSize)
2) E序问题
单个E序持箋q行消耗内存的处理Q如循环几千ơ的字符串处理,对字W串处理应徏议用StringBuffer。此时不会报内存溢出错,却会使系l持l垃圾收集,无法处理其它hQ相关问题程序可通过Thread Dump获取Q见pȝ问题诊断一章)单个E序所甌内存q大Q有的程序会甌几十乃至几百兆内存,此时JVM也会因无法申请到资源而出现内存溢出,Ҏ首先要找到相兛_能,然后交予E序员修改,要找到相关程序,必须在Apache日志中寻找?br /> 当Java对象使用完毕后,其所引用的对象却没有销毁,使得JVM认ؓ他还是活跃的对象而不q行回收Q这L计占用了大量内存而无法释放。由于目前市面上q没有对pȝ影响的内存分析工具Q故此时只能和程序员一起定位?/p>


2. PermD|?br /> 通常׃PermD装载了大量的Servletc而导致溢出,目前的解军_法:
1) PermSize扩大Q一?56M能够满要求
2) 若别无选择Q则只能servlet的\径加到CLASSPATH中,但一般不q么处理

3. C Heap溢出
pȝ对C Heap没有限制Q故C Heap发生问题ӞJavaq程所占内存会持箋增长Q直到占用所有可用系l内?/p>

其他Q?/p>

JVM?个GCU程。第一个线E负责回收Heap的Young区。第二个U程在Heap不Ӟ遍历HeapQ将Young 区升UؓOlder区。Older区的大小{于-Xmx减去-XmnQ不能将-Xms的D的过大,因ؓW二个线E被q运行会降低JVM的性能?/p>

Z么一些程序频J发生GCQ有如下原因Q?br /> l         E序内调用了System.gc()或Runtime.gc()?br /> l         一些中间g软g调用自己的GCҎQ此旉要设|参数禁止这些GC?br /> l         Java的Heap太小Q一般默认的Heap值都很小?br /> l         频繁实例化对象,Release对象。此时尽量保存ƈ重用对象Q例如用StringBuffer()和String()?br /> 如果你发现每ơGC后,Heap的剩余空间会是ȝ间的50%Q这表示你的Heap处于健康状态。许多Server端的JavaE序每次GC后最好能?5%的剩余空间?br /> l验之谈Q?br /> 1QServer端JVM最好将-Xms?Xmx设ؓ相同倹{ؓ了优化GCQ最好让-Xmn值约{于-Xmx?/3[2]?
2Q一个GUIE序最好是?0?0U间q行一ơGCQ每ơ在半秒之内完成[2]?
注意Q?br /> 1Q增加Heap的大虽然会降低GC的频率,但也增加了每ơGC的时间。ƈ且GCq行Ӟ所有的用户U程暂停,也就是GC期间QJava应用E序不做M工作?br /> 2QHeap大小q不军_q程的内存用量。进E的内存使用量要大于-Xmx定义的|因ؓJava为其他Q务分配内存,例如每个U程的Stack{?br /> 2QStack的设?br /> 每个U程都有他自qStack?/p>

-Xss 每个U程的Stack大小

Stack的大限制着U程的数量。如果Stackq大好D内存溢漏?Xss参数军_Stack大小Q例?Xss1024K。如果Stack太小Q也会导致Stack溢漏?br /> 3Q硬件环?br /> g环境也媄响GC的效率,例如机器的种c,内存QswapI间Q和CPU的数量?br /> 如果你的E序需要频J创建很多transient对象Q会DJVM频繁GC。这U情况你可以增加机器的内存,来减SwapI间的用[2]?br /> 4Q?UGC
W一Uؓ单线EGCQ也是默认的GC。,该GC适用于单CPU机器?br /> W二UؓThroughput GCQ是多线E的GCQ适用于多CPUQ用大量线E的E序。第二种GC与第一UGC怼Q不同在于GC在收集Young区是多线E的Q但在Old区和W一U一P仍然采用单线E?XX:+UseParallelGC参数启动该GC?br /> W三UؓConcurrent Low Pause GCQ类gW一U,适用于多CPUQƈ要求~短因GC造成E序停滞的时间。这UGC可以在Old区的回收同时Q运行应用程序?XX:+UseConcMarkSweepGC参数启动该GC?br /> W四UؓIncremental Low Pause GCQ适用于要求羃短因GC造成E序停滞的时间。这UGC可以在Young区回收的同时Q回收一部分Old区对象?Xincgc参数启动该GC?/p>

疯狂 2011-03-08 13:16 发表评论
]]>
提高AJAX客户端响应速度(转蝲)http://www.tkk7.com/freeman1984/archive/2011/02/11/344056.html疯狂疯狂Fri, 11 Feb 2011 07:23:00 GMThttp://www.tkk7.com/freeman1984/archive/2011/02/11/344056.htmlhttp://www.tkk7.com/freeman1984/comments/344056.htmlhttp://www.tkk7.com/freeman1984/archive/2011/02/11/344056.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/344056.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/344056.html提高AJAX客户端响应速度

(文:包一?/span>)

AJAX的出现极大的改变?/span>Web应用客户端的操作模式Q它使的用户可以在全心工作时不必频繁的忍受那令h厌恶的页面刷新。理ZAJAX技术在很大的程度上可以减少用户操作的等待时_同时节约|络上的数据量。而然Q实际情况却q不Lq样。用h怼抱怨用?/span>AJAX的系l响应速度反而降低了?/span>

W者从?/span>AJAX斚w的研发多q_参与开发了目前国内较ؓ成熟?/span>AJAXq_-dorado。根据笔者的l验Q导致这U结果的Ҏ原因q不?/span>AJAX。很多时候系l响应速度的降低都是由不够合理的界面设计和不够高效的编E习惯造成的。下面我们就来分析几?/span>AJAX开发过E中需要时L意的环节?/span>

合理的用客L~程和远E过E调用?/span>

客户端的~程主要都是ZJavaScript的。?/span>JavaScript是一U解释型的编E语aQ它的运行效率相对于Java{都要稍逊一{V同?/span>JavaScript又是q行在浏览器q样一个严格受限的环境当中。因此开发h员对于哪些逻辑可以在客L执行应该有一个清醒的认识?/span>

在实际的应用中究竟应该怎样使用客户端编E,q依赖于开发h员的l验判断。这里很多问题是只可意会的。由于篇q有限,在这里我们大致归U_下面q几个注意事:

可能避免频J的使用q程q程调用Q例如避免在循环体中使用q程q程调用?/span>

如果可能的话可能?/span>AJAX方式的远E过E调用(异步方式的远E过E调用)?/span>

避免重量的数据操作放|在客户端。例如:大批量的数据复制操作、需要通过大量的数据遍历完成的计算{?/span>

改进?/span>DOM对象的操作方式?/span>

客户端的~程中,?/span>DOM对象的操作往往是最Ҏ占用CPU旉的。而对?/span>DOM对象的操作,不同的编E方法之间的性能差异又往往是非常大的?/span>

以下是三D运行结果完全相同的代码Q它们的作用是在|页中创Z?/span>10x1000的表根{然而它们的q行速度却有着天壤之别?/span>

/* 试代码1 - 耗时: 41U?/span>*/

var table = document.createElement("TABLE");

document.body.appendChild(table);

for(var i = 0; i < 1000; i++){

 var row = table.insertRow(-1);

 for(var j = 0; j < 10; j++){

    var cell = objRow.insertCell(-1);

     cell.innerText = "( " + i + " , " + j + " )";

 }

}

/* 试代码2 - 耗时: 7.6U?/span> */

var table = document.getElementById("TABLE");

document.body.appendChild(table);

var tbody = document.createElement("TBODY");

table.appendChild(tbody);

for(var i = 0; i < 1000; i++){

 var row = document.createElement("TR");

 tbody.appendChild(row);

 for(var j = 0; j < 10; j++){

    var cell = document.createElement("TD");

     row.appendChild(cell);

     cell.innerText = "( " + i + " , " + j + " )";

 }

}

/* 试代码3 - 耗时: 1.26U?/span> */

var tbody = document.createElement("TBODY");

for(var i = 0; i < 1000; i++){  

 var row = document.createElement("TR");

       for(var j = 0; j < 10; j++){

    var cell = document.createElement("TD");

     cell.innerText = "( " + i + " , " + j + " )";

     row.appendChild(cell);

 }

 tbody.appendChild(row);

}

var table = document.getElementById("TABLE");

table.appendChild(tbody);

document.body.appendChild(table);

q里?#8220;试代码1”?#8220;试代码2”之间的差别在于在创徏表格单元时用了不同?/span>APIҎ。?#8220;试代码2”?#8220;试代码3之间的差别在于处理顺序的略微不同?/span>

“试代码1”?#8220;试代码2”之间如此大的性能差别我们无从分析Q目前所知的?/span>insertRow?/span>insertCell?/span>DHTML中表格特有的APIQ?/span>createElement?/span>appendChild?/span>W3C DOM的原?/span>API。而前者应该是对后者的装。不q,我们q不能因此而得出结?/span>DOM的原?/span>APIL优于对象Ҏ?/span>API。徏议大家在需要频J调用某一APIӞ对其性能表现做一些基本的试?/span>

“试代码2”?#8220;试代码3”之间的性能差异主要来自于他们的构徏序不同?#8220;试代码2”的做法是首先创徏最外层?/span><TABLE>对象Q然后再在@环中依次创徏<TR>?/span><TD>。?#8220;试代码3”的做法是首先在内存中由内到外的构建好整个表格Q最后再它d到网中。这样做的目的是可能的减少览器重新计页面布局的次数。每当我们将一个对象添加到|页中时Q浏览器都会试寚w面中的控件的布局q行重新计算。所以,如果我们能够首先在内存中整个要构造的对象全部创徏好,然后再一ơ性的d到网中。那么,览器将只会做一ơ布局的重计算。ȝZ句话那就是越晚执?/span>appendChild好。有时ؓ了提高运行效率,我们甚至可以考虑先?/span>removeChild已存在的控件从面中移除,然后构造完成后再重新将其放|回面当中?/span>

提高字符串篏加的速度

在?/span>AJAX提交信息Ӟ我可能常帔R要拼装一些比较大的字W串通过XmlHttp来完?/span>POST提交。尽提交这样大的信息的做法看v来ƈ不优雅,但有时我们可能不得不面对q样的需求。那?/span>JavaScript中对字符串的累加速度如何呢?我们先来做下面的q个实验。篏加一个长度ؓ30000的字W串?/span>

/* 试代码1 - 耗时: 14.325U?/span> */

var str = "";

for (var i = 0; i < 50000; i++) {

       str += "xxxxxx";

}

q段代码耗时14.325U,l果q不理想。现在我们将代码改ؓ如下的Ş式:

/* 试代码2 - 耗时: 0.359U?/span> */

var str = "";

for (var i = 0; i < 100; i++) {

       var sub = "";

       for (var j = 0; j < 500; j++) {

              sub += "xxxxxx";

       }

       str += sub;

}

q段代码耗时0.359U!同样的结果,我们做的只是首先D一些较的字符串然后再l装成更大的字符丌Ӏ这U做法可以有效的在字W串D的后期减内存复制的数据量。知道了q一原理之后我们q可以把上面的代码进一步拆散以后进行测试。下面的代码仅耗时0.140U?/span>

/* 试代码3 - 耗时: 0.140U?/span> */

var str = ""; 

for (var i1 = 0; i1 < 5; i1++) {

       var str1 = "";

       for (var i2 = 0; i2 < 10; i2++) {

              var str2 = "";

              for (var i3 = 0; i3 < 10; i3++) {

                     var str3 = "";

                     for (var i4 = 0; i4 < 10; i4++) {

                            var str4 = "";

                            for (var i5 = 0; i5 < 10; i5++) {

                                   str4 += "xxxxxx";

                            }

                            str3 += str4;

                     }

                     str2 += str3;

              }

              str1 += str2;      

       }

       str += str1; 

}

不过Q上面这U做法也许ƈ不是最好的Q如果我们需要提交的信息?/span>XML格式的(其实l大多数情况下,我们都可以设法将要提交的信息l装?/span>XML格式Q,我们q能扑ֈ更高效更优雅的方?/span>?span style="font-family: 宋体">利用DOM对象为我们组装字W串。下面这D代买组装一个长度ؓ950015的字W串仅须耗时0.890U?/span>

/* 利用DOM对象l装信息 - 耗时: 0.890U?/span> */

var xmlDoc; 

if (browserType == BROWSER_IE) {

       xmlDoc = new ActiveXObject("Msxml.DOMDocument");

}

else {

       xmlDoc = document.createElement("DOM");

}

var root = xmlDoc.createElement("root");

for (var i = 0; i < 50000; i++) {

       var node = xmlDoc.createElement("data");

       if (browserType == BROWSER_IE) {

              node.text = "xxxxxx";

       }

       else {

              node.innerText = "xxxxxx";

       }

       root.appendChild(node);

}

xmlDoc.appendChild(root);

var str;

if (browserType == BROWSER_IE) {

       str = xmlDoc.xml;

}

else {

       str = xmlDoc.innerHTML;

}

避免DOM对象的内存泄漏?/span>

关于IE?/span>DOM对象的内存泄露是一个常常被开发h员忽略的问题。然而它带来的后果却是非怸重的Q它会导?/span>IE的内存占用量持箋上升Qƈ且浏览器的整体运行速度明显下降。对于一些泄露比较严重的|页Q甚臛_要刷新几ơ,q行速度׃降低一倍?/span>

比较常见的内存泄漏的模型?#8220;循环引用模型”?#8220;闭包函数模型”?#8220;DOM插入序模型”,对于前两U泄漏模型,我们都可以通过在网|构时解除引用的方式来避免。而对?#8220;DOM插入序模型”则需要通过改变一些惯有的~程习惯的方式来避免?/span>

有关内存泄漏的模型的更多介绍可以通过Google很快的查刎ͼ本文不做q多的阐q。不q,q里我向您推荐一个可用于查找和分析网内存泄露的工?/span>?span style="font-family: 'Verdana', 'sans-serif'">DripQ目前的较新版本?/span>0.5Q下载地址?/span>http://outofhanwell.com/ieleak/index.php

复杂面的分D装载和初始?/span>

对系l当中某些确实比较复杂而又不便使用IFrame的界面,我们可以对其实施分段装蝲。例如对于多|{界面Q我们可以首先下载和初始化多|{默认,然后利用AJAHQ?/span>asynchronous JavaScript and HTMLQ技术来异步的装载其他标{N中的内容。这样就能保证界面可以在W一旉首先展现l用戗把整个复杂界面的装载过E分散到用户的操作过E当中?/span>

利用GZIP压羃|络量?/span>

除了上面提到的这些代码的改良之外,我们q可以利?/span>GZIP来有效的降低|络量。目前常见的L览器已l全部支?/span>GZIP法Q我们往往只需要编写少量的代码可以支?/span>GZIP了。例如在J2EE中我们可以在Filter中通过下面的代码来判断客户端浏览器是否支持GZIP法Q然后根据需要利?/span>java.util.zip.GZIPOutputStream来实?/span>GZIP的输出?/span>

/* 判断览器对GZIP支持方式的代?/span> */

private static String getGZIPEncoding(HttpServletRequest request) {

 String acceptEncoding = request.getHeader("Accept-Encoding");

 if (acceptEncoding == null) return null;

 acceptEncoding = acceptEncoding.toLowerCase();

 if (acceptEncoding.indexOf("x-gzip") >= 0) return "x-gzip";

 if (acceptEncoding.indexOf("gzip") >= 0) return "gzip";

 return null;

}

一般而言Q?/span>GZIP对于HTML?/span>JSP的压~比可以辑ֈ80%左右Q而它造成的服务端和客L的性能损耗几乎是可以忽略的。结合其他因素,支持GZIP的网站有可能为我们节U?/span>50%的网l流量。因?/span>GZIP的用可以ؓ那些|络环境不是特别好的应用带来显著的性能提升。?/span>Http的监视工?/span>Fiddler可以方便的检出|页在?/span>GZIP前后的通讯数据量?/span>Fiddler的下载地址?/span>http://www.fiddlertool.com/fiddler/

关于Web应用的性能优化其实是一个非常大的话题。本文由于篇q有限,只能涉及其中的几个细节,q且也无法将q些l节的优化方式全面的展现l大家。期望本文能够引起大家对Web应用其是客L性能优化的充分重视。毕竟服务端~程技巧已为大家熟知多q_在服务端挖掘性能的潜力已l不大了。而在客户端的Ҏ改进往往能够得到令h惊奇的性能提升?/span>



疯狂 2011-02-11 15:23 发表评论
]]>
加速JavascriptQDOM操作优化http://www.tkk7.com/freeman1984/archive/2010/10/17/335395.html疯狂疯狂Sun, 17 Oct 2010 15:53:00 GMThttp://www.tkk7.com/freeman1984/archive/2010/10/17/335395.htmlhttp://www.tkk7.com/freeman1984/comments/335395.htmlhttp://www.tkk7.com/freeman1984/archive/2010/10/17/335395.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/335395.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/335395.html原文Q《Speeding up JavaScript: Working with the DOM?/p>

作者: KeeKim Heng, Google Web Developer

在我们开发互联网富应用(RIAQ时Q我们经常写一些javascript脚本来修Ҏ者增加页面元素,q些工作最l是DOM——或者说文档对象模型——来完成的,而我们的实现方式会媄响到应用的响应速度?/p>

DOM操作会导致浏览器重解?reflow)Q这是浏览器的一个决定页面元素如何展现的计算q程。直接修改DOMQ修改元素的CSS样式Q修Ҏ览器的窗口大,都会触发重解析。读取元素的布局属性比如offsetHeithe或者offsetWidth也会触发重解析。重解析需要花费计时_因此重解析触发的少Q应用就会越快?/p>

DOM操作通常要不是修改已经存在的页面上的元素,要不是创徏新的面元素。下面的4U优化方案覆盖了修改和创建DOM节点两种方式Q帮助你减少触发览器重解析的次数?/p>

Ҏ一Q通过CSScd切换来修改DOM

 

q个Ҏ让我们可以一ơ性修改一个元素和它的子元素的多个样式属性而只触发一ơ重解析?/p>

需求:

Qemu注:原文作者写到这里的时候脑子显然短路了一下,把后面的Out-of-the-flow DOM Manipulation模式要解决的问题l摆到这里来了,不过从示范代码中很容易明白作者真正想描述的问题,因此emu׃照翻原文了)

我们现在需要写一个函数来修改一个超链接的几个样式规则。要实现很简单,把这几个规则对应的属性逐一改了好了。但是带来的问题是,每修改一个样式属性,都会D一ơ页面的重解析?/p>

view plaincopy to clipboardprint?
function selectAnchor(element) {  
  element.style.fontWeight = 'bold';  
  element.style.textDecoration = 'none';  
  element.style.color = '#000';  

function selectAnchor(element) {
  element.style.fontWeight = 'bold';
  element.style.textDecoration = 'none';
  element.style.color = '#000';
}

解决Ҏ

要解册个问题,我们可以先创Z个样式名Qƈ且把要修改的样式规则都放到这个类名上Q然后我们给链接添加上q个新类名,可以实现添加几个样式规则而只触发一ơ重解析了。这个模式还有个好处是也实现了表现和逻辑相分R?/p>

view plaincopy to clipboardprint?
.selectedAnchor {  
  font-weight: bold;  
  text-decoration: none;  
  color: #000;  
}  
 
function selectAnchor(element) {  
  element.className = 'selectedAnchor';  

.selectedAnchor {
  font-weight: bold;
  text-decoration: none;
  color: #000;
}

function selectAnchor(element) {
  element.className = 'selectedAnchor';
}

 Ҏ二:在非渲染Z改DOM

Qemu注:作者在q里再次脑子短\Q把DocumentFragment DOM Generation模式的介l提前到q里来了Qemu只好再次发挥一下)
上一个方案解决的是修改一个超链接的问题,当一ơ需要对很多个超链接q行相同修改的时候,q个Ҏ可以大显n手了?/p>

需?/p>

需求是q样的,我们要写一个函数来修改一个指定元素的子元素中所有的链接的样式名(classNameQ属性。要实现很简单,我们可以通过遍历每个链接ƈ且修改它们的样式名来完成d。但是带来的问题是Q每修改一个超链接都会D一ơ重解析?/p>

view plaincopy to clipboardprint?
function updateAllAnchors(element, anchorClass) {  
  var anchors = element.getElementsByTagName('a');  
  for (var i = 0, length = anchors.length; i < length; i ++) {  
    anchors[i].className = anchorClass;  
  }  

function updateAllAnchors(element, anchorClass) {
  var anchors = element.getElementsByTagName('a');
  for (var i = 0, length = anchors.length; i < length; i ++) {
    anchors[i].className = anchorClass;
  }
}
 

解决Ҏ

要解册个问题,我们可以把被修改的指定元素从DOM里面U除Q再修改所有的链接,然后在把q个元素插入回到它原来的位置上。ؓ了完成这个复杂的操作Q我们可以先写一个可重用的函敎ͼ它不但移除了q个DOM节点Q还q回了一个把元素插回到原来的位置的函数?/p>

view plaincopy to clipboardprint?
/** 
 * Remove an element and provide a function that inserts it into its original position 
 * @param element {Element} The element to be temporarily removed 
 * @return {Function} A function that inserts the element into its original position 
 **/ 
function removeToInsertLater(element) {  
  var parentNode = element.parentNode;  
  var nextSibling = element.nextSibling;  
  parentNode.removeChild(element);  
  return function() {  
    if (nextSibling) {  
      parentNode.insertBefore(element, nextSibling);  
    } else {  
      parentNode.appendChild(element);  
    }  
  };  

/**
 * Remove an element and provide a function that inserts it into its original position
 * @param element {Element} The element to be temporarily removed
 * @return {Function} A function that inserts the element into its original position
 **/
function removeToInsertLater(element) {
  var parentNode = element.parentNode;
  var nextSibling = element.nextSibling;
  parentNode.removeChild(element);
  return function() {
    if (nextSibling) {
      parentNode.insertBefore(element, nextSibling);
    } else {
      parentNode.appendChild(element);
    }
  };
}

有了上面q个函数Q现在我们就可以在一个不需要解析渲染的元素上面修改那些链接了。这样只在移除和插入元素的时候各触发一ơ重解析?/p>

view plaincopy to clipboardprint?
function updateAllAnchors(element, anchorClass) {  
  var insertFunction = removeToInsertLater(element);  
  var anchors = element.getElementsByTagName('a');  
  for (var i = 0, length = anchors.length; i < length; i ++) {  
    anchors[i].className = anchorClass;  
  }  
  insertFunction();  

function updateAllAnchors(element, anchorClass) {
  var insertFunction = removeToInsertLater(element);
  var anchors = element.getElementsByTagName('a');
  for (var i = 0, length = anchors.length; i < length; i ++) {
    anchors[i].className = anchorClass;
  }
  insertFunction();
}
 

Ҏ三:一ơ性的DOM元素生成

q个Ҏ让我们创Z个元素的q程只触发一ơ重解析。在创徏完元素以后,先进行所有需要的修改Q最后才把它插入到DOM里面d可以?/p>

需?/p>

需求是q样的,实现一个函敎ͼ往一个指定的父元素上插入一个超链接元素。这个函数要同时可以讄q个链接的昄文字和样式类。我们可以这样做Q创建元素,插入到DOM里面Q然后设|相应的属性。这p触发3ơ重解析?/p>

view plaincopy to clipboardprint?
function addAnchor(parentElement, anchorText, anchorClass) {  
  var element = document.createElement('a');  
  parentElement.appendChild(element);  
  element.innerHTML = anchorText;  
  element.className = anchorClass;  

function addAnchor(parentElement, anchorText, anchorClass) {
  var element = document.createElement('a');
  parentElement.appendChild(element);
  element.innerHTML = anchorText;
  element.className = anchorClass;
}
 

解决Ҏ

很简单,我们只要把插入元素这个操作放到最后做Q就可以只进行一ơ重解析了?/p>

view plaincopy to clipboardprint?
function addAnchor(parentElement, anchorText, anchorClass) {  
  var element = document.createElement('a');  
  element.innerHTML = anchorText;  
  element.className = anchorClass;  
  parentElement.appendChild(element);  

function addAnchor(parentElement, anchorText, anchorClass) {
  var element = document.createElement('a');
  element.innerHTML = anchorText;
  element.className = anchorClass;
  parentElement.appendChild(element);
}

不过Q要是我们想要插入很多个链接到一个元素里面的话,那么q个做法q是有问题:每插入一个超链接q是要触发一ơ重解析。下一个方案可以解册个问题?/p>

Ҏ四:通过文档片段对象QDocumentFragmentQ创Zl元?/p>

q个Ҏ允许我们创徏q插入很多个元素而只触发一ơ重解析。要实现q点需要用到所谓的文档片段对象QDocumentFragmentQ。我们先在DOM之外创徏一个文档片D对象(q样它也׃需要解析和渲染Q,然后我们在文档片D对象中创徏很多个元素,最后我们把q个文档片段对象中所有的元素一ơ性放到DOM里面去,只触发一ơ重解析?/p>

需?/p>


我们要写一个函敎ͼ往一个指定的元素上面增加10个超链接。如果我们简单的直接插入10个超链接到元素上面,׃触发10ơ重解析?/p>

view plaincopy to clipboardprint?
function addAnchors(element) {  
  var anchor;  
  for (var i = 0; i < 10; i ++) {  
    anchor = document.createElement('a');  
    anchor.innerHTML = 'test';  
    element.appendChild(anchor);  
  }  

function addAnchors(element) {
  var anchor;
  for (var i = 0; i < 10; i ++) {
    anchor = document.createElement('a');
    anchor.innerHTML = 'test';
    element.appendChild(anchor);
  }
}

解决Ҏ

要解册个问题,我们要先创徏一个文档片D对象,然后把每个新创徏的超链接都插入到它里面去。当我们把文档片D对象用appendChild命o插入到指定的节点Ӟq个文档片段对象的所有子节点׃赯插入到指定的元素里面Q而且只需要触发一ơ重解析?/p>

view plaincopy to clipboardprint?
function addAnchors(element) {  
  var anchor, fragment = document.createDocumentFragment();  
  for (var i = 0; i < 10; i ++) {  
    anchor = document.createElement('a');  
    anchor.innerHTML = 'test';  
    fragment.appendChild(anchor);  
  }  
  element.appendChild(fragment);  

 

本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/emu/archive/2010/03/01/5334583.aspx



疯狂 2010-10-17 23:53 发表评论
]]>
Tomcat内存溢出的三U情况及解决办法分析 http://www.tkk7.com/freeman1984/archive/2010/10/16/335295.html疯狂疯狂Sat, 16 Oct 2010 05:28:00 GMThttp://www.tkk7.com/freeman1984/archive/2010/10/16/335295.htmlhttp://www.tkk7.com/freeman1984/comments/335295.htmlhttp://www.tkk7.com/freeman1984/archive/2010/10/16/335295.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/335295.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/335295.html Tomcat内存溢出的原?

    在生产环境中tomcat内存讄不好很容易出现内存溢出。造成内存原因是不一LQ当然处理方式也不一栗?/p>

    q里Ҏqx遇到的情况和相关资料q行一个ȝ。常见的一般会有下面三U情况:

    1.OutOfMemoryErrorQ?Java heap space

    2.OutOfMemoryErrorQ?PermGen space

    3.OutOfMemoryErrorQ?unable to create new native thread.

    Tomcat内存溢出解决Ҏ

    对于前两U情况,在应用本w没有内存泄露的情况下可以用讄tomcat jvm参数来解冟뀂(-Xms -Xmx -XXQPermSize  -XXQMaxPermSizeQ?/p>

    最后一U可能需要调整操作系l和tomcat jvm参数同时调整才能辑ֈ目的?/p>

    W一U:是堆溢出?

    在JVM中如?8Q的旉是用于GC且可用的 Heap size 不2Q的时候将抛出此异怿息?/p>

    没有内存泄露的情况下Q调?Xms -Xmx参数可以解决?/p>

    -XmsQ初始堆大小

    -XmxQ最大堆大小

    但堆的大受下面三方面媄响:

    1.相关操作pȝ的数据模型(32-btq是64-bitQ限ӞQ?2位系l下Q一般限制在1.5G~2GQ我?003 server pȝ下(物理内存Q?G?GQjdkQ?.6Q测?1612MQ?4为操作系l对内存无限制。)

    2.pȝ的可用虚拟内存限Ӟ

    3.pȝ的可用物理内存限制?/p>

    堆的大小可以使用 java -Xmx***M  version 命o来测?。支持的话会出现jdk的版本号Q不支持会报错?/p>

    -Xms -Xmx一般配|成一h较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m

    W二U:怹保存区域溢出

    PermGen space的全U是Permanent Generation spaceQ是指内存的怹保存区域。这一部分用于存放Class和Meta的信息,Class在被 Load的时候被攑օPermGen space区域Q它和和存放Instance的Heap区域不同QGCQGarbage CollectionQ不会在ȝ序运行期对PermGen spaceq行清理Q所以如果你的APP会LOAD很多CLASS的话Q就很可能出现PermGen space错误。这U错误常见在web服务?对JSPq行pre compile的时候。但目前的hibernate和spring目中也很容易出现这L问题。http://www.javaeye.com/topic/80620 ?page=1 的帖子有讨论的这个问题。可能是׃q些框架会动态classQ而且jvm的gc是不会清理PemGen space的,D内存溢出?/p>

    q一个一般是加大-XXQPermSize  -XXQMaxPermSize 来解决问题?/p>

    -XXQPermSize 怹保存区域初始大小

    -XXQPermSize 怹保存区域初始最大?/p>

    q一般结合第一条用,比如 set JAVA_OPTS= -Xms1024m -Xmx1024m  -XXQPermSize=128M -XXQPermSize=256M

    有一炚w要注意:java -Xmx***M  version 命o来测试的最大堆内存?-Xmx?-XXQPermSize??比如pȝ支持最大的jvm堆大事1.5GQ那  -Xmx1024m  -XXQPermSize=768M 是无法运行的?/p>

    W三U:无法创徏新的U程?

    q种现象比较见Q也比较奇怪,主要是和jvm与系l内存的比例有关?/p>

    q种怪事是因为JVM已经被系l分配了大量的内存(比如1.5GQ,q且它至要占用可用内存的一半。有人发玎ͼ在线E个数很多的情况下,你分配给JVM 的内存越多,那么Q上q错误发生的可能性就大?/p>

    产生q种现象的原因如下(从这个blog中了解到原因Qhttp://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html Q:

    每一?2位的q程最多可以?G的可用内存,因ؓ另外2G被操作系l保留。这里假设?.5GlJVMQ那么还余下500M可用内存。这500M内存中的一部分必须用于pȝdll的加载,那么真正剩下的也许只?00MQ现在关键的地方出现了:当你使用Java 创徏一个线E,在JVM的内存里也会创徏一个Thread对象Q但是同时也会在操作pȝ里创Z个真正的物理U程Q参考JVM规范Q,操作pȝ会在余下?00兆内存里创徏q个物理U程Q而不是在JVM?500M的内存堆里创建。在jdk1.4里头Q默认的栈大是256KBQ但是在jdk1.5里头Q默认的栈大ؓ1M每线E,因此Q在余下400M的可用内存里Ҏ们最多也只能创徏400个可用线E?/p>

    q样l论出来了Q要惛_建更多的U程Q你必须减少分配lJVM的最大内存。还有一U做法是让JVM宿主在你的JNI代码里边?/p>

    l出一个有兌够创建线E的最大个数的估算公式Q?/p>

    QMaxProcessMemory - JVMMemory - ReservedOsMemoryQ?/ QThreadStackSizeQ?= Number of threads

    对于jdk1.5而言Q假设操作系l保?20M内存Q?/p>

    1.5GB JVMQ?Q?GB-1.5Gb-120MBQ?Q?MBQ?= ~380 threads

    1.0GB JVMQ?Q?GB-1.0Gb-120MBQ?Q?MBQ?= ~880 threads

    ?000/XP/2003的boot.ini里头有一个启动选项Q好像是Q?PAE /3G Q可以让用户q程最大内存扩充至3GQ这时操作系l只能占用最?G的虚存。那样应该可以让JVM创徏更多的线E?/p>

    因此q种情况需要结合操作系l进行相兌整?/p>

    因此Q我们需要结合不同情况对tomcat内存分配q行不同的诊断才能从Ҏ上解决问题?/p>

    以上是针对Tomcat内存溢出的几U解x案。本文来自George的博客:《tomcat内存溢出ȝ?/p>


本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/Senton/archive/2010/07/01/5707446.aspx



疯狂 2010-10-16 13:28 发表评论
]]>
Tomcat启动分析server.xml http://www.tkk7.com/freeman1984/archive/2010/10/11/334485.html疯狂疯狂Mon, 11 Oct 2010 15:13:00 GMThttp://www.tkk7.com/freeman1984/archive/2010/10/11/334485.htmlhttp://www.tkk7.com/freeman1984/comments/334485.htmlhttp://www.tkk7.com/freeman1984/archive/2010/10/11/334485.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/334485.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/334485.html

1 - Tomcat Server的组成部?
1.1 - Server

A Server element represents the entire Catalina servlet container. (Singleton)

1.2 - Service

A Service element represents the combination of one or more Connector components that share a single Engine
Service是这样一个集合:它由一个或者多个Connectorl成Q以及一个EngineQ负责处理所有Connector所获得的客戯?/font>

1.3 - Connector

一个Connector在某个指定端口上侦听客戯求,q将获得的请求交lEngine来处理,从Engine处获得回应ƈq回客户
TOMCAT有两个典型的ConnectorQ一个直接侦听来自browser的httphQ一个侦听来自其它WebServer的请?br /> Coyote Http/1.1 Connector 在端?080处侦听来自客户browser的httph
Coyote JK2 Connector 在端?009处侦听来自其它WebServer(Apache)的servlet/jsp代理h

1.4 - Engine

The Engine element represents the entire request processing machinery associated with a particular Service
It receives and processes all requests from one or more Connectors
and returns the completed response to the Connector for ultimate transmission back to the client
Engine下可以配|多个虚拟主机Virtual HostQ每个虚拟主机都有一个域?br /> 当Engine获得一个请求时Q它把该h匚w到某个Host上,然后把该h交给该Host来处?br /> Engine有一个默认虚拟主机,当请求无法匹配到M一个Host上的时候,交l该默认Host来处?/font>

1.5 - Host

代表一个Virtual HostQ虚拟主机,每个虚拟L和某个网l域名Domain Name相匹?br /> 每个虚拟L下都可以部v(deploy)一个或者多个Web AppQ每个Web App对应于一个ContextQ有一个Context path
当Host获得一个请求时Q将把该h匚w到某个Context上,然后把该h交给该Context来处?br /> 匚w的方法是“最长匹?#8221;Q所以一个path==""的Context成Host的默认Context
所有无法和其它Context的\径名匚w的请求都最l和该默认Context匚w


1.6 - Context

一个Context对应于一个Web ApplicationQ一个Web Application׃个或者多个Servletl成
Context在创建的时候将Ҏ配置文gQCATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml载入Servletc?br /> 当Context获得hӞ在自己的映表(mapping table)中寻扄匚w的Servletc?br /> 如果扑ֈQ则执行该类Q获得请求的回应Qƈq回

2 - Tomcat Server的结构图
 
3 - 配置文gQCATALINA_HOME/conf/server.xml的说?
该文件描qC如何启动Tomcat Server


<!----------------------------------------------------------------------------------------------->


<!-- 启动Server
     在端?005处等待关闭命?br />      如果接受?SHUTDOWN"字符串则关闭服务?br />      -->

<Server port="8005" shutdown="SHUTDOWN" debug="0">


  <!-- Listener ???
       目前没有看到q里
       -->

  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" debug="0"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" debug="0"/>


  <!-- Global JNDI resources ???
       目前没有看到q里Q先略去
       -->

  <GlobalNamingResources>
    ... ... ... ...
  </GlobalNamingResources>

  <!-- Tomcat的Standalone Service
       Service是一lConnector的集?br />        它们q一个Engine来处理所有Connector收到的请?br />        -->

  <Service name="Tomcat-Standalone">


    <!-- Coyote HTTP/1.1 Connector
         className : 该Connector的实现类是org.apache.coyote.tomcat4.CoyoteConnector
         port : 在端口号8080处侦听来自客户browser的HTTP1.1h
         minProcessors : 该Connector先创?个线E等待客戯求,每个h׃个线E负?br />          maxProcessors : 当现有的U程不够服务客户hӞ若线EL不75个,则创建新U程来处理请?br />          acceptCount : 当现有线E已l达到最大数75Ӟ为客戯求排?br />                        当队列中h数超q?00Ӟ后来的请求返回Connection refused错误
         redirectport : 当客戯求是httpsӞ把该h转发到端?443?br />          其它属性略
         -->

    <Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
               port="8080"
               minProcessors="5" maxProcessors="75" acceptCount="100"
               enableLookups="true"
               redirectPort="8443"
               debug="0"
               connectionTimeout="20000"
               useURIValidationHack="false"
               disableUploadTimeout="true" />


    <!-- Engine用来处理Connector收到的Httph
         它将匚wh和自q虚拟LQƈ把请求{交给对应的Host来处?br />          默认虚拟L是localhost
         -->

    <Engine name="Standalone" defaultHost="localhost" debug="0">
   

      <!-- 日志c,目前没有看到Q略d -->

      <Logger className="org.apache.catalina.logger.FileLogger" .../>

      <!-- RealmQ目前没有看刎ͼ略去?-->

      <Realm className="org.apache.catalina.realm.UserDatabaseRealm" .../>


      <!-- 虚拟Llocalhost
           appBase : 该虚拟主机的根目录是webapps/
           它将匚wh和自qContext的\径,q把h转交l对应的Context来处?br />            -->

      <Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true">
     

        <!-- 日志c,目前没有看到Q略d -->

        <Logger className="org.apache.catalina.logger.FileLogger" .../>
     

        <!-- ContextQ对应于一个Web App
             path : 该Context的\径名?"Q故该Context是该Host的默认Context
             docBase : 该Context的根目录是webapps/mycontext/
             -->

        <Context path="" docBase="mycontext" debug="0"/>
       

        <!-- 另外一个ContextQ\径名?wsota -->

        <Context path="/wsota" docBase="wsotaProject" debug="0"/>
            
       
      </Host>
     
    </Engine>

  </Service>

</Server>


<!----------------------------------------------------------------------------------------------->

 

4 - Context的部|配|文件web.xml的说?
一个Context对应于一个Web AppQ每个Web App是由一个或者多个servletl成?br /> 当一个Web App被初始化的时候,它将用自qClassLoader对象载入“部v配置文gweb.xml”中定义的每个servletc?br /> 它首先蝲入在QCATALINA_HOME/conf/web.xml中部|的servletc?br /> 然后载入在自qWeb App根目录下的WEB-INF/web.xml中部|的servletc?br /> web.xml文g有两部分Qservletcd义和servlet映射定义
每个被蝲入的servletc都有一个名字,且被填入该Context的映表(mapping table)中,和某UURL PATTERN对应
当该Context获得hӞ查询mapping tableQ找到被h的servletQƈ执行以获得请求回?/font>


  分析一下所有的Context׃n的web.xml文gQ在其中定义的servlet被所有的Web App载入

 


<!----------------------------------------------------------------------------------------------->


<web-app>


  <!-- 概述Q?br />        该文件是所有的WEB APPq的部|配|文Ӟ
       每当一个WEB APP被DEPLOYQ该文g都将先被处理Q然后才是WEB APP自己?WEB-INF/web.xml
       -->

 

  <!--  +-------------------------+  -->
  <!--  |    servletcd义部?nbsp;   |  -->
  <!--  +-------------------------+  -->

  <!-- DefaultServlet
       当用LHTTPh无法匚wM一个servlet的时候,该servlet被执?br />        URL PATTERN MAPPING : /
       -->

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.DefaultServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>


  <!-- InvokerServlet
       处理一个WEB APP中的匿名servlet
       当一个servlet被编写ƈ~译攑օ/WEB-INF/classes/中,却没有在/WEB-INF/web.xml中定义的时?br />        该servlet被调用,把匿名servlet映射?servlet/ClassName的Ş?br />        URL PATTERN MAPPING : /servlet/*
       -->

    <servlet>
        <servlet-name>invoker</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>


  <!-- JspServlet
       当请求的是一个JSP面的时候(*.jspQ该servlet被调?br />        它是一个JSP~译器,请求的JSP面~译成ؓservlet再执?br />        URL PATTERN MAPPING : *.jsp
       -->

    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>logVerbosityLevel</param-name>
            <param-value>WARNING</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>

 

  <!--  +---------------------------+  -->
  <!--  |    servlet映射定义部分    |  -->
  <!--  +---------------------------+  -->

   
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>invoker</servlet-name>
        <url-pattern>/servlet/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
    </servlet-mapping>


  <!--  +------------------------+  -->
  <!--  |    其它部分Q略d    |  -->
  <!--  +------------------------+  -->

    ... ... ... ...

</web-app>


<!----------------------------------------------------------------------------------------------->

 

5 - Tomcat Server处理一个httph的过E?
假设来自客户的请求ؓQ?br />
http://localhost:8080/wsota/wsota_index.jsp

1) h被发送到本机端口8080Q被在那里侦听的Coyote HTTP/1.1 Connector获得

2) Connector把该h交给它所在的Service的Engine来处理,q等待来自Engine的回?/font>

3) Engine获得hlocalhost/wsota/wsota_index.jspQ匹配它所拥有的所有虚拟主机Host

4) Engine匚w到名为localhost的HostQ即使匹配不C把请求交l该Host处理Q因Host被定义ؓ该Engine的默认主机)

5) localhost Host获得h/wsota/wsota_index.jspQ匹配它所拥有的所有Context

6) Host匚w到\径ؓ/wsota的ContextQ如果匹配不到就把该h交给路径名ؓ""的Contextd理)

7) path="/wsota"的Context获得h/wsota_index.jspQ在它的mapping table中寻扑֯应的servlet

8) Context匚w到URL PATTERN?.jsp的servletQ对应于JspServletc?/font>

9) 构造HttpServletRequest对象和HttpServletResponse对象Q作为参数调用JspServlet的doGet或doPostҎ

10)Context把执行完了之后的HttpServletResponse对象q回lHost

11)Host把HttpServletResponse对象q回lEngine

12)Engine把HttpServletResponse对象q回lConnector

13)Connector把HttpServletResponse对象q回l客户browser

转蝲自:http://www.360doc.com/content/05/1116/10/2689_31126.shtml

疯狂 2010-10-11 23:13 发表评论
]]>
Java虚拟机参?-XX{相兛_数应?/title><link>http://www.tkk7.com/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.tkk7.com/freeman1984/archive/2010/10/11/334483.html</guid><wfw:comment>http://www.tkk7.com/freeman1984/comments/334483.html</wfw:comment><comments>http://www.tkk7.com/freeman1984/archive/2010/10/11/334483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/freeman1984/comments/commentRss/334483.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/freeman1984/services/trackbacks/334483.html</trackback:ping><description><![CDATA[<p><br />官方译文档见:<a >http://www.cnblogs.com/z-zw/archive/2010/09/30/1839394.html</a><br />通常Q我们ؓ了避免内存溢出等问题Q需要设|环境变?br />JAVA_OPTS    -Xms256M -Xmx512M {,【对于服务器Q一般都讄成一L?br />但是有的时候可能这L讄q会不行(比如Q当Server应用E序加蝲较多cLQ即jvm加蝲cLQ永久域中的对象急剧增加Q从而jvm不断调整怹域大,Z避免调整)Q你可以使用更多的参数配|,如: java -Xms512m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=128m<br />其中Q?nbsp;  -XX:MaxPerSize标志来增加永久域的大,-XX:PerSize标志讄初始?/p> <p>-XX</p> <p>Z Sun ?Java 2 Standard EditionQJ2SEQ? 有生成垃圑֛收功能,q允许分隔内存池以包含不同时效的对象。垃圑֛收@环根据时效收集与其他对象彼此独立的对象。用其他参敎ͼ您可以单独设|内存池?大小。ؓ了实现更好的性能Q您应该对包含短期存zd象的池的大小q行讄Q以使该池中的对象的存活旉不会过一个垃圑֛收@环。新生成的池的大由 NewSize ?MaxNewSize 参数定?/p> <p>W一ơ垃圑֛收@环中存活下来的对象{Ud另一个池中。生q者池的大由参数 SurvivorRatio 定?如果垃圾回收变成了瓶颈,您可以尝试定制生成池讄。要监控垃圾回收l计信息Q?Tivoli Performance Viewer 中的对象l计信息?verbose:gc 配置讄?输入下列| <br />-XX:NewSize (lower bound)<br />-XX:MaxNewSize (upper bound)<br />-XX:SurvivorRatio=NewRatioSize <br />-XX:NewSize 320m 此D大可调大新对象区Q减Full GCơ数<br />-XX:+UseParNewGC Q羃短minor攉的时?可用来设|ƈ行收集【多CPU?br />-XX:+ParallelGCThreads 可用来增加ƈ行度【多CPU?br />-XX:+UseParallelGC 讄后可以用ƈ行清除收集器【多CPU?XssQ每个线E的Stack大小</p> <p>-verbose:gc 昄垃圾攉信息<br />-Xloggc:gc.log 指定垃圾攉日志文g<br />刚刚了解到的一些参敎ͼ待实跉|试)<br />-XmnQyoung generation的heap大小Q一般设|ؓXmx??分之一<br />-XX:+UseConcMarkSweepGC Q羃短major攉的时?br />提示Q此选项在Heap Size 比较大而且Major攉旉较长的情况下使用更合?/p> <p>下面的命令把整个堆设|成128mQ新域比率设|成3Q即新域与旧域比例ؓ1Q?Q新域ؓ堆的1/4?2MQ?/p> <p>java –Xms128m –Xmx128m –XX:NewRatio =3~省gؓQNewSize=2m MaxNewSize=32m SurvivorRatio=2。但是,如果 JVM 的堆大小大于 1GBQ则应该使用|-XX:newSize=640m -XX:MaxNewSize=640m -XX:SurvivorRatio=16Q或者将堆的d的 50% ?60% 分配l新生成的池?/p> <p>          举例Q永久域默认大小?m。运行程序时Qjvm会调整永久域的大以满需要。每ơ调整时Qjvm会对堆进行一ơ完全的垃圾攉?/p> <p>使用-XX:MaxPerSize标志来增加永久域的大。在WebLogic Server应用E序加蝲较多cLQ经帔R要增加永久域的最大倹{当jvm加蝲cLQ永久域中的对象急剧增加Q从而jvm不断调整怹域大。ؓ了避?调整Q可使用-XX:PerSize标志讄初始倹{?br />   下面把永久域初始D|成32mQ最大D|成64m?br />    java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m</p> <p>默认状态下QHotSpot在新域中使用复制攉器。该域一般分Z个部分。第一部分为EdenQ用于生成新的对象。另两部分称为救助空_当Eden?满时Q收集器停止应用E序Q把所有可到达对象复制到当前的from救助I间Q一旦当前的from救助I间充满Q收集器则把可到辑֯象复制到当前的to救助 I间。From和to救助I间互换角色。维持活动的对象在救助I间不断复制Q直到它们获得用期q{入旧域。?XX:SurvivorRatio?控制新域子空间的大小?/p> <p>目前Q我的的开发环?2G内存Qtomcat+eclipse 大型应用E序<br />java -Xmx1024m -XX:PermSize=512m   基本ok大部分应用了</p> <p> </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>本文出处Qhttp://hi.baidu.com/china8jie/blog/item/7c4ac1a2e25a9fa5caefd0d1.html</p> <p> </p> <ol><li><strong>常见配置汇?/strong> </li><li>堆设|? <ul><li><strong>-Xms</strong> :初始堆大?</li><li><strong>-Xmx</strong> :最大堆大小 </li><li><strong>-XX:NewSize=n</strong> :讄q轻代大?</li><li><strong>-XX:NewRatio=n:</strong> 讄q轻代和q老代的比倹{如:?Q表C年M与年老代比gؓ1Q?Q年M占整个年Mq老代和的1/4 </li><li><strong>-XX:SurvivorRatio=n</strong> :q轻代中EdenZ两个Survivor区的比倹{注意Survivor区有两个。如Q?Q表CEdenQSurvivor=3Q?Q一个Survivor区占整个q轻代的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> :讄q行攉?</li><li><strong>-XX:+UseParalledlOldGC</strong> :讄q行q老代攉?</li><li><strong>-XX:+UseConcMarkSweepGC</strong> :讄q发攉?/li></ul></li><li>垃圾回收l计信息 <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>q行攉器设|? <ul><li><strong>-XX:ParallelGCThreads=n</strong> :讄q行攉器收集时使用的CPU数。ƈ行收集线E数?</li><li><strong>-XX:MaxGCPauseMillis=n</strong> :讄q行攉最大暂停时?</li><li><strong>-XX:GCTimeRatio=n</strong> :讄垃圾回收旉占程序运行时间的癑ֈ比。公式ؓ1/(1+n)</li></ul></li><li>q发攉器设|? <ul><li><strong>-XX:+CMSIncrementalMode</strong> :讄为增量模式。适用于单CPU情况?</li><li><strong>-XX:ParallelGCThreads=n</strong> :讄q发攉器年M攉方式为ƈ行收集时Q用的CPU数。ƈ行收集线E数?/li></ul></li></ol> <p><br /></p><img src ="http://www.tkk7.com/freeman1984/aggbug/334483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/freeman1984/" target="_blank">疯狂</a> 2010-10-11 23:03 <a href="http://www.tkk7.com/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.tkk7.com/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.tkk7.com/freeman1984/archive/2010/10/10/334235.html</guid><wfw:comment>http://www.tkk7.com/freeman1984/comments/334235.html</wfw:comment><comments>http://www.tkk7.com/freeman1984/archive/2010/10/10/334235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/freeman1984/comments/commentRss/334235.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/freeman1984/services/trackbacks/334235.html</trackback:ping><description><![CDATA[<p> </p> <p>?i?0gQOracle不断q化自己的SQL TuningQ一些秘c的优化口诀已经失效?br />    但我喜欢失效Q不用记口诀Q操个Toad for Oracle Xpert Q按照大方向舒舒服服的调优才是爱做的事情?/p> <p>1.Excution Plan<br />      Excution Plan是最基本的调优概念,不管你的调优吹得如何天花乱堕Q结果还是要由Excution plan来显COracle 最l用什么烦引、按什么顺序连接各表,Full Table Scanq是Access by Rowid IndexQ瓶颈在什么地斏V如果没有它的指|一切调优都是蒙的?/p> <p><br /> 2.Toad for Oracle Xpert<br />     用它来调优在真的好舒服。Quest 吞ƈ了Lecco后,它整合CToad 的SQL Tunning里面Q最清晰的执行计划显C,自动生成N条等价SQL、给Z化徏议,不同SQL执行计划的对比,q有实际执行的逻辑诅R物理读数据{等一目了然?/p> <p><br /> 3.索引<br />    大部分的性能问题其实都是索引应用的问题,Where子句、Order By、Group By 都要用到索引?br />    一般开发h员认为将索引建全了就可以下班回家了,实则q有颇多的思量和陷阱?/p> <p>3.1 索引列上不要q行计算<br />       q是最最普遍的失效陷阱,比如where trunc(order_date)=trunc(sysdate), i+2>4。烦引失效的原因也简单,索引是针对原值徏的二叉树Q你列?3/4+2折腾一番后Q原来的二叉树当然就用不上了。解决的Ҏ:<br />   1. 换成{h语法Q比如trunc(order_date) 换成</p> <p>where order_date>trunc(sysdate)-1 and order_date<trunc(sysdate)+1  2.    特别徏立函数烦?/p> <p>create index Q_XXXX on shop_order(trunc(order_date))    3.    计从{号左边Ud双<br />  q是针对某些无心之失的纠正,把a*2>4 改ؓa>4/2Q把TO_CHAR(zip) = '94002' 改ؓzip = TO_NUMBER('94002');</p> <p>3.2 CBO与烦引选择?br />      Z索引也不一定会被Oracle用的Q就像个挑食的孩子。基于成本的优化?CBO, Cost-Based Optimizer)Q会先看看表的大,q有索引的重复度Q再军_用还是不用。表中有100 条记录而其中有80 个不重复的烦引键? q个索引的选择性就?0/100 = 0.8Q留意Toad里显C烦引的Selective和Cardinailty。实在不听话Ӟp用hints来调教?br />      另外Qwhere语句存在多条索引可用Ӟ只会选择其中一条。所以烦引也不是多好Q)</p> <p>3.3 索引重徏<br />      传说中数据更新频J导致有20%的碎片时QOracle׃攑ּq个索引。宁可信其有之下Q应该时常alter index <INDEXNAME> rebuild一下?/p> <p>3.4 其他要注意的地方<br />       不要使用NotQ如goods_no != 2Q要改ؓ</p> <p>where goods_no>2 or goods_no<2      不要使用is null , 如WHERE DEPT_CODE IS NOT NULL 要改?/p> <p>WHERE DEPT_CODE >=0;3.5 select 的列如果全是索引列时<br />    又如果没有where 条gQ或者where条g全部是烦引列ӞOracle 直接从索引里获取数据而不去读真实的数据表Q这样子理论上会快很多,比如</p> <p>select order_no,order_time from shop_order where shop_no=4当order_no,order_time,shop_no q三列全为烦引列Ӟ你将看到一个和qx完全不同的执行计划?/p> <p>3.6 位图索引<br />      传说中当数据D,比如某些表示分类、状态的列,应该Z囄引而不是普通的二叉树烦引,否则效率低下。不q看执行计划Q这些位囄引鲜有被Oracle临幸的?br />   </p> <p><br /> 4.减少查询往q和查询的表<br /> q也是很单的大道理,E序与Oracle交互的成本极高,所以一个查询能完成的不要分开两次查,如果一个@环执行1万条查询的,怎么都快不到哪里M?/p> <p>4.1 装PL/SQL存储q程<br />   最高的做法是把@环的操作装到PL/SQL写的存储q程里,因ؓ存储q程都在服务端执行,所以没有数据往q的消耗?/p> <p><br /> 4.2 装PL/SQL内部函数<br />   有机会,一些查询封装到函数里,而在普通SQL里用这些函敎ͼ同样是很有效的优化?/p> <p>4.3 Decode/Case<br />   但存储过E也ȝQ所以有case/decode把几条条件基本相同的重复查询合ƈZ条的用法Q?/p> <p>SELECT<br />  COUNT(CASE WHEN price < 13 THEN 1 ELSE null END) low,<br />  COUNT(CASE WHEN price BETWEEN 13 AND 15 THEN 1 ELSE null END) med,<br />  COUNT(CASE WHEN price > 15 THEN 1 ELSE null END) high<br /> FROM products;4.4 一UWhere/Update语法</p> <p>SELECT TAB_NAME FROM TABLES<br /> WHERE (TAB_NAME,DB_VER) = Q? 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 />      qHibernate 新版也支持ROWID了,证明它非常有用。比如号U删除重复数据的最快写法:</p> <p>DELETE FROM EMP E<br /> WHERE E.ROWID > (SELECT MIN(X.ROWID)<br /> FROM EMP X<br /> WHERE X.EMP_NO = E.EMP_NO);6.l极U技 - Hints<br />    q是Oracle DBA的玩P也是l极武器Q比如Oracle在CBO,RBO中所做的选择M合自己心水时Q可以用它来强力调教一下OracleQ结果经常让人喜出望外?br />    如果开发h员没那么多时间来专门学习它,可以依靠Toad SQL opmitzer 来自动生成这些提C,然后Ҏ一下各U提C的实际效果。不q随着10g的进化,hints的惊喜少了?/p> <p>7. 扑և要优化的Top SQL<br />     了q么久的枪,如果找不到敌人是仉L事情?br />     q怺10gq方面做得非常好。进入Web理界面Q就能看到当前或者Q意一天的SQL列表Q按性能排序?br />     有了它,SQL Trace和TKPROF都可以不用了?/p> <p><br /> 本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/calvinxiu/archive/2005/11/15/529756.aspx</p> <img src ="http://www.tkk7.com/freeman1984/aggbug/334235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/freeman1984/" target="_blank">疯狂</a> 2010-10-10 23:52 <a href="http://www.tkk7.com/freeman1984/archive/2010/10/10/334235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>google Analytics 初探http://www.tkk7.com/freeman1984/archive/2010/09/16/332234.html疯狂疯狂Thu, 16 Sep 2010 13:37:00 GMThttp://www.tkk7.com/freeman1984/archive/2010/09/16/332234.htmlhttp://www.tkk7.com/freeman1984/comments/332234.htmlhttp://www.tkk7.com/freeman1984/archive/2010/09/16/332234.html#Feedback2http://www.tkk7.com/freeman1984/comments/commentRss/332234.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/332234.html http://code.google.com/intl/zh-CN/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html
当然要想用的更好需要去研究下他的apiQ包扩一些新ҎQ和一些统计的api。这文章是关于豆瓣|的使用l验Q后面还附加了点评网的代码?br />    内容如下Q?

豆瓣从今q开始也加入 Google Analytics 的统计阵营。让我们通过它加载的 Google Analytics 源码Q简单分析一下它都是怎么应用的?/p>

我们先从豆瓣的源码来看看它的Google Analyticsl计代码

豆瓣 Google Analytics 代码
豆瓣 Google Analytics 代码

我们知道一般默认的 Google Analytics代码如下Q?/p>

默认  Google Analytics l计代码
默认 Google Analytics l计代码

两相ҎQ我们就会发现豆瓣加?ga.js 的方式与默认的方式有些不太一P׃豆瓣q没有采?https 加密讉KQ所以撇弃了默认的ga.js加蝲方式?/p>

默认的统计函敎ͼpageTracker 也被豆瓣Ҏ?_ga Q这个只是名U定义上的区别,q没有什么实质的改变。豆瓣的主要应用是下面两个函敎ͼ

使用 _ga._addOrganic 识别非主搜索引?/h3>

再来看豆瓣比默认 Google Analytics 代码增加的部分,那就是多了数?_ga._addOrganic Q这?Google Analytics d自定义搜索引擎的代码。尽?Google Analytics 对于L的搜索引擎都能自动识别,但毕竟能识别的是国外的主搜索引擎,在国内,像搜狐的 SogouQQQ ?sosoQ网易的有道{搜索引擎,都不能被 Google Analytics 正确识别Q而被当作推荐来源。这时候我们就可以利用_addOrganic 参数来识别这些非L搜烦引擎Q如豆瓣的做法?/p>

使用 _addIgnoredOrganic 忽略关键?/h3>

除了d自定义搜索引擎,豆瓣在最后还d了如下这些代?

_ga._addIgnoredOrganic("豆瓣");
_ga._addIgnoredOrganic("douban");
_ga._addIgnoredOrganic("豆瓣|?);
_ga._addIgnoredOrganic("www.douban.com");

q些代码用来把引号中的关键词从搜索引擎的关键词报告中排除Q而当成直接点击量来源?/p>

Z么要q么做?因ؓ一个知名的大网站,来自q些品牌词的搜烦量都非常大Q常常是排在前几位的搜烦关键词来源,而这通常是因为搜索引擎养成现在的人都懒得记网址Q直接搜索品牌名来记住域名。这些品牌词对于|站的关键词来源分析q没有很直接的帮助,所以在来自品牌词的量很大的情况下Q可以直接把q些关键词识别成直接点击量来源?/p>

关于自定?Google Analytics 搜烦引擎?strong>排除特定关键词ؓ直接点击量来?/strong>的语法,可以参?a class="external" title="_addOrganic() ?_addIgnoredOrganic() 用法介绍" target="_blank"> Google Code 上关于这斚w的详l介l?/a>

通过 _setVar 识别用户

当我们登录豆瓣后Q再来分析豆瓣的源码Q会发现多了一?code>ga._setVar(”xxxx”)?Google Analytics 参数?/p>

豆瓣使用 Google Analytics ?_setVar参数来跟t登录用戯? src=
豆瓣使用 Google Analytics ?_setVar参数来跟t登录用戯?

_setVar() 函数?Google Analytics 的用户定义函敎ͼ主要用于对特定来源的用户行ؓq行分类Q例如可以对d览的用戯|一个数|然后?Google Analytics 后台?strong>讉K?用户定义 中查看其览属性?/p>

Google Analytics 讉K?用户定义报告
Google Analytics 讉K?用户定义报告

分析豆瓣的源码可以知道,豆瓣Ҏ一个登录后的用P都赋以一个专门的 id |q样可以在用户定义报告里Q看到整体的d用户讉K行ؓQ乃x个登录用L览行ؓ。通过q样讑֮后,豆瓣便可以轻易获取高忠诚度访问用L讉K行ؓ?a class="external" title="_setVar 讄说明" target="_blank">关于_setVar()的更多说明,请参?Google Analytics的技术文?/a>

如何Ҏ讉K者在我的|站上访问的面或在表单上做出的响应对其q行分类Q?a class="external" title=" 如何Ҏ讉K者在我的|站上访问的面或在表单上做出的响应对其q行分类Q? target="_blank">?Google Analytics 官方的帮助文Ӟ也给Z另外一个应用案?/a>

值得注意的是Q原来在讄 _setVar() 函数的时候,整个|站的蟩出率会出现重大的偏差Q不q在最q的google analytics官方博客Q指bug已经修正Q客户在q行q方面设|的时候,q是要注意对比前后数据是否有重大偏差?/p>

通过 _trackPageview 区分不同cd的评?/h2>

豆瓣上的书评Q媄评和乐评可以说是豆瓣|站的核心h值所在。一般评论的URL格式如下Q?/p>

豆瓣上单条评论的URL
豆瓣上单条评论的URL

当我们查看该面的网|代码Ӟ会发现有的现象:

豆瓣单条评论늚 Google Analytics 代码
豆瓣单条评论늚 Google Analytics 代码

我们知道Q一?Google Analytics ?code>_trackPageview() 括弧中的参数是留I的Q?Google Analytics 会自动捕L址?URL 参数Q如果在 _trackPageview()括弧中输入特定的数|那么?Google Analytics 的报表中QURL 是我们指定的参敎ͼ而不再是我们在地址栏看到的 URL?/p>

如上面的例子Q我们在 Google Analytics 中看到的URL是/book/review/1946018/Q而不再是我们在浏览器地址栏看到的/review/1946018/

当所在频道是电媄或者音乐时Q?code>_trackPageview() 中的参数根据所在频道的属性,变ؓ/movie/xxxxx 或?/music/xxxxx的数倹{?/p>

豆瓣通过对的参数q行重新指定Q主要有以下的好处:

保证了用户和搜烦引擎看到?URL 比较短,辑ֈ URL 对用户友好和Ҏ索引擎友好的目的Q而在 Google Analytics 报告中,通过 内容/内容l目/ 报告Q又能了解到各个频道ȝ览情况?/p>

在GA?span style="color: #ff0000">内容l目报告中,会多出 /book/ /music/ /movie/ q样的文件夹来,总而获得各个频道的合计览数据?/p>

而如果只是用默?_trackPageview()Q你只能得到所有评论页面的览数据Q而无法得到细分的各个频道的浏览数据?/p>

关于_trackPageview()的具体的使用Ҏ可参?Google Code 的说?/a>

注意事项:使用 _trackPageview() 参数重新指定 URL 之后Q网站覆盖图的数据将受到影响?a class="external" target="_blank">可参?Google Analytics 的官方帮助文?/a>

除了豆瓣使用 _trackPageview() 来对URLq行重写Q?a class="external" target="_blank">大众点评|?/a>也采用了cM的做法(应该是比豆瓣更早采用。。。因为是我在点评|Q职时候实验的做法;那时候豆瓣还没有使用 Google Analytis l计代码Q呵呵)Q有兴趣的同学可以自己去研究点评?Google Analytis 代码?br />

文章来自Qhttp://fairyfish.net/2009/06/30/google-analytics-in-douban/

----------------------------------------大众点评|的的代码,主页?br /> <script type="text/javascript">
var pageTracker = _gat._getTracker("UA-464026-1");
pageTracker._addOrganic("soso", "w");
pageTracker._addOrganic("sogou", "query");
pageTracker._addOrganic("yodao", "q");
pageTracker._addOrganic("bing", "q");
pageTracker._addOrganic("gougou", "search");
pageTracker._initData();
pageTracker._trackPageview("home/beijing_all");
</script>
     
   q个是子面search/category/2/10/g328
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-464026-1");
pageTracker._addOrganic("soso", "w");
pageTracker._addOrganic("sogou", "query");
pageTracker._addOrganic("yodao", "q");
pageTracker._addOrganic("bing", "q");
pageTracker._addOrganic("gougou", "search");
pageTracker._initData();
pageTracker._trackPageview("dp_searchpv_card");
pageTracker._trackPageview("dp_searchpv_promo");
pageTracker._trackPageview("search/beijing_food_category/g328");
</script>
可以看出其中的pageTracker._trackPageview("。。?);是动态的也就是页面的Q我们可以动态的赋|q样可以显C正的地址了?/p>

 

  大家如果有什么这斚w的经验可以一同分享下?br />
   



疯狂 2010-09-16 21:37 发表评论
]]>使用tomcat的compression来提高网加载速度http://www.tkk7.com/freeman1984/archive/2010/09/15/332121.html疯狂疯狂Wed, 15 Sep 2010 15:39:00 GMThttp://www.tkk7.com/freeman1984/archive/2010/09/15/332121.htmlhttp://www.tkk7.com/freeman1984/comments/332121.htmlhttp://www.tkk7.com/freeman1984/archive/2010/09/15/332121.html#Feedback4http://www.tkk7.com/freeman1984/comments/commentRss/332121.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/332121.html         tomcat使用HTTP/1.1 GZIP 来压~,以减带宽压力,
       首先介绍下gzipQ?br />         HTTP协议上的GZIP~码是一U用来改qWEB应用E序性能的技术。大量的WEB站点常常使用GZIP压羃技术来让用h受更快的速度。这一般是指WWW服务器中安装的一个功?当有人来讉Kq个服务器中的网站时,服务器中的这个功能就网内容压~后传输到来访的电脑览器中昄出来.一般对U文本内容可压羃到原大小?0Q?q样传输快?效果是你点ȝ址后会很快的显C出?当然q也会增加服务器的负? 一般服务器中都安装有这个功能模块的.
      我们使用单的例子来介ltomcat的压~用:Q用firebug查看h情况Q?br />
 首先是一个简单的servletQ?br /> 内容Q?br />
public void doPost(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, IOException {

        response.setContentType(
"text/html");
        PrintWriter out 
= response.getWriter();
        out
                .println(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println(
"  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println(
"  <BODY>");
        out.print(
" <select> ");
        
for (int i = 0; i < 100000; i++{
            out.print(
"<option>testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest"+i+"</option>");
        }

        out.println(
"</select>");
        out.println(
"  </BODY>");
        out.println(
"</HTML>");
        out.flush();
        out.close();
    }

我们输Z个十万个选项的下拉框Q在不用的压羃的时候:


    h数据辑ֈ9m ,大概的计下我的下蝲用时Q?m长城宽带Q:9*1024/(4*1024/8)=18m  Q加上多人共享带宽,也就是差不多20m。firebug昄20.96?br />
    q个速度|站体验肯定是很差的Q接下来使用tomcat的压~以后看看:

   当然是要对其q行配置Q?br />    有以下几个参数可以用:

    compression="on" 
是否启用压羃 on为启用(文本数据压羃Q?offZ启用Q?force 压羃所有数?br /> compressionMinSize1="2048" 
当超q最数据大才q行压羃
 noCompressionUserAgents="gozilla, traviata" 
哪些客户端发出的h不压~,默认是不限制
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
配置惛_~的数据cdQ默认是 text/html,text/xml,text/plain

配置以后是这LQ?br />
<Connector port="8088" protocol="HTTP/1.1" 
               connectionTimeout
="20000" 
               redirectPort
="8443"
               compression
="on" 
               compressionMinSize1
="2048" 
               noCompressionUserAgents
="gozilla, traviata" 
               compressableMimeType
="text/html,text/xml,text/javascript,text/css,text/plain"/>

启动后再看:

 
q次数据被压~到274.7kQ响应速度也减了一半,当然Q服务器的数据压~和览器的数据解压都需要用时间?br />
 
例子完毕Q?br />    当然tomcat的压~技术还有很多其他的Ҏ,然而对于大数据量的h不光是要使用q种技术,q需要在其他地方下功夫,比如ajax技术,~存{等Q?br /> 也希望大家补充学习,谢谢?br />  


疯狂 2010-09-15 23:39 发表评论
]]>
QQ Dmysql 服务无法启动http://www.tkk7.com/freeman1984/archive/2010/09/06/331173.html疯狂疯狂Mon, 06 Sep 2010 02:59:00 GMThttp://www.tkk7.com/freeman1984/archive/2010/09/06/331173.htmlhttp://www.tkk7.com/freeman1984/comments/331173.htmlhttp://www.tkk7.com/freeman1984/archive/2010/09/06/331173.html#Feedback0http://www.tkk7.com/freeman1984/comments/commentRss/331173.htmlhttp://www.tkk7.com/freeman1984/services/trackbacks/331173.html

l果一看竟然被qqq程占用着Qƈ且处于close_wait状态?br /> 处理ҎQ直接干掉qqq程Q然后启动mysql卛_?br />
以下是关于tcp 状态一些介l?供大家参考:
 Close_Wait状态解?/span>

CLOSE_WAIT状态的生成原因
通过TCP的状态图我们可以看出只有被动关闭的一端才有CLOSE_WAIT状态,当收到Finq发送了Ack?br /> 服务器状态就变成了CLOSE_WAIT状态,如果我们的服务器一直处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!Qƈ且没有发送Fin信oQ原因往往是没有调用TCP的CloseSocket?/p>

解决CLOSE_WAIT的方?
1 一般原因都是TCPq接没有调用关闭Ҏ。需要应用来处理|络链接关闭?br /> 2 对于Webh出现q个原因Q经常是因ؓResponse的BodyStream没有调用Close.
比如Widnows?
使用HttpWebRequest 一定要保证GetRequestStream和GetResponse对象关闭Q否则容易造成q接处于CLOSE_WAIT状?br /> 3 TCP的KeepLive功能Q可以让操作pȝ替我们自动清理掉CLOSE_WAIT的连接?br /> 但是KeepLive在Windows操作pȝ下默认是7200U,也就?个小时才清理一ơ。往往满不了要求。可以调该数倹{?br /> Windows下的调整Ҏ?br /> HKEY_LOCAL_MACHINE"CurrentControlSet"Services"Tcpip"Parameters下的以下三个参数Q?
KeepAliveInterval,讄其gؓ1000
KeepAliveTime,讄其gؓ300000(单位为毫U,300000代表5分钟)
TcpMaxDataRetransmissions,讄其gؓ5

Close_Wait引发的问?
Close_Wait会占用一个连接,|络可用q接。数量过多,可能会引Ll性能下降Qƈ占用pȝ非换内存?其是在有连接池的情况下(比如HttpRequest)
会耗尽q接池的|络q接敎ͼD无法建立|络q接

--------------------------------------------
TCP状态{U要?br />     TCP协议规定Q对于已l徏立的q接Q网l双方要q行四次握手才能成功断开q接Q如果缺了其中某个步骤Q将会ɘq接处于假死状态,q接本n占用的资源不会被释放。网l服务器E序要同时管理大量连接,所以很有必要保证无用连接完全断开Q否则大量僵ȝq接会浪费许多服务器资源。在众多TCP状态中Q最值得注意的状态有两个QCLOSE_WAIT和TIME_WAIT?nbsp; 

1、LISTENING状?br />   FTP服务启动后首先处于侦听(LISTENINGQ状态?br /> 2、ESTABLISHED状?br />   ESTABLISHED的意思是建立q接。表CZ台机器正在通信?br /> 3、CLOSE_WAIT
    Ҏd关闭q接或者网l异常导致连接中断,q时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来得连接正关?br /> 4、TIME_WAIT
    我方d调用close()断开q接Q收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持l?MSL(即两倍的分段最大生存期)Q以此来保旧的q接状态不会对新连接生媄响。处于TIME_WAIT状态的q接占用的资源不会被内核释放Q所以作为服务器Q在可能的情况下Q尽量不要主动断开q接Q以减少TIME_WAIT状态造成的资源浪贏V?
    目前有一U避免TIME_WAIT资源费的方法,是关闭socket的LINGER选项。但q种做法是TCP协议不推荐用的Q在某些情况下这个操作可能会带来错误?

详细一点的文档Q?br /> http://apps.hi.baidu.com/share/detail/10908121

疯狂 2010-09-06 10:59 发表评论
]]>
可能用堆栈变?/title><link>http://www.tkk7.com/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.tkk7.com/freeman1984/archive/2010/01/29/311223.html</guid><wfw:comment>http://www.tkk7.com/freeman1984/comments/311223.html</wfw:comment><comments>http://www.tkk7.com/freeman1984/archive/2010/01/29/311223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/freeman1984/comments/commentRss/311223.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/freeman1984/services/trackbacks/311223.html</trackback:ping><description><![CDATA[<p>如果您频J存取变量,需要考虑从何处存取这些变量。变量是 <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 /> 变量Q还是堆栈变量,或者是cȝ实例变量Q变量的存储位置对存取它的代码的性能有明昄影响Q例如,误虑下面q段代码Q?</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<val; i++) j += 1; } //存取cȝ实例变量 void instanceAccess(int val) { for (int i=0; i<val; i++) instVar += 1; } //存取cȝ static 变量 void staticAccess(int val) { for (int i=0; i<val; i++) staticVar += 1; } } </pre> </td> </tr> </tbody> </table> <br /> <p>q段代码中的每个Ҏ都执行相同的循环Qƈ反复相同的次数。唯一的不同是每个循环使一个不同类型的变量递增。方? <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 /> 使一个局部堆栈变量递增Q?<code>instanceAccess</code> 使类的一个实例变量递增Q?<code>staticAccess</code> 使类的一?<code>static</code> 变量递增?</p> <p><code>instanceAccess</code> ?<code>staticAccess</code> 的执行时间基本相同。但是, <code>stackAccess</code> 要快两到三倍。存取堆栈变量如此快是因为,JVM 存取堆栈变量比它存取 <code>static</code> 变量或类的实例变量执行的操作。请看一下ؓq三个方法生成的字节码: </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 q将它存储在局部分变量表中索引?2 的位|?(j)? 2 iconst_0 //压入 0? 3 istore_3 //弹出 0 q将它存储在局部变量表中烦引ؓ 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 于 valQ则跌位置 7? 18 return //q回调用Ҏ? Method void instanceAccess(int) 0 iconst_0 //?0 压入堆栈? 1 istore_2 //弹出 0 q将它存储在局部变量表中烦引ؓ 2 的位|?(i)? 2 goto 18 //跌位置 18? 5 aload_0 //压入索引 0 (this)? 6 dup //复制堆栈的值ƈ它压入? 7 getfield #19 <Field int instVar> //弹出 this 对象引用q压?instVar 的倹{? 10 iconst_1 //压入 1? 11 iadd //弹出栈顶的两个|q压入它们的和? 12 putfield #19 <Field int instVar> //弹出栈顶的两个值ƈ和存储?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 于 valQ则跌位置 5? 23 return //q回调用Ҏ? Method void staticAccess(int) 0 iconst_0 //?0 压入堆栈? 1 istore_2 //弹出 0 q将它存储在局部变量表中烦引ؓ 2 的位|?(i)? 2 goto 16 //跌位置 16? 5 getstatic #25 <Field int staticVar> //常数存储池?staticVar 的值压入堆栈? 8 iconst_1 //压入 1? 9 iadd //弹出栈顶的两个|q压入它们的和? 10 putstatic #25 <Field int staticVar> //弹出和的值ƈ它存储?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 于 valQ则跌位置 5? 21 return //q回调用Ҏ? </pre> </td> </tr> </tbody> </table> <br /> <p>查看字节码揭CZ堆栈变量效率更高的原因。JVM 是一U基于堆栈的虚拟机,因此优化了对堆栈数据的存取和处理。所有局部变量都存储在一个局部变量表中,?Java 操作数堆栈中q行处理Qƈ可被高效地存取。存?<code>static</code> 变量和实例变量成本更高,因ؓ JVM 必须使用代h更高的操作码Qƈ从常数存储池中存取它们。(常数存储池保存一个类型所使用的所有类型、字D和Ҏ的符号引用。) </p> <p>通常Q在W一ơ从常数存储池中讉K <code>static</code> 变量或实例变量以后,JVM 动态更改字节码以用效率更高的操作码。尽有q种优化Q堆栈变量的存取仍然更快?</p> <p>考虑到这些事实,可以重新构建前面的代码Q以侉K过存取堆栈变量而不是实例变量或 <code>static</code> 变量使操作更高效。请考虑修改后的代码Q?</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<val; i++) j += 1; instVar = j; } void staticAccess(int val) { int j = staticVar; for (int i=0; i<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> 变量中。这U简单的更改明显提高?<code>instanceAccess</code> ?<code>staticAccess</code> 的性能。这三个Ҏ的执行时间现在基本相同, <code>instanceAccess</code> ?<code>staticAccess</code> 的执行速度只比 <code>stackAccess</code> 的执行速度慢大U?4%?</p> <p>qƈ不表C您应该避免使用 <code>static</code> 变量或实例变量。您应该使用Ҏ的设计有意义的存储机制。例如,如果您在一个@环中存取 <code>static</code> 变量或实例变量,则您可以临时它们存储在一个局部堆栈变量中Q这样就可以明显地提高代码的性能。这提供最高效的字节码指o序列?JVM 执行<br /> 转蝲自ibm</p> <img src ="http://www.tkk7.com/freeman1984/aggbug/311223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/freeman1984/" target="_blank">疯狂</a> 2010-01-29 14:56 <a href="http://www.tkk7.com/freeman1984/archive/2010/01/29/311223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://cdessc.com" target="_blank">AרAV</a>| <a href="http://zc-zk.com" target="_blank">վ߹ۿ</a>| <a href="http://kanzhelu23.com" target="_blank">ѱվڹۿ</a>| <a href="http://clzqb2b.com" target="_blank">Ʒ˹ۿƵ</a>| <a href="http://xiaojiejieav.com" target="_blank">պƷƵ</a>| <a href="http://mmm19.com" target="_blank">þѸƵ</a>| <a href="http://zzyqr.com" target="_blank">Ļ</a>| <a href="http://boyipark.com" target="_blank">67194츾ѹۿ </a>| <a href="http://6atb.com" target="_blank">wwwѸƵ </a>| <a href="http://wwwyy763.com" target="_blank">޳AV߹ۿ</a>| <a href="http://9898vip.com" target="_blank">99ƷƵ</a>| <a href="http://zqsplc.com" target="_blank">ƵѴȫϼ</a>| <a href="http://my94ok.com" target="_blank">ձ2019߹ۿ</a>| <a href="http://dzyong.com" target="_blank">һƷһAVһи</a>| <a href="http://hberay.com" target="_blank">av벻߹ۿ</a>| <a href="http://wwwnewhtbook.com" target="_blank">˾ƷƵ99߹ۿ</a>| <a href="http://www1688mz.com" target="_blank">ۺһ </a>| <a href="http://a8g8.com" target="_blank">þþƷaһվ </a>| <a href="http://044242.com" target="_blank">һվ</a>| <a href="http://77sosoo.com" target="_blank">˾ƷѾþþþ</a>| <a href="http://milbolg.com" target="_blank">þþþþþ99Ʒ</a>| <a href="http://ttooyuyu.com" target="_blank">ˬִ̼߳Ƶ </a>| <a href="http://szzrjk.com" target="_blank">޾ƷŮþþþ</a>| <a href="http://bzzxyp.com" target="_blank">˳ëƬ߲</a>| <a href="http://91ptv.com" target="_blank">ɫ͵͵ۺAV </a>| <a href="http://www50884.com" target="_blank">þþþAVרJN</a>| <a href="http://34pmpm.com" target="_blank">޳avƬۿ</a>| <a href="http://wwwkk5679.com" target="_blank">޾Ʒպ?V</a>| <a href="http://xxzyyj.com" target="_blank">ɫƵɫ¶¶ѹۿ</a>| <a href="http://qqcnm.com" target="_blank">AVһ߹ۿ </a>| <a href="http://ynxxrh.com" target="_blank">߹ۿ</a>| <a href="http://8izh.com" target="_blank">91ѹԲ2021</a>| <a href="http://tccqdy.com" target="_blank">˵Ƶ߹ۿ</a>| <a href="http://sanyoumiaomu.com" target="_blank">պӰ߹ۿ</a>| <a href="http://12345ww.com" target="_blank">ֻ߿avƬ</a>| <a href="http://41xjj.com" target="_blank">ĻӰӾƷ</a>| <a href="http://9akk.com" target="_blank">޾Ʒɫҹרպ</a>| <a href="http://sds54.com" target="_blank">ŷղ߳v</a>| <a href="http://w9366.com" target="_blank">AVӰԺ߹ۿ</a>| <a href="http://czhos.com" target="_blank">һ޾ƷҺ</a>| <a href="http://avqq222.com" target="_blank">ձ岻Ļ </a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>