﻿<?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-月亮的太阳-文章分类-编程</title><link>http://www.blogjava.net/zyb9114/category/5859.html</link><description>小乖的BLOG</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 18:51:52 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 18:51:52 GMT</pubDate><ttl>60</ttl><item><title>[Jakarta Commons Cookbook 笔记] StringUtils类使用[转]</title><link>http://www.blogjava.net/zyb9114/articles/27748.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Thu, 12 Jan 2006 06:12:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/27748.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/27748.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/27748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/27748.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/27748.html</trackback:ping><description><![CDATA[<STRONG>检查字符串是否为空或null或仅仅包含空格<BR></STRONG>&nbsp; String test = "";<BR>&nbsp; String test1=" ";<BR>&nbsp; String test2 = "\n\n\t";<BR>&nbsp; String test3 = null;<BR>&nbsp; System.out.println( "test blank? " + StringUtils.isBlank( test ) ); <BR>&nbsp; System.out.println( "test1 blank? " + StringUtils.isBlank( test1 ) );<BR>&nbsp; System.out.println( "test2 blank? " + StringUtils.isBlank( test2 ) );<BR>&nbsp; System.out.println( "test3 blank? " + StringUtils.isBlank( test3 ) );<BR>&nbsp; 运行结果：<BR>&nbsp; test blank? true<BR>&nbsp; test1 blank? true<BR>&nbsp; test2 blank? true<BR>&nbsp; test3 blank? true<BR>&nbsp; 相对应的还有一个StringUtils.isNotBlank(String str)<BR>&nbsp; StringUtils.isEmpty(String str)则检查字符串是否为空或null（不检查是否仅仅包含空格）<BR>&nbsp; <BR>&nbsp; <STRONG>分解字符串</STRONG><BR>&nbsp; StringUtils.split(null, *, *)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = null<BR>&nbsp; StringUtils.split("", *, *)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = []<BR>&nbsp; StringUtils.split("ab de fg", null, 0)&nbsp;&nbsp; = ["ab", "cd", "ef"]<BR>&nbsp; StringUtils.split("ab&nbsp;&nbsp; de fg", null, 0) = ["ab", "cd", "ef"]<BR>&nbsp; StringUtils.split("ab:cd:ef", ":", 0)&nbsp;&nbsp;&nbsp; = ["ab", "cd", "ef"]<BR>&nbsp; StringUtils.split("ab:cd:ef", ":", 1)&nbsp;&nbsp;&nbsp; = ["ab:cd:ef"]<BR>&nbsp; StringUtils.split("ab:cd:ef", ":", 2)&nbsp;&nbsp;&nbsp; = ["ab", "cd:ef"]<BR>&nbsp; StringUtils.split(String str,String separatorChars,int max) str为null时返回null<BR>&nbsp; separatorChars为null时默认为按空格分解，max为0或负数时分解没有限制，max为1时返回整个字符串，max为分解成的个数（大于实际则无效）<BR>&nbsp; <BR>&nbsp; <STRONG>去除字符串前后指定的字符</STRONG><BR>&nbsp; StringUtils.strip(null, *)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = null<BR>&nbsp; StringUtils.strip("", *)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = ""<BR>&nbsp; StringUtils.strip("abc", null)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "abc"<BR>&nbsp; StringUtils.strip(" abc ", null)&nbsp;&nbsp;&nbsp; = "abc"<BR>&nbsp; StringUtils.strip("&nbsp; abcyx", "xyz") = "&nbsp; abc"<BR>&nbsp; StringUtils.strip(String str,String stripChars) str为null时返回null,stripChars为null时默认为空格
<P>&nbsp; <STRONG>创建醒目的Header（调试时用）</STRONG><BR>&nbsp; public String createHeader( String title ) {<BR>&nbsp;&nbsp;&nbsp; int width = 30;<BR>&nbsp;&nbsp;&nbsp; String stars = StringUtils.repeat( "*", width);<BR>&nbsp;&nbsp;&nbsp; String centered = StringUtils.center( title, width, "*" );<BR>&nbsp;&nbsp;&nbsp; String heading = StringUtils.join(new Object[]{stars, centered, stars}, "\n");<BR>&nbsp;&nbsp;&nbsp; return heading;<BR>&nbsp; }<BR>&nbsp; 调用createHeader("TEST")的输出结果:<BR>&nbsp; ******************************<BR>&nbsp; ************ TEST ************<BR>&nbsp; ******************************</P>
<P>&nbsp; <STRONG>字符的全部反转及以单个词为单位的反转<BR></STRONG>&nbsp; String original = "In time, I grew tired of his babbling nonsense.";<BR>&nbsp; StringUtils.reverse( original )&nbsp;&nbsp; = ".esnesnon gnilbbab sih fo derit werg I ,emit nI"<BR>&nbsp; 以单个词为单位的反转<BR>&nbsp; public Sentence reverseSentence(String sentence) {<BR>&nbsp;&nbsp;&nbsp; String reversed = StringUtils.chomp( sentence, "." );<BR>&nbsp;&nbsp;&nbsp; reversed = StringUtils.reverseDelimited( reversed, ' ' );<BR>&nbsp;&nbsp;&nbsp; reversed = reversed + ".";<BR>&nbsp;&nbsp;&nbsp; return reversed;<BR>&nbsp; }<BR>&nbsp; String sentence = "I am Susan."<BR>&nbsp; reverseSentence( sentence ) )&nbsp;&nbsp; = "Susan am I."</P>
<P>&nbsp; <STRONG>检查字符串是否仅仅包含数字、字母或数字和字母的混合<BR></STRONG>&nbsp; String test1 = "ORANGE";<BR>&nbsp; String test2 = "ICE9";<BR>&nbsp; String test3 = "ICE CREAM";<BR>&nbsp; String test4 = "820B Judson Avenue";<BR>&nbsp; String test5 = "1976";<BR>&nbsp; 结果：<BR>&nbsp; boolean t1val = StringUtils.isAlpha( test1 ); // returns true<BR>&nbsp; boolean t2val = StringUtils.isAlphanumeric( test2 ); // returns true<BR>&nbsp; boolean t3val = StringUtils.isAlphaSpace( test3 ); // returns true<BR>&nbsp; boolean t4val = StringUtils.isAlphanumericSpace( test4 ); // returns true<BR>&nbsp; boolean t5val = StringUtils.isNumeric( test5 ); // returns true</P><img src ="http://www.blogjava.net/zyb9114/aggbug/27748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2006-01-12 14:12 <a href="http://www.blogjava.net/zyb9114/articles/27748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Weblogic服务器性能调优[转]</title><link>http://www.blogjava.net/zyb9114/articles/26113.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Fri, 30 Dec 2005 12:58:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/26113.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/26113.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/26113.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/26113.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/26113.html</trackback:ping><description><![CDATA[<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123696092><SPAN lang=EN-US><FONT face=Arial>Weblogic</FONT></SPAN></A>服务器性能调优</H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">注：在下面做的介绍都是以</SPAN><SPAN lang=EN-US><FONT face=Arial>Weblogic8.1</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">为例的，其它版本的</SPAN><SPAN lang=EN-US><FONT face=Arial>Weblogic</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">可能会有些许不同。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>1) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>JAVA</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">参数；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>a) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编辑</SPAN><SPAN lang=EN-US><FONT face=Arial>Weblogic Server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">启动脚本文件；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l1 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><FONT face=Arial>BEA_HOME\user_projects\domains\domain-name\startWebLogic.cmd(startWebLogic.sh on Unix)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l1 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><FONT face=Arial>BEA_HOME\user_projects\domains\domain-name\startManagedWebLogic.cmd(startManagedWebLogic.sh on Unix)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>b) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编辑</SPAN><SPAN lang=EN-US><FONT face=Arial>set JAVA_OPTIONS</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">命令，如：</SPAN><SPAN lang=EN-US><FONT face=Arial>set JAVA_OPTIONS=-Xms<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chmetcnv w:st="on" UnitName="m" SourceValue="256" HasSpace="False" Negative="False" NumberType="1" TCSC="0">256m</st1:chmetcnv> –Xmx<st1:chmetcnv w:st="on" UnitName="m" SourceValue="256" HasSpace="False" Negative="False" NumberType="1" TCSC="0">256m</st1:chmetcnv></FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>c) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">保存，重启即可。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">注：在</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>WebLogic</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">中，为了获得更好的性能，</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>BEA</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">公司推荐最小</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>Java</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆等于最大</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>Java</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆。</SPAN><SPAN lang=EN-US style="COLOR: blue"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>2) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">开发模式</SPAN><SPAN lang=EN-US><FONT face=Arial> vs. </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">产品模式；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">开发模式和产品模式的一些参数的默认值不同，可能会对性能造成影响，下面是对性能有影响的参数列表：</SPAN></P>
<TABLE class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 194.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=259>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">参数</SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 134.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=179>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">开发模式默认值</SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 164.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=219>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">产品模式默认值</SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 194.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=259>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial>Execute Queue: Thread Count</FONT></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 134.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=179>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial>15 threads</FONT></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 164.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=219>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial>25 threads</FONT></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 194.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=259>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial>JDBC Connection Pool: MaxCapacity</FONT></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 134.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=179>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial>15 connnections</FONT></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 164.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=219>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial>25 connections</FONT></SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置</SPAN><FONT face=Arial> <SPAN lang=EN-US>&gt; </SPAN></FONT><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">常规选择产品模式。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>3) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽量开启本地</SPAN><SPAN lang=EN-US><FONT face=Arial>I/O</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">服务器</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>myserver</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调整选择启用本地</SPAN><SPAN lang=EN-US><FONT face=Arial>I/O</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">注：此值也可通过手动的修改</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>config.xml</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置文件。</SPAN><SPAN lang=EN-US style="COLOR: blue"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>4) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调优执行队列线程；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>a) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">修改默认执行线程数</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在这里，执行队列的线程数表示执行队列能够同时执行的操作的数量。但此值不是设的越大越好，应该恰到好处的去设置它，太小了，执行队列中将会积累很多待处理的任务，太大了，则会消耗大量的系统资源从而影响整体的性能。在产品模式下默认为</SPAN><SPAN lang=EN-US><FONT face=Arial>25</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">个执行线程。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">为了设置理想的执行队列的线程数，我们可以启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">服务器</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>myserver</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">监视</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">性能中监控最大负载时执行队列的吞吐量和队列中的等待请求数，据此确定理想的数值。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">理想的默认执行线程数是由多方面的因素决定的，比如机器</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">性能、总体体系架构、</SPAN><SPAN lang=EN-US><FONT face=Arial>I/O</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、操作系统的进程调度机制、</SPAN><SPAN lang=EN-US><FONT face=Arial>JVM</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的线程调度机制。随着</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">个数的增加，</SPAN><SPAN lang=EN-US><FONT face=Arial>WebLogic</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">可以近乎线性地提高线程数。线程数越多，花费在线程切换的时间也就越多；线程数越小，</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">可能无法得到充分的利用。为获取一个理想的线程数，需要经过反复的测试。在测试中，可以以</SPAN><SPAN lang=EN-US><FONT face=Arial>25*CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">个数为基准进行调整。当空闲线程较少，</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">利用率较低时，可以适当增加线程数的大小（每五个递增）。对于</SPAN><SPAN lang=EN-US><FONT face=Arial>PC Server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>Windows 2000</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，则最好每个</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">小于</SPAN><SPAN lang=EN-US><FONT face=Arial>50</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">个线程，以</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">利用率为</SPAN><SPAN lang=EN-US><FONT face=Arial>90%</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">左右为最佳。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">服务器</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>myserver</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; Execute Queue &gt; weblogic.kernel.Defalt &gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置中修改线程计数。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>b) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设定执行队列的溢出条件；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Weblogic Server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">提供给默认的执行队列或用户自定义的执行队列自定义溢出条件的功能，当满足此溢出条件时，服务器改变其状态为“警告”状态，并且额外的再分配一些线程去处理在队列中的请求，而达到降低队列长度的目的。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">服务器</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>myserver</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; Execute Queue &gt; weblogic.kernel.Defalt &gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置下面几项：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l3 level2 lfo3; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">队列长度：此值表示执行队列中可容纳的最大请求数，默认值是</SPAN><SPAN lang=EN-US><FONT face=Arial>65536</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，最后不要手动改变此值。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l3 level2 lfo3; tab-stops: list 42.0pt"><SPAN class=dialog-label><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">队列长度阈值百分比：此值表示溢出条件，</SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在此服务器指出队列溢出之前可以达到的队列长度大小的百分比。</SPAN></SPAN><SPAN class=dialog-label><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l3 level2 lfo3; tab-stops: list 42.0pt"><SPAN class=dialog-label><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">线程数增加：当检测到溢出条件时，将增加到执行队列中的线程数量。如果</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和内存不是足够的高，尽量不要改变默认值“</SPAN><SPAN lang=EN-US><FONT face=Arial>0</FONT></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">”。因为</SPAN><SPAN lang=EN-US><FONT face=Arial>Weblogic</FONT></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">一旦增加后不会自动缩减，虽然最终可能确实起到了降低请求的作用，但在将来的运行中将影响程序的性能。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l3 level2 lfo3; tab-stops: list 42.0pt"><SPAN class=dialog-label><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">最大线程数：为了防止创建过多的线程数量，可以通过设定最大的线程数进行控制。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在实际的应用场景中，应根据具体情况适当的调整以上参数。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>c) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设定执行队列监测行为</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US><FONT face=Arial>Weblogic Server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">能够自动监测到当一个执行线程变为“阻塞”。变为“阻塞”状态的执行线程将无法完成当前的工作，也无法再执行新请求。如果执行队列中的所有执行线程都变为“阻塞”状态，</SPAN><SPAN lang=EN-US><FONT face=Arial>Weblogic server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">可能改变状态为“警告”或“严重”状态。如果</SPAN><SPAN lang=EN-US><FONT face=Arial>Weblogic server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">变为“严重”状态，可以通过</SPAN><SPAN lang=EN-US><FONT face=Arial>Node Manager</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">来自动关闭此服务器并重新启动它。具体请参考：</SPAN><SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Verdana; mso-ansi-language: EN"><A href="http://e-docs.bea.com/wls/docs81/adminguide/nodemgr.html#NodeManagerCapabilities">Node Manager Capabilities</A></SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 黑体; mso-ascii-font-family: Verdana; mso-ansi-language: EN; mso-hansi-font-family: Verdana">文档。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">服务器</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>myserver</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调整下可配置下面几项：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo2; tab-stops: list 42.0pt"><SPAN class=dialog-help><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">阻塞线程最长时间：</SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在此服务器将线程诊断为阻塞线程之前，线程必须连续工作的时间长度</SPAN><SPAN lang=EN-US><FONT face=Arial>(</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">秒</SPAN><SPAN lang=EN-US><FONT face=Arial>)</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。默认情况下，</SPAN><SPAN lang=EN-US><FONT face=Arial>WebLogic Server </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">认为线程在连续工作</SPAN><SPAN lang=EN-US><FONT face=Arial> 600 </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">秒后成为阻塞线程。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo2; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">阻塞线程计时器间隔：</SPAN></SPAN><SPAN class=dialog-help><SPAN lang=EN-US><FONT face=Arial>WebLogic Server </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">定期扫描线程以查看它们是否已经连续工作了</SPAN><SPAN lang=EN-US><FONT face=Arial> "</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">阻塞线程最长时间</SPAN><SPAN lang=EN-US><FONT face=Arial>" </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">字段中指定的时间长度的间隔时间</SPAN><SPAN lang=EN-US><FONT face=Arial>(</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">秒</SPAN><SPAN lang=EN-US><FONT face=Arial>)</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。默认情况下，</SPAN><SPAN lang=EN-US><FONT face=Arial>WebLogic Server </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">将此时间间隔设置为</SPAN><SPAN lang=EN-US><FONT face=Arial> 600 </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">秒。</SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN lang=EN-US><FONT face=Arial>5) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调优</SPAN><SPAN lang=EN-US><FONT face=Arial>TCP</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">连接缓存数；</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN lang=EN-US><FONT face=Arial>WebLogic Server</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">用</SPAN><SPAN lang=EN-US><FONT face=Arial>Accept Backlog</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">参数规定服务器向操作系统请求的队列大小，默认值为</SPAN><SPAN lang=EN-US><FONT face=Arial>50</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。当系统重载负荷时</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">这个值可能过小</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">日志中报</SPAN><SPAN lang=EN-US><FONT face=Arial>Connection Refused,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">导致有效连接请求遭到拒绝</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">此时可以提高</SPAN><SPAN lang=EN-US><FONT face=Arial>Accept Backlog 25%</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">直到连接拒绝错误消失。对于</SPAN><SPAN lang=EN-US><FONT face=Arial>Portal</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类型的应用</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">默认值往往是不够的。</SPAN><SPAN lang=EN-US><FONT face=Arial>Login Timeout</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>SSL Login Timeout</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">参数表示普通连接和</SPAN><SPAN lang=EN-US><FONT face=Arial>SSL</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">连接的超时时间</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">如果客户连接被服务器中断或者</SPAN><SPAN lang=EN-US><FONT face=Arial>SSL</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">容量大</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">可以尝试增加该值。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">服务器</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>myserver</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调整下可配置“接受预备连接”。</SPAN><SPAN class=dialog-help><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN class=dialog-help><SPAN lang=EN-US><FONT face=Arial>6) </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">改变</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编译器；</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">标准的</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编译器是</SPAN><SPAN lang=EN-US><FONT face=Arial>javac</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，但编译</SPAN><SPAN lang=EN-US><FONT face=Arial>JSP servlets</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">速度太慢，为了提高编译速度，可以使用</SPAN><SPAN lang=EN-US><FONT face=Arial>sj</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">或</SPAN><SPAN lang=EN-US><FONT face=Arial>jikes</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编译器取代</SPAN><SPAN lang=EN-US><FONT face=Arial>javac</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编译器。下面说说更改</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编译器：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过启动管理控制台，在域（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>mydomain</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">服务器</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; server</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例（如：</SPAN><SPAN lang=EN-US><FONT face=Arial>myserver</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）</SPAN><SPAN lang=EN-US><FONT face=Arial>&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">配置</SPAN><SPAN lang=EN-US><FONT face=Arial> &gt; </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">常规下改变</SPAN><SPAN class=dialog-label><SPAN lang=EN-US><FONT face=Arial>Java </FONT></SPAN></SPAN><SPAN class=dialog-label><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编译器</SPAN><FONT face=Arial>，默认为</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial>javac</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。输入完整路径，如：</SPAN><SPAN lang=EN-US><FONT face=Arial>c:\visualcafe31\bin\sj.exe</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。然后打开高级选项，在<SPAN class=dialog-label>预规划到类路径</SPAN>填写</SPAN><FONT face=Arial><SPAN class=dialog-help>编译</SPAN></SPAN><SPAN class=dialog-help><SPAN lang=EN-US> Java </SPAN></SPAN></FONT><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">代码时为</SPAN><SPAN lang=EN-US><FONT face=Arial> Java </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编译器类路径预规划的选项，如：</SPAN></SPAN><A name=1104268></A><SPAN class=dialog-help><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">BEA_HOME\jdk141_02\jre\lib\rt.jar</SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN lang=EN style="mso-ansi-language: EN"><FONT face=Arial>7) </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-ansi-language: EN">使用</SPAN></SPAN><SPAN class=dialog-help><SPAN lang=EN style="mso-ansi-language: EN"><FONT face=Arial>Webogic Server</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-ansi-language: EN">集群提高性能；</SPAN></SPAN><SPAN class=dialog-help><SPAN lang=EN style="mso-ansi-language: EN"><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">具体关于如何配置</SPAN><SPAN lang=EN-US><FONT face=Arial>Weblogic</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">集群，我就不细说了。详情可参考：</SPAN></SPAN><SPAN lang=EN style="mso-ansi-language: EN"><A href="http://e-docs.bea.com/wls/docs81/cluster/overview.html"><FONT face=Arial>Introduction to WebLogic Server Clustering</FONT></A></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-ansi-language: EN">。</SPAN><SPAN lang=EN style="mso-ansi-language: EN"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN style="mso-ansi-language: EN"><FONT face=Arial>8) Weblogic EJB</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-ansi-language: EN">调优</SPAN><SPAN lang=EN style="mso-ansi-language: EN"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">由于</SPAN><SPAN lang=EN-US><FONT face=Arial>EJB2.0</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">已经很少项目在用了，</SPAN><SPAN lang=EN-US><FONT face=Arial>EJB3.0</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">再成熟一点，我再补充这一部分吧！</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN lang=EN-US><FONT face=Arial>9) JDBC</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">应用调优</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN lang=EN-US><FONT face=Arial>JDBC Connection Pool</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的调优受制于</SPAN><SPAN lang=EN-US><FONT face=Arial>WebLogic Server</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">线程数的设置和数据库进程数</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">游标的大小。通常我们在一个线程中使用一个连接</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">所以连接数并不是越多越好</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">为避免两边的资源消耗，建议设置连接池的最大值等于或者略小于线程数。同时为了减少新建连接的开销</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">将最小值和最大值设为一致。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">增加</SPAN><SPAN lang=EN-US><FONT face=Arial>Statement Cache Size</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对于大量使用</SPAN><SPAN lang=EN-US><FONT face=Arial>PreparedStatement</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对象的应用程序很有帮助</SPAN><SPAN lang=EN-US><FONT face=Arial>,WebLogic</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">能够为每一个连接缓存这些对象</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">此值默认为</SPAN><SPAN lang=EN-US><FONT face=Arial>10</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。在保证数据库游标大小足够的前提下</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">可以根据需要提高</SPAN><SPAN lang=EN-US><FONT face=Arial>Statement Cache Size</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。比如当你设置连接数为</SPAN><SPAN lang=EN-US><FONT face=Arial>25,Cache Size</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">为</SPAN><SPAN lang=EN-US><FONT face=Arial>10</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">时</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">数据库可能需要打开</SPAN><SPAN lang=EN-US><FONT face=Arial>25*10=250</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">个游标。不幸的是</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">当遇到与</SPAN><SPAN lang=EN-US><FONT face=Arial>PreparedStatement Cache</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">有关的应用程序错误时</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">你需要将</SPAN><SPAN lang=EN-US><FONT face=Arial>Cache Size</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置为</SPAN><SPAN lang=EN-US><FONT face=Arial>0</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽管</SPAN><SPAN lang=EN-US><FONT face=Arial>JDBC Connection Pool</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">提供了很多高级参数</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在开发模式下比较有用</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">但大部分在生产环境下不需调整。这里建议最好不要设置测试表</SPAN><SPAN lang=EN-US><FONT face=Arial>, </FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">同时</SPAN><SPAN lang=EN-US><FONT face=Arial>Test Reserved Connections</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>Test Released Connections</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">也无需勾上。</SPAN><FONT face=Arial> </FONT></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">当然如果你的数据库不稳定</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">时断时续</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">你就可能需要上述的参数打开。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">最后提一下驱动程序类型的选择</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">以</SPAN><SPAN lang=EN-US><FONT face=Arial>Oracle</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">为例</SPAN><SPAN lang=EN-US><FONT face=Arial>,Oracle</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">提供</SPAN><SPAN lang=EN-US><FONT face=Arial>thin</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动和</SPAN><SPAN lang=EN-US><FONT face=Arial>oci</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">从性能上来讲</SPAN><SPAN lang=EN-US><FONT face=Arial>,oci</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动强于</SPAN><SPAN lang=EN-US><FONT face=Arial>thin</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">特别是大数据量的操作。但在简单的数据库操作中</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">性能相差不大</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">随着</SPAN><SPAN lang=EN-US><FONT face=Arial>thin</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动的不断改进</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">这一弱势将得到弥补。而</SPAN><SPAN lang=EN-US><FONT face=Arial>thin</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动的移植性明显强于</SPAN><SPAN lang=EN-US><FONT face=Arial>oci</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动。所以在通常情况下建议使用</SPAN><SPAN lang=EN-US><FONT face=Arial>thin</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动。而最新驱动器由于</SPAN><SPAN lang=EN-US><FONT face=Arial>WebLogic server/bin</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">目录下的类包可能不是最新的</SPAN><SPAN lang=EN-US><FONT face=Arial>,</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">请以</SPAN><SPAN lang=EN-US><FONT face=Arial>Oracle</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">网站为准</SPAN><SPAN lang=EN-US><FONT face=Arial>: </FONT><A href="http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc9201.html"><FONT face=Arial>http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc9201.html</FONT></A></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN class=dialog-help><SPAN lang=EN-US><FONT face=Arial>10) JSP</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调优</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level1 lfo4; tab-stops: list 42.0pt"><SPAN class=dialog-help><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>jsp-param pageCheckSeconds=-1</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level1 lfo4; tab-stops: list 42.0pt"><SPAN class=dialog-help><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>serlet-reload-check=-1</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">或</SPAN><SPAN lang=EN-US><FONT face=Arial>ServletReloadCheckSecs=-1</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level1 lfo4; tab-stops: list 42.0pt"><SPAN class=dialog-help><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>jsp-param precompile=true</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，关闭</SPAN><SPAN lang=EN-US><FONT face=Arial>JSP</FONT></SPAN></SPAN><SPAN class=dialog-help><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">预编译选项。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P><img src ="http://www.blogjava.net/zyb9114/aggbug/26113.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-30 20:58 <a href="http://www.blogjava.net/zyb9114/articles/26113.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>挖掘Jakarta Commons中隐藏的宝贝(三)[转载]</title><link>http://www.blogjava.net/zyb9114/articles/25552.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Tue, 27 Dec 2005 03:59:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/25552.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/25552.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/25552.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/25552.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/25552.html</trackback:ping><description><![CDATA[<STRONG>3. 使用XPath语法来查询对象和集合<BR></STRONG><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;Commons JXPath是一种让人很吃惊地（非标准的）对XML标准的使用。XPath一段时间以来一直是作为在一个XSL样式表中选择结点或结点集的一种方法。如果你用过XML，你会很熟悉用这样的语法/foo/bar来从foo文档元素中选择bar子元素。<BR><BR>&nbsp;&nbsp;&nbsp; Jakarta Commons JXPath增加了一种有趣的手法：你可以用JXPath来从bean和集合中选择对象，其中如servlet上下文和DOM文档对象。考虑一个包含了Person对象的列表。每一个Person对象有一个属性的类型为Job，每一个Job对象有一个salary(薪水)属性，类型为int。Person对象也有一个coountry属性，它是两个字符的国家代码。使用JXPath，你可以很容易地选出所有国家为美国，薪水超过一百万美元的Person对象。下面是设置一个由JXPath过滤地bean的List的代码:<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>// Person的构造器设置姓和国家代码<BR>Person person1 = new Person( "Tim", "US" );<BR>Person person2 = new Person( "John", "US" );<BR>Person person3 = new Person( "Al",&nbsp;&nbsp;"US" );<BR>Person person4 = new Person( "Tony", "GB" );<BR><BR>// Job的构造器设工作名称和薪水<BR>person1.setJob( new Job( "Developer", 40000 ) );<BR>person2.setJob( new Job( "Senator", 150000 ) );<BR>person3.setJob( new Job( "Comedian", 3400302 ) );<BR>person4.setJob( new Job( "Minister", 2000000 ) );<BR><BR>Person[] personArr = <BR>&nbsp;&nbsp;new Person[] { person1, person2, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; person3, person4 };<BR><BR>List people = Arrays.asList( personArr );</FONT></PRE><BR><BR><FONT size=2>people List包含了四个bean: Tim, John, Al, 和George。Tim是一个挣4万美元的开发者，John是一个挣15万美元的参议员，Al是一个挣340万美元的喜剧演员，Tony是一个挣200万欧元的部长。我们的任务很简单：遍历这个List,打印出每一个挣钱超过100百万美元的美国公民的名字。记住people是一个由Person对象构成的ArrayList,让我们先看一下没有利用JXPath便利的解决方案：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>Iterator peopleIter = people.getIterator();<BR>while( peopleIter.hasNext() ) {<BR>&nbsp;&nbsp;Person person = (Person) peopleIter.next();<BR><BR>&nbsp;&nbsp;if( person.getCountry() != null &amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person.getCountry().equals( "US" ) &amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person.getJob() != null &amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person.getJob().getSalary() &gt; 1000000 ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print( person.getFirstName() + " "<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; person.getLastName() );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>}</FONT></PRE><BR><BR><FONT size=2>上面的例子是繁重的，并有些容易犯错。为了发现合适的Person对象，你必须首先遍历每一个Person对象并且检查conuntry的属性。如果country属性不为空并且符合要求，那么你就要检查job属性并看一下它是否不为空并且salary属性的值大于100万。上面的例子的代码行数可以被Java 1.5的语法大大减少，但是，哪怕是Java 1.5，你仍旧需要在两层上作两次比较。<BR><BR>如果你想对内存中的一组Person对象也做一些这样的查询呢？如果你的应用想显示所有在英格兰的名叫Tony的人呢？喔，如果你打印出每一个薪水少于2万的工作的名称呢？<BR><BR>如果你将这些对象存储到关系数据库中，你可以用一个SQL查询来解决问题，但你正在处理的是内存中的对象，你可以不必那么奢侈。虽然XPath主要是用在XML上面，但你可以用它来写一个针对对象集合的“查询”，将对象作为元素和，把bean属性作为子元素。是的，这是一种对XPath奇怪的应用，但请先看一下下面的例子如何在people上，一个由Person对象构成的ArrayList，实现这三种查询：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.jxpath.JXPathContext;<BR><BR>public List queryCollection(String xpath,<BR>&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;Collection col) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;List results = new ArrayList();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;JXPathContext context = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JXPathContext.newContext( col );<BR> <BR>&nbsp;&nbsp;&nbsp;&nbsp;Iterator matching = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.iterate( xpath );<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;while( matching.hasNext() ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;results.add( matching.getNext() );<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return results;<BR>}<BR><BR>String query1 =<BR>&nbsp;&nbsp; ".[@country = 'US']/job[@salary &gt; 1000000]/..";&nbsp;&nbsp;<BR>String query2 =<BR>&nbsp;&nbsp; ".[@country = 'GB' and @name = 'Tony']";&nbsp;&nbsp;<BR>String query3 = <BR>&nbsp;&nbsp; "./job/name";<BR><BR>List richUsPeople = <BR>&nbsp;&nbsp;&nbsp;&nbsp;queryCollection( query1, people );<BR>List britishTony = <BR>&nbsp;&nbsp;&nbsp;&nbsp;queryCollection( query2, people );<BR>List jobNames = <BR>&nbsp;&nbsp;&nbsp;&nbsp;queryCollection( query3, people );</FONT></PRE>
<P><BR><BR><FONT size=2>queryCollection()方法使用了一个XPath表达式，将它应用到一个集合上。XPath表达式被JXPathContext求值， JXPathContext由JXPathContext.newContext()调用创建，并将它传入要执行查询的集合中。凋用context.iterate()来在集合中的每一个元素上应用XPath表达式，返回包含所有符合条件的“节点”（这里是“对象”）的Iterator。上例中执行的第一个查询，query1,执行了和不使用JXPath的例子相同的查询。query2选择所有国家为GB并且名字属性为Tony的Person对象，query3返回了一个String对象的List,包含了所有Job对象的name属性。<BR><BR>当我第一次看到Commons JXPath, 它是一个坏思想的想法触动了我。为什么要把XPath表达式应用到对象上?有点感觉不对。把XPath作为一个bean的集合的查询语言的这种意想不到的用法，在过去几年中已经好多次给我带来了便利。如果你发现你在list中循环来查找符合条件的元素，请考虑一下JXPath。更多的信息，请参考Jakarta Commons Cookbook的第12章，“查找和过滤”，它讨论了Commons JXPath和与Commons Digester配对的Jakarta Lucene。<BR><BR><B><SPAN style="FONT-SIZE: 16px">还有更多</SPAN></B><BR>对Jakarta Commons纵深地探索仍然在调试中。在这一系列的下面几部分中，我会介绍一些相关的工具和功能。在Commons Collections中设置操作，在collection中使用Predicate对象，使用Commons Configuration来配置一个应用和使用Commons Betwixt来读写XML。能从Jakarta Commons得到的东西还有很多，不能在几千字中表达，所以我建议你看一下Jakarta Commons Cookbook。许多功能可能会，一眼看上去，有点普通，但Jakarta Commons的能量就蕴藏在这些工具的相互组合和与你的系统的集成当中。<BR><BR>Timothy M. O'Brien是一个专业的独立的开发者，在Chicago地区工作和生活。<BR><BR><B>资源</B><BR>·onjava.com:</FONT><A href="http://www.onjava.com/" target=_new><FONT size=2>onjava.com</FONT></A><BR><FONT size=2>·Matrix-Java开发者社区:</FONT><A href="http://www.matrix.org.cn/" target=_new><FONT size=2>http://www.matrix.org.cn/</FONT></A><BR><FONT size=2>·APACHE:</FONT><A href="http://www.apache.org/" target=_new><FONT size=2>APACHE.org</FONT></A><BR></P>
<P>Tracker:http://www.blogjava.net/flyingis/archive/2005/11/09/18959.html</P><img src ="http://www.blogjava.net/zyb9114/aggbug/25552.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-27 11:59 <a href="http://www.blogjava.net/zyb9114/articles/25552.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>挖掘Jakarta Commons中隐藏的宝贝(二)[转载] </title><link>http://www.blogjava.net/zyb9114/articles/25551.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Tue, 27 Dec 2005 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/25551.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/25551.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/25551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/25551.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/25551.html</trackback:ping><description><![CDATA[<STRONG>2．Commons Collections中的算子<BR></STRONG><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;算子成为Commons Collections 3.1中的有趣的部分有两个原因：它们没有得到应得的重视并且它们有改变你编程的方式的潜力。算子只是一个奇特的名字，它代表了一个包装了函数的对象—一个“函数对象”。当然，它们不是一回事。如果你曾经使用过C和C++的方法指针，你就会理解算子的威力。<BR>一个算子是一个对象—一个Predicate,一个Closure, 一个Transformer。<BR><BR>Predicates求对象的值并返回一个boolean，Transformer求对象的值并返回新对象，Closure接受对象并执行代码。算子可以被组合成组合算子来模仿循环，逻辑表达式，和控制结构，并且算子也可以被用来过滤和操作集合中的元素。在这么短的篇幅中解释清楚算子是不可能的，所以跳过介绍，我将会通过使用和不使用算子来解决同一问题（解释算子）。在这个例子中，从一个ArrayList中而来的Student对象会被排序到两个List中，如果他们符合某种标准的话。<BR><BR>成绩为A的学生会被加到honorRollStudents(光荣榜)中，得D和F的学生被加到problemStudents (问题学生)list中。学生分开以后，系统将会遍历每个list，给加入到光荣榜中学生一个奖励，并安排与问题学生的家长谈话的时间表。下面的代码不使用算子实现了这个过程：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>List allStudents = getAllStudents();<BR><BR>// 创建两个ArrayList来存放荣誉学生和问题学生<BR>List honorRollStudents = new ArrayList();<BR>List problemStudents = new ArrayList();<BR><BR>// 遍历所有学生，将荣誉学生放入一个List,问题学生放入另一个<BR>Iterator allStudentsIter = allStudents.iterator();<BR>while( allStudentsIter.hasNext() ) {<BR>&nbsp;&nbsp;Student s = (Student) allStudentsIter.next();<BR><BR>&nbsp;&nbsp;if( s.getGrade().equals( "A" ) ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;honorRollStudents.add( s );<BR>&nbsp;&nbsp;} else if( s.getGrade().equals( "B" ) &amp;&amp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getAttendance() == PERFECT) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;honorRollStudents.add( s );<BR>&nbsp;&nbsp;} else if( s.getGrade().equals( "D" ) || <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getGrade().equals( "F" ) ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;problemStudents.add( s );<BR>&nbsp;&nbsp;} else if( s.getStatus() == SUSPENDED ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;problemStudents.add( s );<BR>&nbsp;&nbsp;}<BR>}<BR><BR>// 对于的有荣誉学生，增加一个奖励并存储到数据库中<BR>Iterator honorRollIter = <BR>&nbsp;&nbsp;&nbsp;&nbsp;honorRollStudents.iterator();<BR>while( honorRollIter.hasNext() ) {<BR>&nbsp;&nbsp;Student s = (Student) honorRollIter.next();<BR>&nbsp;&nbsp; <BR> // 给学生记录增加一个奖励<BR>&nbsp;&nbsp;s.addAward( "honor roll", 2005 );<BR>&nbsp;&nbsp;Database.saveStudent( s );<BR>}<BR><BR>// 对所有问题学生，增加一个注释并存储到数据库中<BR>Iterator problemIter = problemStudents.iterator();<BR>while( problemIter.hasNext() ) {<BR>&nbsp;&nbsp;Student s = (Student) problemIter.next();<BR><BR>&nbsp;&nbsp;// 将学生标记为需特殊注意<BR>&nbsp;&nbsp;s.addNote( "talk to student", 2005 );<BR>&nbsp;&nbsp;s.addNote( "meeting with parents", 2005 );<BR>&nbsp;&nbsp;Database.saveStudent( s );<BR>}</FONT></PRE><BR><BR><FONT size=2>上述例子是非常过程化的;要想知道Student对象发生了什么事必须遍历每一行代码。例子的第一部分是基于成绩和考勤对Student对象进行逻辑判断。<BR><BR>第二部分对Student对象进行操作并存储到数据库中。像上述这个有着50行代码程序也是大多程序所开始的—可管理的过程化的复杂性。但是当需求变化时，问题出现了。一旦判断逻辑改变，你就需要在第一部分中增加更多的逻辑表达式。<BR><BR>举例来说，如果一个有着成绩B和良好出勤记录，但有五次以上的留堂记录的学生被判定为问题学生，那么你的逻辑表达式将会如何处理?或者对于第二部分中，只有在上一年度不是问题学生的学生才能进入光荣榜的话，如何处理？当例外和需求开始改变进而影响到过程代码时，可管理的复杂性就会变成不可维护的面条式的代码。<BR><BR>从上面的例子中回来，考虑一下那段代码到底在做什么。它在一个List遍历每一个对象，检查标准，如果适用该标准，对此对象进行某些操作。上述例子可以进行改进的关键一处在于从代码中将标准与动作解藕开来。下面的两处代码引用以一种非常不同的方法解决了上述的问题。首先，荣誉榜和问题学生的标准被两个Predicate对象模型化了，并且加之于荣誉学生和问题学生上的动作也被两个Closure对象模型化了。这四个对象如下定义： <BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.collections.Closure;<BR>import org.apache.commons.collections.Predicate;<BR><BR>// 匿名的Predicate决定一个学生是否加入荣誉榜<BR>Predicate isHonorRoll = new Predicate() {<BR>&nbsp;&nbsp;public boolean evaluate(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;return( ( s.getGrade().equals( "A" ) ) ||<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;( s.getGrade().equals( "B" ) &amp;&amp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.getAttendance() == PERFECT ) );<BR>&nbsp;&nbsp;}<BR>};<BR><BR>//匿名的Predicate决定一个学生是否是问题学生<BR>Predicate isProblem = new Predicate() {<BR>&nbsp;&nbsp;public boolean evaluate(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;return ( ( s.getGrade().equals( "D" ) || <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getGrade().equals( "F" ) ) ||<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getStatus() == SUSPENDED );<BR>&nbsp;&nbsp;}<BR>};<BR><BR>//匿名的Closure将一个学生加入荣誉榜<BR>Closure addToHonorRoll = new Closure() {<BR>&nbsp;&nbsp;public void execute(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>// 对学生增加一个荣誉记录<BR>&nbsp;&nbsp;&nbsp;&nbsp;s.addAward( "honor roll", 2005 );<BR>&nbsp;&nbsp;&nbsp;&nbsp;Database.saveStudent( s );<BR>&nbsp;&nbsp;}<BR>};<BR><BR>// 匿名的Closure将学生标记为需特殊注意<BR>Closure flagForAttention = new Closure() {<BR>&nbsp;&nbsp;public void execute(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>// 标记学生为需特殊注意<BR>&nbsp;&nbsp;&nbsp;&nbsp;s.addNote( "talk to student", 2005 );<BR>&nbsp;&nbsp;&nbsp;&nbsp;s.addNote( "meeting with parents", 2005 );<BR>&nbsp;&nbsp;&nbsp;&nbsp;Database.saveStudent( s );<BR>&nbsp;&nbsp;}<BR>};</FONT></PRE><BR><BR><FONT size=2>这四个匿名的Predicate和Closure是从作为一个整体互相分离的。flagForAttention(标记为注意)并不知道什么是确定一个问题学生的标准 。现在需要的是将正确的Predicate和正确的Closure结合起来的方法，这将在下面的例子中展示：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.collections.ClosureUtils;<BR>import org.apache.commons.collections.CollectionUtils;<BR>import org.apache.commons.collections.functors.NOPClosure;<BR><BR>Map predicateMap = new HashMap();<BR><BR>predicateMap.put( isHonorRoll, addToHonorRoll );<BR>predicateMap.put( isProblem, flagForAttention );<BR>predicateMap.put( null, ClosureUtils.nopClosure() );<BR><BR>Closure processStudents = <BR>&nbsp;&nbsp;&nbsp;&nbsp;ClosureUtils.switchClosure( predicateMap );<BR><BR>CollectionUtils.forAllDo( allStudents, processStudents );</FONT></PRE><BR><BR><FONT size=2>在上面的代码中，predicateMap将Predicate与Closure进行了配对;如果一个学生满足作为键值的Predicate的条件，那么它将把它的值传到作为Map的值的Closure中。通过提供一个NOPClosure值和null键对，我们将把不符合任何Predicate条件的Student对象传给由ClosureUtils调用创建的“不做任何事”或者“无操作”的NOPClosure。<BR><BR>一个SwitchClosure, processStudents，从predicateMap中创建。并且通过使用CollectionUtils.forAllDo()方法，将processStudents Closure应用到allStudents中的每一个Student对象上。这是非常不一样的处理方法;记住，你并没有遍历任何队列。而是通过设置规则和因果关系，以及CollectionUtils和SwitchClosur来完成了这些操作。<BR><BR>当你将使用Predicate的标准与使用Closure的动作将分离开来时，你的代码的过程式处理就少了，而且更容易测试了。isHonorRoll Predicate能够与addToHonorRoll Closure分离开来进行独立的单元测试，它们也可以合起来通过使用Student类的模仿对象进行测试。第二个例子也会演示CollectionUtils.forAllDo()，它将一个Closure应用到了一个Collection的每一个元素中。<BR><BR>你也许注意到了使用算子并没用减少代码行数，实际上，使用算子还增加了代码量。但是，通过算子，你得到了将到了标准与动作的模块性与封装性的好处。如果你的代码题已经接近于几百行，那么请考虑一下更少过程化处理，更多面向对象的解决方案—通过使用算子。<BR><BR>Jakarta Commons Cookbook中的第四章“算子”介绍了Commons Collections中可用的算子，在第五章，“集合”中，向你展示了如何使用算子来操作Java 集合类API。<BR><BR>所有的算子-- Closure, Predicate, 和 Transformer—能够被合并为合并算子来处理任何种类的逻辑问题。switch, while和for结构能够被SwitchClosure, WhileClosure, 和 ForClosure模型化。<BR>复合的逻辑表达式可以被多个Predicate构建，通过使用OrPredicate, AndPredicate, AllPredicate, 和 NonePredicate将它们相互联接。Commons BeanUtils也包含了算子的实现被用来将算子应用到bean的属性中-- BeanPredicate, BeanComparator, 和 BeanPropertyValueChangeClosure。算子是考虑底层的应用架构的不一样的方法，它们可以很好地改造你编码实现的方法。</FONT><img src ="http://www.blogjava.net/zyb9114/aggbug/25551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-27 11:57 <a href="http://www.blogjava.net/zyb9114/articles/25551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>挖掘Jakarta Commons中隐藏的宝贝(一)[转载] </title><link>http://www.blogjava.net/zyb9114/articles/25550.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Tue, 27 Dec 2005 03:56:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/25550.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/25550.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/25550.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/25550.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/25550.html</trackback:ping><description><![CDATA[<FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;如果你不熟悉Jakarta Commons话，那么很有可能你已经重新发明了好几个轮子。在你编写更多的普通的框架或工具之前，体验一下Commons吧。它将会大大地节约你的时间。太多的人自己写一个，其实是与Commons Lang中的StringUtils重复的StringUtils类，或者，开发者不知道从Commons Collections中重新创建工具，哪怕commons-collections.jar已经在classpath中可用了。<BR><BR>真的，请停一下。看看Commons Collections API，然后再回到你的任务中;我发誓你会发现一些简单有用的东西可以帮你在明年节省一周的时间。如果大家花一点时间看看Jakarta Commons，我们将会得到更少的重复代码—我们将在重用的宗旨下真正做一些有用的事情。<BR><BR>我确实看到这样的情况发生过：一些人研究了一下Commons BeanUtils或者Commons Collections，然后总是有“啊，如果我那时知道这个的话，我就不会写那一万行的代码了”这样的时刻。Jakarta Commons仍有一部分保持相当的神秘;比如，许多人还没有听说过Commons CLI和Commons Configuration，并且大多数人还没有注意到Commons Collections中的functors(算子)包的价值。在这一系列中，我会专门强调一些Jakarta Commons中较少得到重视的工具和功能。<BR><BR>在这一系列的第一部分，我将探索定义在Commons Digester中的XML规则，Commons Collections中的功能，和使用一个有趣的应用，Commons JXPath，来查询一个对象的List。Jakarta Commons包含的功能目的在于帮助你解决低层次的编程问题：遍历集合，解析XML和从List中检出对象。我建议你花一些时间在这些小功能上，学习Jakarta Commons真的会为你节省不少时间。<BR><BR>并不简单地是学习使用Commons Digester来解析XML或者使用CollectionUtils的Predicate来过滤一个集合，而是当你一旦意识到如何将这些功能组合起来使用并且如何将Commons集成到你的项目中去的时候，你才会真正地看到它的好处。如果你这样做地话，你将会把commons-lang.jar, commons-beanutils.jar,和 commons-digester.jar当成JVM本身来看待。<BR><BR>如果你对Jakarta Commons更深的内容感兴趣的话，可以看一下Jakarta Commons Cookbook。这本书给你很多方法来更好的使用Commons，并告诉你如何将Jakarta Commons与其它的小的开源组件集成，如Velocity, FreeMarker, Lucene, 和 Jakarta Slide。这本书，我介绍了一组广泛的工具从Commons Lang中的简单工具到组合了Commons Digester, Commons Collections, 和Jakarta Lucene来搜索威廉.莎士比亚的著作。我希望这一系列和Jakarta Commons Cookbook这本书能够提供给你一些有趣的低层次的编程问题的解决方案。<BR><BR></FONT><B><SPAN style="FONT-SIZE: 16px">1. 用于Commons Digester的基于XML的规则集</SPAN></B><BR><FONT size=2>Commons Digester 1.6提供了将XML转化为对象的最简单的方法。Digester已经由O'Reilly网站上的两篇文章介绍过了:“学习和使用Jakarta Digester”，作者是Philipp K. Janert,和“使用Jakarta Commons, 第二部分”，作者是Vikram Goyal。两篇文章都演示了XML规则集的使用，但如何在XML中定义规则集并没有理解。大多所见到的Digester的使用是程序化地定义规则集，以已编译的形式。你应该避免硬编码的Digester规则，特别是当你可以将映射信息存储在外部文件中或一个类路径资源中时。外部化一个Digester规则可以更好地适应一个演化中的XML文档结构或者说一个演化中的对象模型。<BR><BR>为了演示在XML中定义规则集与硬编码的规则集之间的区别，考虑系统解析XML给一个Person bean，包括在下面定义的属性—id, name和age。<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>package org.test;<BR><BR>public class Person {<BR>&nbsp;&nbsp;public String id;<BR>&nbsp;&nbsp;public String name;<BR>&nbsp;&nbsp;public int age;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;public Person() {}<BR><BR>&nbsp;&nbsp;public String getId() { return id; }<BR>&nbsp;&nbsp;public void setId(String id) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;this.id = id;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public String getName() { return name; }<BR>&nbsp;&nbsp;public void setName(String name) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public int getAge() { return age; }<BR>&nbsp;&nbsp;public void setAge(int age) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;this.age = age;<BR>&nbsp;&nbsp;}<BR>}</FONT></PRE><BR><BR><FONT size=2>确认你的应用需要解析一个包含了多个person元素的XML文件。下面的XML文件，data.xml,包含了两个person元素，你想要把它们解析到Person对象中：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2><PEOPLE><BR>&nbsp;&nbsp;<PERSON id=1><BR>&nbsp;&nbsp;&nbsp;&nbsp;<NAME>Tom Higgins</NAME><BR>&nbsp;&nbsp;&nbsp;&nbsp;<AGE>25</AGE><BR>&nbsp;&nbsp;</PERSON><BR>&nbsp;&nbsp;<PERSON id=2><BR>&nbsp;&nbsp;&nbsp;&nbsp;<NAME>Barney Smith</NAME><BR>&nbsp;&nbsp;&nbsp;&nbsp;<AGE>75</AGE><BR>&nbsp;&nbsp;</PERSON><BR>&nbsp;&nbsp;<PERSON id=3><BR>&nbsp;&nbsp;&nbsp;&nbsp;<NAME>Susan Shields</NAME><BR>&nbsp;&nbsp;&nbsp;&nbsp;<AGE>53</AGE><BR>&nbsp;&nbsp;</PERSON><BR></PEOPLE></FONT></PRE><BR><BR><FONT size=2>你希望如果结构和XML文件的内容在未来几个月中变化，你不需要在已编译的Java代码中硬编码XML文件的结构。为了做到这一点，你需要在一个XML文件中定义Digester的规则，并且它可以作为一种资源从类路径中装入。下面的XML文档，person-rules.xml,映射person元素到Person bean：<BR></FONT><PRE class=overflow title="pre code"><FONT size=2><DIGESTER-RULES><BR>&nbsp;&nbsp;<PATTERN value="people/person"><BR>&nbsp;&nbsp;&nbsp;&nbsp;<OBJECT-CREATE-RULE classname="org.test.Person" /><BR>&nbsp;&nbsp;&nbsp;&nbsp;<SET-NEXT-RULE <BR methodname="add">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;paramtype="java.lang.Object"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<SET-PROPERTIES-RULE /><BR>&nbsp;&nbsp;&nbsp;&nbsp;<BEAN-PROPERTY-SETTER-RULE pattern="name" /><BR>&nbsp;&nbsp;&nbsp;&nbsp;<BEAN-PROPERTY-SETTER-RULE pattern="age" /><BR>&nbsp;&nbsp;</PATTERN><BR></DIGESTER-RULES></FONT></PRE><BR><BR><FONT size=2>上述所做的是指示Digester创建一个新的Person实例，当它遇到一个person元素时，调用add()来将Person对象加入到一个ArrayList中，设置person元素中相匹配的属性，并从下一级元素name和age中设置name和age的属性。<BR><BR>现在你已经看到了Person类，会被解析的文档，和以XML的形式定义的Digester规则。现在你需要创建一个由person-rules.xml定义了规则的Digester的实例。下面的代码创建 了一个Digester，通过将person-rules.xml的URL传递给DigesterLoader<BR><BR>既然person-rules.xml文件是与解析它的类在同一个包内的类路径资源，URL可以通过getClass().getResource()来得到。DigesterLoader然后解析规则并将它加到新创建的Digester上：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.digester.Digester;<BR>import org.apache.commons.digester.xmlrules.DigesterLoader;<BR><BR>// 从XML规则集中配置Digester<BR>URL rules = getClass().getResource("./person-rules.xml");<BR>Digester digester = <BR>&nbsp;&nbsp;&nbsp;&nbsp;DigesterLoader.createDigester(rules);<BR><BR>// 将空的List推入到Digester的堆栈<BR>List people = new ArrayList();<BR>digester.push( people );<BR><BR>// 解析XML文档<BR>InputStream input = new FileInputStream( "data.xml" );<BR>digester.parse( input );</FONT></PRE><BR><BR><FONT size=2>一旦Digester完成对data.xml的解析，三个Person对象将会在ArrayList people中。<BR>与将规则定义在XML不同的方法是使用简便的方法将它们加入到一个Digester实例中。大多数文章和例子都用这种方法，使用addObjectCreate() 和 addBeanPropertySetter()这样的方法来将规则加入中Digester上。下面的代码加入了与定义在person-rules.xml中相同的规则:<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>digester.addObjectCreate("people/person", Person.class);<BR>digester.addSetNext("people/person", "add", "java.lang.Object");<BR>digester.addBeanPropertySetter("people/person", "name");<BR>digester.addBeanPropertySetter("people/person", "age");</FONT></PRE>
<P><BR><BR><FONT size=2>如果你曾经发现自己正在用一个有着2500行代码的类，用SAX来解析一个巨大的XML文档，或者使用DOM或JDOM的完整的一个集合类，你就会理解XML的解析比它应该做的要复杂的多，就大多数情况来说。如果你正在建一个有着严格的速度和内存要求的高效的系统，你会需要SAX解析器的速度。如果你需要DOM级别3的复杂度，你会需要像Apache Xerces的解析器。但如果你只是简单的试图将几个XML文档解析到对象中去的话，看一下Commons Digester, 并把你的规则定义在一个XML文件中。<BR><BR>任何时候你都应该将配置信息从硬编码中移出来。我会建议你在一个XML文件中定义规则并从文件系统或类路径中装入它。这样可以使你的程序更好地适应XML文档以及对象模型的变化。有关在XML文件中定义Digester规则的更多的资料，参看Jakarta Commons Cookbook一书的6.2节,“将XML文档转换为对象”。<BR><BR>Tracker:http://www.blogjava.net/flyingis/archive/2005/11/09/18957.html</FONT></P><img src ="http://www.blogjava.net/zyb9114/aggbug/25550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-27 11:56 <a href="http://www.blogjava.net/zyb9114/articles/25550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java垃圾回收机制</title><link>http://www.blogjava.net/zyb9114/articles/25483.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Mon, 26 Dec 2005 11:29:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/25483.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/25483.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/25483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/25483.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/25483.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><B><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">引言</SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma"> <SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 27pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">的堆是一个运行时数据区<SPAN lang=EN-US>,</SPAN>类的实例<SPAN lang=EN-US>(</SPAN>对象<SPAN lang=EN-US>)</SPAN>从中分配空间。<SPAN lang=EN-US>Java</SPAN>虚拟机<SPAN lang=EN-US>(JVM)</SPAN>的堆中储存着正在运行的应用程序所建立的所有对象，这些对象通过<SPAN lang=EN-US>new</SPAN>、<SPAN lang=EN-US>newarray</SPAN>、<SPAN lang=EN-US>anewarray</SPAN>和<SPAN lang=EN-US>multianewarray</SPAN>等指令建立，但是它们不需要程序代码来显式地释放。一般来说，堆的是由垃圾回收 来负责的，尽管<SPAN lang=EN-US>JVM</SPAN>规范并不要求特殊的垃圾回收技术，甚至根本就不需要垃圾回收，但是由于内存的有限性，<SPAN lang=EN-US>JVM</SPAN>在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术，它自动地释放不再被程序引用的对象，按照特定的垃圾收集算法来实现资源自动回收的功能。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><B><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">垃圾收集的意义<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">在<SPAN lang=EN-US>C++</SPAN>中，对象所占的内存在程序结束运行之前一直被占用，在明确释放之前不能分配给其它对象；而在<SPAN lang=EN-US>Java</SPAN>中，当没有对象引用指向原先分配给某个对象的内存时，该内存便成为垃圾。<SPAN lang=EN-US>JVM</SPAN>的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是<SPAN lang=EN-US>"</SPAN>无用信息<SPAN lang=EN-US>"</SPAN>，这些信息将被丢弃。当一个对象不再被引用的时候，内存回收它占领的空间，以便空间被后来的新对象使用。事实上，除了释放没用的对象，垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间，内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端，<SPAN lang=EN-US>JVM</SPAN>将整理出的内存分配给新的对象。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">垃圾收集能自动释放内存空间，减轻编程的负担。这使<SPAN lang=EN-US>Java </SPAN>虚拟机具有一些优点。首先，它能使编程效率提高。在没有垃圾收集机制的时候，可能要花许多时间来解决一个难懂的存储器问题。在用<SPAN lang=EN-US>Java</SPAN>语言编程的时候，靠垃圾收集机制可大大缩短时间。其次是它保护程序的完整性<SPAN lang=EN-US>, </SPAN>垃圾收集是<SPAN lang=EN-US>Java</SPAN>语言安全性策略的一个重要部份。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">垃圾收集的一个潜在的缺点是它的开销影响程序性能。<SPAN lang=EN-US>Java</SPAN>虚拟机必须追踪运行程序中有用的对象<SPAN lang=EN-US>, </SPAN>而且最终释放没用的对象。这一个过程需要花费处理器的时间。其次垃圾收集算法的不完备性，早先采用的某些垃圾收集算法就不能保证<SPAN lang=EN-US>100%</SPAN>收集到所有的废弃内存。当然随着垃圾收集算法的不断改进以及软硬件运行效率的不断提升，这些问题都可以迎刃而解。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><B><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">垃圾收集的算法分析<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">语言规范没有明确地说明<SPAN lang=EN-US>JVM</SPAN>使用哪种垃圾回收算法，但是任何一种垃圾收集算法一般要做<SPAN lang=EN-US>2</SPAN>件基本的事情：（<SPAN lang=EN-US>1</SPAN>）发现无用信息对象；（<SPAN lang=EN-US>2</SPAN>）回收被无用对象占用的内存空间，使该空间可被程序再次使用。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">大多数垃圾回收算法使用了根集<SPAN lang=EN-US>(root set)</SPAN>这个概念；所谓根集就量正在执行的<SPAN lang=EN-US>Java</SPAN>程序可以访问的引用变量的集合<SPAN lang=EN-US>(</SPAN>包括局部变量、参数、类变量<SPAN lang=EN-US>)</SPAN>，程序可以使用引用变量访问对象的属性和调用对象的方法。垃圾收集首选需要确定从根开始哪些是可达的和哪些是不可达的，从根集可达的对象都是活动对象，它们不能作为垃圾被回收，这也包括从根集间接可达的对象。而根集通过任意路径不可达的对象符合垃圾收集的条件，应该被回收。下面介绍几个常用的算法。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 27pt; TEXT-INDENT: -18pt; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 27.0pt"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-list: Ignore">1、<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: red; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">引用计数法</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">(Reference Counting Collector)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">引用计数法是唯一没有使用根集的垃圾回收的法，该算法使用引用计数器来区分存活对象和不再使用的对象。一般来说，堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时，引用计数器置为<SPAN lang=EN-US>1</SPAN>。当对象被赋给任意变量时，引用计数器每次加<SPAN lang=EN-US>1</SPAN>当对象出了作用域后<SPAN lang=EN-US>(</SPAN>该对象丢弃不再使用<SPAN lang=EN-US>)</SPAN>，引用计数器减<SPAN lang=EN-US>1</SPAN>，一旦引用计数器为<SPAN lang=EN-US>0</SPAN>，对象就满足了垃圾收集的条件。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 17.95pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">基于引用计数器的垃圾收集器运行较快，不会长时间中断程序执行，适宜地必须 实时运行的程序。但引用计数器增加了程序执行的开销，因为每次对象赋给新的变量，计数器加<SPAN lang=EN-US>1</SPAN>，而每次现有对象出了作用域生，计数器减<SPAN lang=EN-US>1</SPAN>。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 17.95pt; TEXT-INDENT: -17.95pt; mso-pagination: widow-orphan; mso-char-indent-count: -1.71"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">2</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">、<SPAN lang=EN-US style="COLOR: red">tracing</SPAN><SPAN style="COLOR: red">算法</SPAN><SPAN lang=EN-US>(Tracing Collector)</SPAN></SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 17.95pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">tracing</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">算法是为了解决引用计数法的问题而提出，它使用了根集的概念。基于<SPAN lang=EN-US>tracing</SPAN>算法的垃圾收集器从根集开始扫描，识别出哪些对象可达，哪些对象不可达，并用某种方式标记可达对象，例如对每个可达对象设置一个或多个位。在扫描识别过程中，基于<SPAN lang=EN-US>tracing</SPAN>算法的垃圾收集也称为标记和清除<SPAN lang=EN-US>(mark-and-sweep)</SPAN>垃圾收集器<SPAN lang=EN-US>.<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">3</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">、<SPAN lang=EN-US style="COLOR: red">compacting</SPAN>算法<SPAN lang=EN-US>(Compacting Collector)<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 27pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">为了解决堆碎片问题，基于<SPAN lang=EN-US>tracing</SPAN>的垃圾回收吸收了<SPAN lang=EN-US>Compacting</SPAN>算法的思想，在清除的过程中，算法将所有的对象移到堆的一端，堆的另一端就变成了一个相邻的空闲内存区，收集器会对它移动的所有对象的所有引用进行更新，使得这些引用在新的位置能识别原来 的对象。在基于<SPAN lang=EN-US>Compacting</SPAN>算法的收集器的实现中，一般增加句柄和句柄表。　　<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">4</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">、<SPAN lang=EN-US style="COLOR: red">copying</SPAN><SPAN style="COLOR: red">算法</SPAN><SPAN lang=EN-US>(Coping Collector)<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 27pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。它开始时把堆分成 一个对象 面和多个空闲面， 程序从对象面为对象分配空间，当对象满了，基于<SPAN lang=EN-US>coping</SPAN>算法的垃圾 收集就从根集中扫描活动对象，并将每个 活动对象复制到空闲面<SPAN lang=EN-US>(</SPAN>使得活动对象所占的内存之间没有空闲洞<SPAN lang=EN-US>)</SPAN>，这样空闲面变成了对象面，原来的对象面变成了空闲面，程序会在新的对象面中分配内存。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 27pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">一种典型的基于<SPAN lang=EN-US>coping</SPAN>算法的垃圾回收是<SPAN lang=EN-US>stop-and-copy</SPAN>算法，它将堆分成对象面和空闲区域面，在对象面与空闲区域面的切换过程中，程序暂停执行。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">5</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">、<SPAN lang=EN-US style="COLOR: red">generation</SPAN>算法<SPAN lang=EN-US>(Generational Collector)<BR></SPAN>　　<SPAN lang=EN-US>stop-and-copy</SPAN>垃圾收集器的一个缺陷是收集器必须复制所有的活动对象，这增加了程序等待时间，这是<SPAN lang=EN-US>coping</SPAN>算法低效的原因。在程序设计中有这样的规律：多数对象存在的时间比较短，少数的存在时间比较长。因此，<SPAN lang=EN-US>generation</SPAN>算法将堆分成两个或多个，每个子堆作为对象的一代<SPAN lang=EN-US>(generation)</SPAN>。由于多数对象存在的时间比较短，随着程序丢弃不使用的对象，垃圾收集器将从最年轻的子堆中收集这些对象。在分代式的垃圾收集器运行后，上次运行存活下来的对象移到下一最高代的子堆中，由于老一代的子堆不会经常被回收，因而节省了时间。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">6</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">、<SPAN lang=EN-US style="COLOR: red">adaptive</SPAN>算法<SPAN lang=EN-US>(Adaptive Collector)<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">在特定的情况下，一些垃圾收集算法会优于其它算法。基于<SPAN lang=EN-US>Adaptive</SPAN>算法的垃圾收集器就是监控当前堆的使用情况，并将选择适当算法的垃圾收集器。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><B><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">透视<SPAN lang=EN-US>Java</SPAN>垃圾回收</SPAN></B><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">、命令行参数透视垃圾收集器的运行<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">2</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">、使用<SPAN lang=EN-US>System.gc()</SPAN>可以不管<SPAN lang=EN-US>JVM</SPAN>使用的是哪一种垃圾回收的算法，都可以请求<SPAN lang=EN-US>Java</SPAN>的垃圾回收。在命令行中有一个参数<SPAN lang=EN-US>-verbosegc</SPAN>可以查看<SPAN lang=EN-US>Java</SPAN>使用的堆内存的情况，它的格式如下：<SPAN lang=EN-US><BR><BR><SPAN style="COLOR: red">java -verbosegc classfile</SPAN><BR><BR></SPAN>　　可以看个例子：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">class TestGC <BR>{<BR></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">　<SPAN lang=EN-US>public static void main(String[] args) <BR></SPAN>　<SPAN lang=EN-US>{<BR></SPAN>　　<SPAN lang=EN-US>new TestGC();<BR></SPAN>　　<SPAN lang=EN-US>System.gc();<BR></SPAN>　　<SPAN lang=EN-US>System.runFinalization();<BR></SPAN>　<SPAN lang=EN-US>}<BR>}<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma"><BR></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">　　在这个例子中，一个新的对象被创建，由于它没有使用，所以该对象迅速地变为可达，程序编译后，执行命令：<SPAN lang=EN-US> java -verbosegc TestGC </SPAN>后结果为：<SPAN lang=EN-US><BR><BR>[Full GC 168K-&gt;97K(1984K), 0.0253873 secs]<BR><BR></SPAN>　　机器的环境为，<SPAN lang=EN-US>Windows 2000 + JDK<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">1.3.1</st1:chsdate>,</SPAN>箭头前后的数据<SPAN lang=EN-US>168K</SPAN>和<SPAN lang=EN-US>97K</SPAN>分别表示垃圾收集<SPAN lang=EN-US>GC</SPAN>前后所有存活对象使用的内存容量，说明有<SPAN lang=EN-US>168K-97K=71K</SPAN>的对象容量被回收，括号内的数据<SPAN lang=EN-US>1984K</SPAN>为堆内存的总容量，收集所需要的时间是<SPAN lang=EN-US>0.0253873</SPAN>秒（这个时间在每次执行的时候会有所不同）。<SPAN lang=EN-US><BR><BR></SPAN>　　<SPAN lang=EN-US>2</SPAN>、<SPAN lang=EN-US>finalize</SPAN>方法透视垃圾收集器的运行<SPAN lang=EN-US><BR><BR></SPAN>　　在<SPAN lang=EN-US>JVM</SPAN>垃圾收集器收集一个对象之前 ，一般要求程序调用适当的方法释放资源，但在没有明确释放资源的情况下，<SPAN lang=EN-US>Java</SPAN>提供了缺省机制来终止化该对象心释放资源，这个方法就是<SPAN lang=EN-US>finalize</SPAN>（）。它的原型为：<SPAN lang=EN-US><BR><BR>protected void finalize() throws Throwable<BR><BR></SPAN>　　在<SPAN lang=EN-US>finalize()</SPAN>方法返回之后，对象消失，垃圾收集开始执行。原型中的<SPAN lang=EN-US>throws Throwable</SPAN>表示它可以抛出任何类型的异常。<SPAN lang=EN-US><BR><BR></SPAN>　　之所以要使用<SPAN lang=EN-US>finalize()</SPAN>，是由于有时需要采取与<SPAN lang=EN-US>Java</SPAN>的普通方法不同的一种方法，通过分配内存来做一些具有<SPAN lang=EN-US>C</SPAN>风格的事情。这主要可以通过<SPAN lang=EN-US>"</SPAN>固有方法<SPAN lang=EN-US>"</SPAN>来进行，它是从<SPAN lang=EN-US>Java</SPAN>里调用非<SPAN lang=EN-US>Java</SPAN>方法的一种方式。<SPAN lang=EN-US>C</SPAN>和<SPAN lang=EN-US>C++</SPAN>是目前唯一获得固有方法支持的语言。但由于它们能调用通过其他语言编写的子程序，所以能够有效地调用任何东西。在非<SPAN lang=EN-US>Java</SPAN>代码内部，也许能调用<SPAN lang=EN-US>C</SPAN>的<SPAN lang=EN-US>malloc()</SPAN>系列函数，用它分配存储空间。而且除非调用了<SPAN lang=EN-US>free()</SPAN>，否则存储空间不会得到释放，从而造成内存<SPAN lang=EN-US>"</SPAN>漏洞<SPAN lang=EN-US>"</SPAN>的出现。当然，<SPAN lang=EN-US>free()</SPAN>是一个<SPAN lang=EN-US>C</SPAN>和<SPAN lang=EN-US>C++</SPAN>函数，所以我们需要在<SPAN lang=EN-US>finalize()</SPAN>内部的一个固有方法中调用它。也就是说我们不能过多地使用<SPAN lang=EN-US>finalize()</SPAN>，它并不是进行普通清除工作的理想场所。<SPAN lang=EN-US><BR><BR></SPAN>　　在普通的清除工作中，为清除一个对象，那个对象的用户必须在希望进行清除的地点调用一个清除方法。这与<SPAN lang=EN-US>C++"</SPAN>破坏器<SPAN lang=EN-US>"</SPAN>的概念稍有抵触。在<SPAN lang=EN-US>C++</SPAN>中，所有对象都会破坏（清除）。或者换句话说，所有对象都<SPAN lang=EN-US>"</SPAN>应该<SPAN lang=EN-US>"</SPAN>破坏。若将<SPAN lang=EN-US>C++</SPAN>对象创建成一个本地对象，比如在堆栈中创建（在<SPAN lang=EN-US>Java</SPAN>中是不可能的），那么清除或破坏工作就会在<SPAN lang=EN-US>"</SPAN>结束花括号<SPAN lang=EN-US>"</SPAN>所代表的、创建这个对象的作用域的末尾进行。若对象是用<SPAN lang=EN-US>new</SPAN>创建的（类似于<SPAN lang=EN-US>Java</SPAN>），那么当程序员调用<SPAN lang=EN-US>C++</SPAN>的<SPAN lang=EN-US>delete</SPAN>命令时（<SPAN lang=EN-US>Java</SPAN>没有这个命令），就会调用相应的破坏器。若程序员忘记了，那么永远不会调用破坏器，我们最终得到的将是一个内存<SPAN lang=EN-US>"</SPAN>漏洞<SPAN lang=EN-US>"</SPAN>，另外还包括对象的其他部分永远不会得到清除。<SPAN lang=EN-US><BR><BR></SPAN>　　相反，<SPAN lang=EN-US>Java</SPAN>不允许我们创建本地（局部）对象<SPAN lang=EN-US>--</SPAN>无论如何都要使用<SPAN lang=EN-US>new</SPAN>。但在<SPAN lang=EN-US>Java</SPAN>中，没有<SPAN lang=EN-US>"delete"</SPAN>命令来释放对象，因为垃圾收集器会帮助我们自动释放存储空间。所以如果站在比较简化的立场，我们可以说正是由于存在垃圾收集机制，所以<SPAN lang=EN-US>Java</SPAN>没有破坏器。然而，随着以后学习的深入，就会知道垃圾收集器的存在并不能完全消除对破坏器的需要，或者说不能消除对破坏器代表的那种机制的需要（而且绝对不能直接调用<SPAN lang=EN-US>finalize()</SPAN>，所以应尽量避免用它）。若希望执行除释放存储空间之外的其他某种形式的清除工作，仍然必须调用<SPAN lang=EN-US>Java</SPAN>中的一个方法。它等价于<SPAN lang=EN-US>C++</SPAN>的破坏器，只是没后者方便。<SPAN lang=EN-US><BR><BR></SPAN>　　下面这个例子向大家展示了垃圾收集所经历的过程，并对前面的陈述进行了总结。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">class Chair {<BR></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">　<SPAN lang=EN-US>static boolean gcrun = false;<BR></SPAN>　<SPAN lang=EN-US>static boolean f = false;<BR></SPAN>　<SPAN lang=EN-US>static int created = 0;<BR></SPAN>　<SPAN lang=EN-US>static int finalized = 0;<BR></SPAN>　<SPAN lang=EN-US>int i;<BR></SPAN>　<SPAN lang=EN-US>Chair() {<BR></SPAN>　　<SPAN lang=EN-US>i = ++created;<BR></SPAN>　　<SPAN lang=EN-US>if(created == 47) <BR></SPAN>　　　<SPAN lang=EN-US>System.out.println("Created 47");<BR></SPAN>　<SPAN lang=EN-US>}<BR></SPAN>　<SPAN lang=EN-US>protected void finalize() {<BR></SPAN>　　<SPAN lang=EN-US>if(!gcrun) {<BR></SPAN>　　　<SPAN lang=EN-US>gcrun = true;<BR></SPAN>　　　<SPAN lang=EN-US>System.out.println("Beginning to finalize after " + created + " Chairs have been created");<BR></SPAN>　　<SPAN lang=EN-US>}<BR></SPAN>　　<SPAN lang=EN-US>if(i == 47) {<BR></SPAN>　　　<SPAN lang=EN-US>System.out.println("Finalizing Chair #47, " +"Setting flag to stop Chair creation");<BR></SPAN>　　　<SPAN lang=EN-US>f = true;<BR></SPAN>　　<SPAN lang=EN-US>}<BR></SPAN>　　<SPAN lang=EN-US>finalized++;<BR></SPAN>　　<SPAN lang=EN-US>if(finalized &gt;= created)<BR></SPAN>　　　<SPAN lang=EN-US>System.out.println("All " + finalized + " finalized");<BR></SPAN>　<SPAN lang=EN-US>}<BR>}<BR><BR>public class Garbage {<BR></SPAN>　<SPAN lang=EN-US>public static void main(String[] args) {<BR></SPAN>　　<SPAN lang=EN-US>if(args.length == 0) {<BR></SPAN>　　　<SPAN lang=EN-US>System.err.println("Usage: \n" + "java Garbage before\n or:\n" + "java Garbage after");<BR></SPAN>　　　<SPAN lang=EN-US>return;<BR></SPAN>　　<SPAN lang=EN-US>}<BR></SPAN>　　<SPAN lang=EN-US>while(!Chair.f) {<BR></SPAN>　　　<SPAN lang=EN-US>new Chair();<BR></SPAN>　　　<SPAN lang=EN-US>new String("To take up space");<BR></SPAN>　　<SPAN lang=EN-US>}<BR></SPAN>　　<SPAN lang=EN-US>System.out.println("After all Chairs have been created:\n" + "total created = " + Chair.created +<BR>", total finalized = " + Chair.finalized);<BR></SPAN>　　<SPAN lang=EN-US>if(args[0].equals("before")) {<BR></SPAN>　　　　<SPAN lang=EN-US>System.out.println("gc():");<BR></SPAN>　　　　<SPAN lang=EN-US>System.gc();<BR></SPAN>　　　　<SPAN lang=EN-US>System.out.println("runFinalization():");<BR></SPAN>　　　　<SPAN lang=EN-US>System.runFinalization();<BR></SPAN>　　<SPAN lang=EN-US>}<BR></SPAN>　　<SPAN lang=EN-US>System.out.println("bye!");<BR></SPAN>　　<SPAN lang=EN-US>if(args[0].equals("after"))<BR></SPAN>　　　<SPAN lang=EN-US>System.runFinalizersOnExit(true);<BR></SPAN>　<SPAN lang=EN-US>}<BR>}<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma"><BR></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Tahoma">　　上面这个程序创建了许多<SPAN lang=EN-US>Chair</SPAN>对象，而且在垃圾收集器开始运行后的某些时候，程序会停止创建<SPAN lang=EN-US>Chair</SPAN>。由于垃圾收集器可能在任何时间运行，所以我们不能准确知道它在何时启动。因此，程序用一个名为<SPAN lang=EN-US>gcrun</SPAN>的标记来指出垃圾收集器是否已经开始运行。利用第二个标记<SPAN lang=EN-US>f</SPAN>，<SPAN lang=EN-US>Chair</SPAN>可告诉<SPAN lang=EN-US>main()</SPAN>它应停止对象的生成。这两个标记都是在<SPAN lang=EN-US>finalize()</SPAN>内部设置的，它调用于垃圾收集期间。另两个<SPAN lang=EN-US>static</SPAN>变量<SPAN lang=EN-US>--created</SPAN>以及<SPAN lang=EN-US>finalized--</SPAN>分别用于跟踪已创建的对象数量以及垃圾收集器已进行完收尾工作的对象数量。最后，每个<SPAN lang=EN-US>Chair</SPAN>都有它自己的（非<SPAN lang=EN-US>static</SPAN>）<SPAN lang=EN-US>int i</SPAN>，所以能跟踪了解它具体的编号是多少。编号为<SPAN lang=EN-US>47</SPAN>的<SPAN lang=EN-US>Chair</SPAN>进行完收尾工作后，标记会设为<SPAN lang=EN-US>true</SPAN>，最终结束<SPAN lang=EN-US>Chair</SPAN>对象的创建过程。（关于这个例子的更具体的分析和说明请参看《<SPAN lang=EN-US>Java</SPAN>编程思想》的第四章）<SPAN lang=EN-US><BR><BR></SPAN>　　<B>关于垃圾收集的几点补充</B><SPAN lang=EN-US><BR><BR></SPAN>　　经过上述的说明，可以发现垃圾回收有以下的几个特点：<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>1</SPAN>）垃圾收集发生的不可预知性：由于实现了不同的垃圾收集算法和采用了不同的收集机制，所以它有可能是定时发生，有可能是当出现系统空闲<SPAN lang=EN-US>CPU</SPAN>资源时发生，也有可能是和原始的垃圾收集一样，等到内存消耗出现极限时发生，这与垃圾收集器的选择和具体的设置都有关系。<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>2</SPAN>）垃圾收集的精确性：主要包括<SPAN lang=EN-US>2 </SPAN>个方面：（<SPAN lang=EN-US>a</SPAN>）垃圾收集器能够精确标记活着的对象；（<SPAN lang=EN-US>b</SPAN>）垃圾收集器能够精确地定位对象之间的引用关系。前者是完全地回收所有废弃对象的前提，否则就可能造成内存泄漏。而后者则是实现归并和复制等算法的必要条件。所有不可达对象都能够可靠地得到回收，所有对象都能够重新分配，允许对象的复制和对象内存的缩并，这样就有效地防止内存的支离破碎。（<SPAN lang=EN-US>3</SPAN>）现在有许多种不同的垃圾收集器，每种有其算法且其表现各异，既有当垃圾收集开始时就停止应用程序的运行，又有当垃圾收集开始时也允许应用程序的线程运行，还有在同一时间垃圾收集多线程运行。<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>4</SPAN>）垃圾收集的实现和具体的<SPAN lang=EN-US>JVM </SPAN>以及<SPAN lang=EN-US>JVM</SPAN>的内存模型有非常紧密的关系。不同的<SPAN lang=EN-US>JVM </SPAN>可能采用不同的垃圾收集，而<SPAN lang=EN-US>JVM </SPAN>的内存模型决定着该<SPAN lang=EN-US>JVM</SPAN>可以采用哪些类型垃圾收集。现在，<SPAN lang=EN-US>HotSpot </SPAN>系列<SPAN lang=EN-US>JVM</SPAN>中的内存系统都采用先进的面向对象的框架设计，这使得该系列<SPAN lang=EN-US>JVM</SPAN>都可以采用最先进的垃圾收集。<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>5</SPAN>）随着技术的发展，现代垃圾收集技术提供许多可选的垃圾收集器，而且在配置每种收集器的时候又可以设置不同的参数，这就使得根据不同的应用环境获得最优的应用性能成为可能。<SPAN lang=EN-US><BR><BR></SPAN>　　针对以上特点，我们在使用的时候要注意：<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>1</SPAN>）不要试图去假定垃圾收集发生的时间，这一切都是未知的。比如，方法中的一个临时对象在方法调用完毕后就变成了无用对象，这个时候它的内存就可以被释放。<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>2</SPAN>）<SPAN lang=EN-US>Java</SPAN>中提供了一些和垃圾收集打交道的类，而且提供了一种强行执行垃圾收集的方法<SPAN lang=EN-US>--</SPAN>调用<SPAN lang=EN-US>System.gc()</SPAN>，但这同样是个不确定的方法。<SPAN lang=EN-US>Java </SPAN>中并不保证每次调用该方法就一定能够启动垃圾收集，它只不过会向<SPAN lang=EN-US>JVM</SPAN>发出这样一个申请，到底是否真正执行垃圾收集，一切都是个未知数。<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>3</SPAN>）挑选适合自己的垃圾收集器。一般来说，如果系统没有特殊和苛刻的性能要求，可以采用<SPAN lang=EN-US>JVM</SPAN>的缺省选项。否则可以考虑使用有针对性的垃圾收集器，比如增量收集器就比较适合实时性要求较高的系统之中。系统具有较高的配置，有比较多的闲置资源，可以考虑使用并行标记<SPAN lang=EN-US>/</SPAN>清除收集器。<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>4</SPAN>）关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的，不要让自己的一个小错误导致内存出现大漏洞。<SPAN lang=EN-US><BR><BR></SPAN>　　（<SPAN lang=EN-US>5</SPAN>）尽早释放无用对象的引用。大多数程序员在使用临时变量的时候，都是让引用变量在退出活动域<SPAN lang=EN-US>(scope)</SPAN>后，自动设置为<SPAN lang=EN-US>null</SPAN>，暗示垃圾收集器来收集该对象，还必须注意该引用的对象是否被监听，如果有，则要去掉监听器，然后再赋空值。<SPAN lang=EN-US><BR><BR></SPAN>　　<B>结束语</B><SPAN lang=EN-US><BR><BR></SPAN>　　一般来说，<SPAN lang=EN-US>Java</SPAN>开发人员可以不重视<SPAN lang=EN-US>JVM</SPAN>中堆内存的分配和垃圾处理收集，但是，充分理解<SPAN lang=EN-US>Java</SPAN>的这一特性可以让我们更有效地利用资源。同时要注意<SPAN lang=EN-US>finalize()</SPAN>方法是<SPAN lang=EN-US>Java</SPAN>的缺省机制，有时为确保对象资源的明确释放，可以编写自己的<SPAN lang=EN-US>finalize</SPAN>方法。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P><img src ="http://www.blogjava.net/zyb9114/aggbug/25483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-26 19:29 <a href="http://www.blogjava.net/zyb9114/articles/25483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java性能调优续</title><link>http://www.blogjava.net/zyb9114/articles/25480.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Mon, 26 Dec 2005 10:44:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/25480.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/25480.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/25480.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/25480.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/25480.html</trackback:ping><description><![CDATA[<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123372421><SPAN lang=EN-US><FONT face=Arial size=4>3.2 </FONT></SPAN></A><SPAN style="mso-bookmark: _Toc123372421"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>字符串的调优</FONT></SPAN></SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">下面列出一些常见的关于字符串优化的策略，简单的我就不多作解释了。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>1) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用规则表达式处理字符串匹配代替复杂的字符串查找和复制操作；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>2) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用不拷贝字符串中字符的高效方法，例如</SPAN><SPAN lang=EN-US><FONT face=Arial>String.subString()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">方法；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>3) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能不要使用需要拷贝字符串中字符的低效方法，例如</SPAN><SPAN lang=EN-US><FONT face=Arial>String.toUpperCase()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>String.toLowercase()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>4) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在编译期使用</SPAN><SPAN lang=EN-US><FONT face=Arial>String</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的“</SPAN><SPAN lang=EN-US><FONT face=Arial>+</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">”操作符来执行连接操作，在运行期使用</SPAN><SPAN lang=EN-US><FONT face=Arial>StringBuffer</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">执行连接操作；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">这里特别强调一下，因为我已经在网上看到好多文章都推荐使用</SPAN><SPAN lang=EN-US><FONT face=Arial>StringBuffer</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的</SPAN><SPAN lang=EN-US><FONT face=Arial>append()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">方法来做字符串的连接操作。其实在</SPAN><SPAN lang=EN-US><FONT face=Arial>JVM</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">能够在编译期就能确定结果的情形，使用</SPAN><SPAN lang=EN-US><FONT face=Arial>String</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的“</SPAN><SPAN lang=EN-US><FONT face=Arial>+</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">”操作符的性能要好很多。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123372422><SPAN lang=EN-US><FONT face=Arial size=4>3.3 </FONT></SPAN></A><SPAN style="mso-bookmark: _Toc123372422"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>异常，类型转换和变量</FONT></SPAN></SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>1) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">考虑在抛出异常的时候是否可以不即时生成堆栈信息而使用一个已有的异常实例；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">创建异常的开销很大。当创建一个异常时，需要收集一个栈跟踪（</SPAN><SPAN lang=EN-US><FONT face=Arial>Stack Trace</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">），这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照，正是这一部分开销很大。运行时栈不是为有效的异常创建而设计的，而是设计用来让运行时尽可能快地运行。入栈，出栈，入栈，出栈。让这样的工作顺利完成，而没有任何不必要的延迟。但是，当需要创建一个</SPAN><SPAN lang=EN-US><FONT face=Arial>Exception</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">时，</SPAN><SPAN lang=EN-US><FONT face=Arial>JVM</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">不得不说：“先别动，我想就你现在的样子存一份快照，所以按时停止入栈和出栈操作，笑着等我拍完快照吧。”栈跟踪不只包含运行时栈中的一两个元素，而是包含这个栈中的每一个元素，从栈顶到栈底，还有行号和一切应有的东西。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">因此，创建异常这一部分开销很大。从技术上讲，栈跟踪快照是在本地方法</SPAN><SPAN lang=EN-US><FONT face=Arial>Throwable.fillInStackTrace()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">中发生的，这个方法不是从</SPAN><SPAN lang=EN-US><FONT face=Arial>Throwable contructor</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">那里调用的。但是这并并没有什么影响——如果你创建了一个</SPAN><SPAN lang=EN-US><FONT face=Arial>Exception</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，就得付出代价。好在捕获异常开销不大，因此可以用</SPAN><SPAN lang=EN-US><FONT face=Arial>try-catch</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">将核心内容包起来。你也可以在方法定义中定义</SPAN><SPAN lang=EN-US><FONT face=Arial>throws</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">子句，这样对性能不会造成什么损失。从技术上讲，你甚至可以随意地抛出异常，而不用花费很大的代价。招致性能损失的并不是</SPAN><SPAN lang=EN-US><FONT face=Arial>throw</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">幸运的是，好的编程习惯已教会我们，不应该不管三七二十一就抛出异常。异常是为异常的情况而设计的，使用时也应该牢记这一原则。但是，万一你不想遵从好的编程习惯，</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">语言就会让你知道，那样就可以让你的程序运行的更快，从而鼓励你去那样做。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>2) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">用</SPAN><SPAN lang=EN-US><FONT face=Arial>instanceof</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">替代在</SPAN><SPAN lang=EN-US><FONT face=Arial>try-catch</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">中做投机的强制类型转换方法；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>3) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能少的使用强制类型转换方法，尤其是使用类型特定的集合类时；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>4) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用</SPAN><SPAN lang=EN-US><FONT face=Arial>int</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">优先于其他所有的数据类型；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>5) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能使用基本数据类型做临时变量；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>6) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">考虑直接获取实例变量而不通过</SPAN><SPAN lang=EN-US><FONT face=Arial>get</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，</SPAN><SPAN lang=EN-US><FONT face=Arial>set</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">方法获取（注意：这不符合面向对象的封装原则，不推荐使用）。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123372423><SPAN lang=EN-US><FONT face=Arial size=4>3.4 </FONT></SPAN></A><SPAN style="mso-bookmark: _Toc123372423"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>循环，选择和递归</FONT></SPAN></SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>1) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在循环中消除不必要的代码，做尽可能少的事情；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>2) Switch</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">语句中使用连续的</SPAN><SPAN lang=EN-US><FONT face=Arial>case</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">值；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>3) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">确定是否真的需要用到递归，最好转为用循环来实现。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123372424><SPAN lang=EN-US><FONT face=Arial size=4>3.5 </FONT></SPAN></A><SPAN style="mso-bookmark: _Toc123372424"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>输入输出操作</FONT></SPAN></SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>1) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在程序中尽量不要使用</SPAN><SPAN lang=EN-US><FONT face=Arial>System.out</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">这样的语句，而使用</SPAN><SPAN lang=EN-US><FONT face=Arial>log4j</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">这样的日志工具替换，以在程序正式上线的时候可以关闭所有不必要的日志操作提高性能；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>2) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">当程序中有大量的</SPAN><SPAN lang=EN-US><FONT face=Arial>I/O</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">操作时，考虑将日志写入不同的文件做到并行化操作以提高性能，并可以用一个后台线程执行</SPAN><SPAN lang=EN-US><FONT face=Arial>I/O</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">操作而不打断正常程序的执行；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>3) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">正确的使用序列化机制，没有必要序列化的成员变量需要标识为</SPAN><SPAN lang=EN-US><FONT face=Arial>transient</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>4) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用</SPAN><SPAN lang=EN-US><FONT face=Arial>NIO</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">技术。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123372425><SPAN lang=EN-US><FONT face=Arial size=4>3.6 JDBC</FONT></SPAN></A><SPAN lang=EN-US><FONT face=Arial size=4> </FONT></SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>1) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用正确的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDBC</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动，尽可能地选择最新的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDBC</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">最新的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDBC</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">驱动不仅优化了性能，而且提供了更多的性能更好的接口供开发人员使用。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>2) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用应用服务器自带的连接池，而不要使用自己的连接池或干脆不用连接池；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>3) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在使用完数据库资源后，需依次关闭</SPAN><SPAN lang=EN-US><FONT face=Arial>ResultSet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，</SPAN><SPAN lang=EN-US><FONT face=Arial>Statement</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>Connection</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>4) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">手动控制事务，使用</SPAN><SPAN lang=EN-US><FONT face=Arial>connection.setAutoCommit(false)</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">关闭自动提交，使用</SPAN><SPAN lang=EN-US><FONT face=Arial>executeBatch()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">进行批量更新；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>5) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">业务复杂或者大数据量操作时使用存储过程；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>6) ResultSet.next()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">极其消耗性能，建议使用</SPAN><SPAN lang=EN-US><FONT face=Arial>RowSet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">替代</SPAN><SPAN lang=EN-US><FONT face=Arial>ResultSet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>7) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">把所有的字符数据都保存为</SPAN><SPAN lang=EN-US><FONT face=Arial>Unicode</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">以</SPAN><SPAN lang=EN-US><FONT face=Arial>UniCode</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">形式处理所有数据，数据库驱动程序不必再执行转换过程；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>8) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能的优化</SPAN><SPAN lang=EN-US><FONT face=Arial>SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">语句；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>9) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">少用</SPAN><SPAN lang=EN-US><FONT face=Arial>join</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，多用</SPAN><SPAN lang=EN-US><FONT face=Arial>index</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>10) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用</SPAN><SPAN lang=EN-US><FONT face=Arial>EXPLAIN</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">工具监控</SPAN><SPAN lang=EN-US><FONT face=Arial>SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">语句的执行，以确定瓶颈所在；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>11)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">不要使用</SPAN><SPAN lang=EN-US><FONT face=Arial> SELECT * ..., </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用</SPAN><SPAN lang=EN-US><FONT face=Arial> SELECT Field1, Field1 ...</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>12)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过</SPAN><SPAN lang=EN-US><FONT face=Arial>index</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">获取字段，而不要使用名字去获取，例如</SPAN><SPAN lang=EN-US><FONT face=Arial>resultSet.getString(1) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">而不是</SPAN><SPAN lang=EN-US><FONT face=Arial> resultSet.getString("field1")</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>13)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">缓存数据，避免重复查询；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>14)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">考虑使用内存数据库；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>15)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调整</SPAN><SPAN lang=EN-US><FONT face=Arial>fetch size</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">进行批量查询；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>16)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能的使</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">数据类型和数据库类型相匹配，转换数据在匹配不好的数据类型间效率太差；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>17)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">避免使用低效的</SPAN><SPAN lang=EN-US><FONT face=Arial>metadata</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调用，尤其是</SPAN><SPAN lang=EN-US><FONT face=Arial>getBestRowIdentifier( ), getColumns( ), getCrossReference( ), getExportedKeys( ), getImportedKeys( ), getPrimaryKeys( ), getTables( ), and getVersionColumns( )</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>18)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用</SPAN><SPAN lang=EN-US><FONT face=Arial>metadata</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">查询减少数据库网络通信量；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>19)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"></SPAN><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用最低的事务隔离级别；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>20)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用乐观锁机制；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>21)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">把应用服务器和数据库分散在不同的机器中，性能可能会更好。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123372426><SPAN lang=EN-US><FONT face=Arial size=4>3.7 Servlet</FONT></SPAN></A><SPAN style="mso-bookmark: _Toc123372426"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>JSP</FONT></SPAN></FONT></SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>1) Session</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的使用；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">应用服务器保存很多会话时，容易造成内存不足，所以尽量减少</SPAN><SPAN lang=EN-US><FONT face=Arial>Session</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的使用，放置到</SPAN><SPAN lang=EN-US><FONT face=Arial>Session</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">中的对象不应该是大对象，最好是简单的小对象，实现串行化接口。当会话不再需要时，应当及时调用</SPAN><SPAN lang=EN-US><FONT face=Arial>invalidate()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">方法清除会话。而当某个变量不需要时，及时调用</SPAN><SPAN lang=EN-US><FONT face=Arial>removeAttribute()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">方法清除变量。当</SPAN><SPAN lang=EN-US><FONT face=Arial>session</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">终止时需要清除不必要的资源，实现</SPAN><SPAN lang=EN-US><FONT face=Arial>HttpSessionBindingListener</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">接口的</SPAN><SPAN lang=EN-US><FONT face=Arial>valueUnbound()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">方法。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>2) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用</SPAN><SPAN lang=EN-US><FONT face=Arial>include directive</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，而不使用</SPAN><SPAN lang=EN-US><FONT face=Arial>include action</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">目前在</SPAN><SPAN lang=EN-US><FONT face=Arial>JSP</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">页面中引入外部资源的方法主要有两种：</SPAN><SPAN lang=EN-US><FONT face=Arial>include directive</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>include action</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。</SPAN><SPAN lang=EN-US><FONT face=Arial>Include directive</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">：例如</SPAN><SPAN lang=EN-US><FONT face=Arial>&lt;%@ include file=”copyright.html” %&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，该指令在编译时引入指定的资源。在编译之前，带有</SPAN><SPAN lang=EN-US><FONT face=Arial>include</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">指令的页面和指定的资源被合并成一个文件。被引用的资源在编译时就确定，比运行时才确定资源更高效。</SPAN><SPAN lang=EN-US><FONT face=Arial>Include action</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">：例如</SPAN><SPAN lang=EN-US><FONT face=Arial>&lt; jsp:include page=”copyright.jsp” /&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，该动作引入指定页面执行后生成的结果。由于它在运行时完成，因此对输出结果的控制更加灵活。但是，只有当引用的内容被频繁改变时，或者在对主页面的请求没有出现之前，被引用的页面无法确定时，使用</SPAN><SPAN lang=EN-US><FONT face=Arial>include action</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">才合算。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>3) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对于那些无需跟踪会话状态的</SPAN><SPAN lang=EN-US><FONT face=Arial>jsp</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，关闭自动创建的会话可以节省一些资源。使用如下</SPAN><SPAN lang=EN-US><FONT face=Arial>page</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">指令：</SPAN><SPAN lang=EN-US><FONT face=Arial> &lt; %@ page session=”false” %&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>4) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽量不要把</SPAN><SPAN lang=EN-US><FONT face=Arial>jsp</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">页面定义为单线程，应设置为</SPAN><SPAN lang=EN-US><FONT face=Arial>&lt; %@page isThreadSafe=”true” %&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>5) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在</SPAN><SPAN lang=EN-US><FONT face=Arial>jsp</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">页面最好使用输出缓存功能，如：</SPAN><SPAN lang=EN-US><FONT face=Arial>&lt; %@page buffer=”32kb” %&gt;</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>6) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在</SPAN><SPAN lang=EN-US><FONT face=Arial>servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">之间跳转时，</SPAN><SPAN lang=EN-US><FONT face=Arial>forward</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">比</SPAN><SPAN lang=EN-US><FONT face=Arial>sendRedirect</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">更有效；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>7) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>HttpServletResponse</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">缓冲区，如：</SPAN><SPAN lang=EN-US><FONT face=Arial>response.setBufferSize(20000)</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>8) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">建议在</SPAN><SPAN lang=EN-US><FONT face=Arial>servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">里使用</SPAN><SPAN lang=EN-US><FONT face=Arial>ServletOutputStream</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">输出图片等对象；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>9) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">不要使用</SPAN><SPAN lang=EN-US><FONT face=Arial>SingleThreadModel</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，使</SPAN><SPAN lang=EN-US><FONT face=Arial>Servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">是线程安全的，但是尽可能的减少消耗在同步代码上的时间，使用足够多的</SPAN><SPAN lang=EN-US><FONT face=Arial>servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">去响应用户的请求；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>10) </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能的使</SPAN><SPAN lang=EN-US><FONT face=Arial>useBean</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的范围在</SPAN><SPAN lang=EN-US><FONT face=Arial>page</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">范围内；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>11)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><FONT face=Arial><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>Servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的</SPAN><SPAN lang=EN-US><FONT face=Arial>inti()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>destroy()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">或</SPAN><SPAN lang=EN-US><FONT face=Arial>jspInit()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>jspDestroy()</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">方法用于创建和删除昂贵的资源，例如缓存对象和数据库连接；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>12)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">避免使用反向</SPAN><SPAN lang=EN-US><FONT face=Arial>DNS</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">查找；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>13)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">预编译</SPAN><SPAN lang=EN-US><FONT face=Arial>JSP</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">页面；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>14)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能的在客户段校验数据；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>15)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face=Arial>&nbsp;</FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">禁止自动装载特色防止周期性的装载</SPAN><SPAN lang=EN-US><FONT face=Arial>servlet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>jsp</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123372427><SPAN lang=EN-US><FONT face=Arial size=4>3.8 EJB</FONT></SPAN></A></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">由于</SPAN><SPAN lang=EN-US><FONT face=Arial>EJB2.0</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">已经很少项目在用了，</SPAN><SPAN lang=EN-US><FONT face=Arial>EJB3.0</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">再成熟一点，我再补充这一部分吧！</SPAN></FONT></P><img src ="http://www.blogjava.net/zyb9114/aggbug/25480.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-26 18:44 <a href="http://www.blogjava.net/zyb9114/articles/25480.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>应用程序调优——对象创建</title><link>http://www.blogjava.net/zyb9114/articles/25362.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sun, 25 Dec 2005 05:16:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/25362.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/25362.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/25362.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/25362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/25362.html</trackback:ping><description><![CDATA[<SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>对象创建</FONT></SPAN>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对象的创建是一个非常昂贵的工作，而由于对象的创建而导致经常性的垃圾收集则是一个更加消耗时间和</SPAN><SPAN lang=EN-US><FONT face=Arial>CPU</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的操作。我们在编码时，应当尽量的减少对象的创建。不要在经常被执行的代码中创建对象；使用集合对象时最好预先分配其大小；当一个</SPAN><SPAN lang=EN-US><FONT face=Arial>class</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的多个实例都需要获取某个对象时，最好能标记那个对象</SPAN><SPAN lang=EN-US><FONT face=Arial>static</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；当不需要</SPAN><SPAN lang=EN-US><FONT face=Arial>stack trace</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">时尽可能的重用异常实例等等都能很有效的避免对象创建而导致的额外的开销。下面是一些常用的有效的策略：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="COLOR: blue; mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>1)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对象池技术</SPAN><SPAN lang=EN-US style="COLOR: blue"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">中开发一个普遍性的对象池架构可以更好地利用资源，并可以使对象创建的成本降到最小。大多数人对直接或间接运用对象池来连接一个数据库都很熟悉。但通常你也可以将对象放入对象池中从而节省重要的资源、提高程序的效率并控制对不充足资源的访问。出于对设计、成本或性能的考虑，放入对象池中的对象通常是有限的。它们或者是初始化成本很高的对象，或者是很少用的对象。运用对象池我们可以管理竞争性客户端对有限的对象集的访问。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>对象池主要是可以更好地运用你的资源。例如，设想有相当多的客户要有效运用很少的数据库连接或网络连接。通过限制对对象的访问（只在客户端需要的时候才能访问对象），你就可以释放资源，让其它客户端使用。通过对象池提高对象的利用率通常可以提高系统的性能。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">你可以使用对象池使初始化的成本达到最小。典型的例子包括数据库、网络连接和线程。这样的连接通常需要很多时间来初始化。一旦创建了这些连接，你就可以重用它们，从而极大地节省了成本。因此，你可以将初始化成本很高（从时间、内存或其它资源方面考虑）的对象放入对象池中。例如，大多数容器都将</SPAN><SPAN lang=EN-US><FONT face=Arial>EJB</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">放入对象池中，从而避免重复的资源分配和状态初始化。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>一个设计良好的对象池架构具有普遍性，它适合不同应用程序的需要。可以让你控制对象池的容量、对象填充策略和对象状态。它可以极大地提高你的应用程序的效率，不管从速度方面考虑，还是从资源利用率方面考虑，该架构都可以提供这样的好处。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在这里，给大家推荐一个开源的项目</SPAN><SPAN lang=EN-US><FONT face=Arial>Commons-Pool</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">（</SPAN><SPAN lang=EN-US><A href="http://jakarta.apache.org/commons/pool/"><FONT face=Arial color=#525252>http://jakarta.apache.org/commons/pool/</FONT></A></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">），我还没来得及研究，谁用过了，感觉好的，麻烦告诉我一下，谢谢！</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="COLOR: blue; mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>2)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>ThreadLocal</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">技术</SPAN><SPAN lang=EN-US style="COLOR: blue"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>使用此技术获取线程绑定的带状态的单例对象。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="COLOR: blue; mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">单例模式</SPAN><SPAN lang=EN-US style="COLOR: blue"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">通过单例模式或使定义对象</SPAN><SPAN lang=EN-US><FONT face=Arial>static</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">来使得对象的实例只能有一个并被其他对象所共享。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="COLOR: blue; mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>4)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">枚举常量</SPAN><SPAN lang=EN-US style="COLOR: blue"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用整数取代字符串作为枚举常量，比如</SPAN><SPAN lang=EN-US><FONT face=Arial>FEMALE</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>MALE</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">我们可以用整数</SPAN><SPAN lang=EN-US><FONT face=Arial>1</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>2</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">来替代。这样将带来速度上和内存上的优势。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="COLOR: blue; mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>5)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>SoftReference</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>WeakReference</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US style="COLOR: blue"><FONT face=Arial>PhantomReference</FONT></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">引用类</SPAN><SPAN lang=EN-US style="COLOR: blue"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">引用类的主要功能就是能够引用仍可以被垃圾收集器回收的对象。在引入引用类之前，我们只能使用强引用（</SPAN><SPAN lang=EN-US><FONT face=Arial>Strong Reference</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）。例如</SPAN><SPAN lang=EN-US><FONT face=Arial>obj</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">这个引用将引用堆中存储的一个对象，只要</SPAN><SPAN lang=EN-US><FONT face=Arial>obj</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">引用还存在，垃圾收集器就永远不会释放用来容纳该对象的存储空间。当</SPAN><SPAN lang=EN-US><FONT face=Arial>obj</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">超出范围或被显式指定为</SPAN><SPAN lang=EN-US><FONT face=Arial>null</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">时，垃圾收集器就认为没有对这个对象的其他引用，也就可以收集它了。然而还需要注意一个重要的细节：仅凭对象可以被收集并不意味着垃圾收集器的一次指定运行就能够回收它。由于各种垃圾收集算法不同，某些算法会更频繁地分析生存期较短的对象，而不是较老、生存期较长的对象。因此，一个可供收集的对象可能永远也不会被回收。如果程序在垃圾收集器释放对象之前结束，这种情况就可能会出现。因此，概括地说，你永远无法保证可供收集的对象总是会被垃圾收集器收集。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>让我们来看看一些术语和定义：</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">强可及对象（</SPAN><SPAN lang=EN-US><FONT face=Arial>Strongly Reachable</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）：可以通过强引用访问的对象。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">软可及对象（</SPAN><SPAN lang=EN-US><FONT face=Arial>Softly Reachable</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）：不是强可及对象，并且能够通过软引用访问的对象。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">弱可及对象（</SPAN><SPAN lang=EN-US><FONT face=Arial>Weakly Reachable</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）：不是强可及对象也不是软可及对象，并且能够通过弱引用访问的对象。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">虚可及对象（</SPAN><SPAN lang=EN-US><FONT face=Arial>Phantomly Reachable</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）：不是强可及对象、软可及对象，也不是弱可及对象，已经结束的，可以通过虚引用访问的对象。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">清除：将引用对象的</SPAN><SPAN lang=EN-US><FONT face=Arial>refernce</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">域设置为</SPAN><SPAN lang=EN-US><FONT face=Arial>null</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，并将引用类在堆中引用的对象声明为可结束的。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>SoftReference</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类：</SPAN><SPAN lang=EN-US><FONT face=Arial>SoftReference</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类的一个典型用途就是用于内存敏感的高速缓存。</SPAN><SPAN lang=EN-US><FONT face=Arial>SoftReference</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的原理是：在保持对对象的引用时保证在</SPAN><SPAN lang=EN-US><FONT face=Arial>JVM</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">报告内存不足情况之前清楚所有的软引用。关键之处在于，垃圾收集器在运行时可能会（也可能不会）释放软可及对象。对象是否被是否取决于垃圾收集器的算法以及垃圾收集器运行时可用的内存数量。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>WeakReference</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类：</SPAN><SPAN lang=EN-US><FONT face=Arial>WeakReference</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类的一个典型用途就是规范化映射（</SPAN><SPAN lang=EN-US><FONT face=Arial>Canonicalized Mapping</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）。另外，对于那些生存期相对较长而且重新创建的开销也不高的对象来说，弱引用也比较有用。关键之处在于，垃圾收集器运行时如果碰到了弱可及对象，将释放</SPAN><SPAN lang=EN-US><FONT face=Arial> WeakReference </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">引用的对象。然而，请注意，垃圾收集器可能要运行多次才能找到并释放弱可及对象。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 14.25pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>PhantomReference</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类：</SPAN><SPAN lang=EN-US><FONT face=Arial>PhantomReference </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类只能用于跟踪对被引用对象即将进行的收集。同样，它还能用于执行</SPAN><SPAN lang=EN-US><FONT face=Arial> pre-mortem </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">清除操作。</SPAN><SPAN lang=EN-US><FONT face=Arial> PhantomReference </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">必须与</SPAN><SPAN lang=EN-US><FONT face=Arial> ReferenceQueue </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">类一起使用。需要</SPAN><SPAN lang=EN-US><FONT face=Arial> ReferenceQueue </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">是因为它能够充当通知机制。当垃圾收集器确定了某个对象是虚可及对象时，</SPAN><SPAN lang=EN-US><FONT face=Arial> PhantomReference </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对象就被放在它的</SPAN><SPAN lang=EN-US><FONT face=Arial> ReferenceQueue </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">上。将</SPAN><SPAN lang=EN-US><FONT face=Arial> PhantomReference </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对象放在</SPAN><SPAN lang=EN-US><FONT face=Arial> ReferenceQueue </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">上也就是一个通知，表明</SPAN><SPAN lang=EN-US><FONT face=Arial> PhantomReference </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">对象引用的对象已经结束，可供收集了。这使您能够刚好在对象占用的内存被回收之前采取行动。</SPAN><SPAN lang=EN-US><FONT face=Arial> </FONT></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在某些场合引用类还是很有用的，具体可以参考文章</SPAN><SPAN lang=EN-US><FONT face=Arial>Java2</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">引用类使用指南（</SPAN><SPAN lang=EN-US><A href="http://www-128.ibm.com/developerworks/cn/java/j-refs/index.html"><FONT face=Arial color=#525252>http://www-128.ibm.com/developerworks/cn/java/j-refs/index.html</FONT></A></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">）。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="COLOR: blue; mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>6)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能少的减少不必要对象的生成</SPAN><SPAN lang=EN-US style="COLOR: blue"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">尽可能减少在循环中创建对象，使用</SPAN><SPAN lang=EN-US><FONT face=Arial>StringBuffer</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">而不要使用</SPAN><SPAN lang=EN-US><FONT face=Arial>String</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">来做连接操作等等。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="COLOR: blue; mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>7)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="COLOR: blue; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">改变对象的创建时机</SPAN><SPAN lang=EN-US style="COLOR: blue"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>通过提前创建对象或延迟到使用时再创建对象，来做到性能优化和避免创建过多的对象。<BR><BR>Tracker:http://www.blogjava.net/patrick/archive/2005/12/25/25348.aspx</FONT></SPAN></P><img src ="http://www.blogjava.net/zyb9114/aggbug/25362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-25 13:16 <a href="http://www.blogjava.net/zyb9114/articles/25362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>性能调优的基本知识和JDK调优</title><link>http://www.blogjava.net/zyb9114/articles/25361.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sun, 25 Dec 2005 05:14:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/25361.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/25361.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/25361.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/25361.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/25361.html</trackback:ping><description><![CDATA[<H1 style="MARGIN: 17pt 0cm 16.5pt"><A name=_Toc123026767><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-bidi-font-size: 22.0pt"><FONT size=4>一</FONT></SPAN></A><FONT size=4><SPAN style="mso-bookmark: _Toc123026767"><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; mso-bidi-font-size: 22.0pt"><FONT face=Arial> </FONT></SPAN></SPAN><SPAN style="mso-bookmark: _Toc123026767"><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-bidi-font-size: 22.0pt">基本知识</SPAN></SPAN><SPAN style="mso-bookmark: _Toc123026767"></SPAN><SPAN lang=EN-US style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; mso-bidi-font-size: 22.0pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></FONT></H1>
<H2 style="MARGIN: 13pt 0cm"><A name=_Toc123026768><SPAN lang=EN-US style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%"><FONT face=Arial size=4>1.1 </FONT></SPAN></A><FONT size=4><SPAN style="mso-bookmark: _Toc123026768"><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">性能是什么</SPAN></SPAN><SPAN style="mso-bookmark: _Toc123026768"></SPAN><SPAN lang=EN-US style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%"><o:p></o:p></SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在性能调优之前，我们首先来了解一下性能是什么？关于性能，我想每个学习过</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的人都能列出几点，甚至可以夸夸其谈。在《</SPAN><SPAN lang=EN-US><FONT face=Arial>Java TM Platform Performance</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">》一书中，定义了如下五个方面来作为评判性能的标准：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>1)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">运算的性能——哪一个算法的执行性能最好？</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>2)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">内存的分配——程序运行时需要耗费多少内存？</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">启动的时间——程序启动需要多长时间？这在</SPAN><SPAN lang=EN-US><FONT face=Arial>Web</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">项目中的影响不大，但要注意部分程序需要部署或运行在客户端时的情形（比如</SPAN><SPAN lang=EN-US><FONT face=Arial>applet</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">程序）。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>4)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">程序的可伸缩性——在压力负载的情况下，程序的性能如何？</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>5)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">性能的感知——用户在什么情况下会觉得程序的性能不好？</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>以上五个方面，在具体的使用场景可以有选择的去评判。至于这五方面的性能调优，在后续的章节中将会陆续的给以相应的性能调优策略。</FONT></SPAN></P>
<H2 style="MARGIN: 13pt 0cm"><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%"><FONT face=Arial>1.2 </FONT></SPAN><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调优的规则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 14pt; LINE-HEIGHT: 173%"><o:p></o:p></SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>我们只需要关心对我们程序有影响，可以察觉到的性能问题，而不是每一个类中的每一个方法我们都需要想方设法的提高性能。如果程序的性能没有达到我们所期望的要求，我们才需要考虑如何优化性能。同样的，晦涩的代码虽然提高了程序的性能，但同时可能带给我们的是维护的噩梦。我们需要折中的考虑以上两种情况，使得程序的代码是优美的，并且运行的足够快，达到客户所期望的性能要求。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">优化代码甚至会导致不良的结果，</SPAN><SPAN lang=EN-US><FONT face=Arial>Donald Knuth</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">（一位比较牛比较有影响的人物，具体是谁，我也忘了，谁知道，可以告诉我一下，谢谢！）曾说过，“</SPAN><SPAN lang=EN-US><FONT face=Arial>Premature optimization is the root of all evil”</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。在开始性能调优前，需要先指出不优化代码的一些理由。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>1)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">如果优化的代码已经正常工作，优化后可能会引入新的</SPAN><SPAN lang=EN-US><FONT face=Arial>bug</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>2)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">优化代码趋向于使代码更难理解和维护；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在一个平台上优化的代码，在另一个平台上可能更糟；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo2; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>4)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">花费很多时间在代码的优化上，提高了很少的性能，却导致了晦涩的代码。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>确实，在优化前，我们必须认真的考虑是否值得去优化。</FONT></SPAN></P>
<H2 style="MARGIN: 13pt 0cm"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>1.3 </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">调优的步骤</SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>一般我们提高应用程序的性能划分为以下几个步骤：</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l3 level1 lfo3; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>1)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">明确应用程序的性能指标，怎样才符合期望的性能需求；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l3 level1 lfo3; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>2)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">在目标平台进行测试；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l3 level1 lfo3; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">如果性能已经达到性能指标，</SPAN><SPAN lang=EN-US><FONT face=Arial>Stop</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l3 level1 lfo3; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>4)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">查找性能瓶颈；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l3 level1 lfo3; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>5)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">修改性能瓶颈；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l3 level1 lfo3; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>6)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">返回到第</SPAN><SPAN lang=EN-US><FONT face=Arial>2</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">步。</SPAN></FONT></P>
<H1 style="MARGIN: 17pt 0cm 16.5pt"><FONT size=4><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-bidi-font-size: 22.0pt">二</SPAN><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; mso-bidi-font-size: 22.0pt"><FONT face=Arial> <SPAN lang=EN-US>JDK</SPAN></FONT></SPAN><SPAN style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; FONT-FAMILY: 黑体; mso-ascii-font-family: Arial; mso-bidi-font-size: 22.0pt">调优</SPAN><SPAN lang=EN-US style="FONT-SIZE: 14pt; LINE-HEIGHT: 240%; mso-bidi-font-size: 22.0pt"><o:p></o:p></SPAN></FONT></H1>
<H2 style="MARGIN: 13pt 0cm"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>2.1 </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">选择合适的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">版本</SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">不同版本的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">，甚至不同厂家的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">可能都存在着很大的差异，对于性能优化的程度不同。一般来说，尽可能选择最新发布的稳定的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">版本。最新的稳定的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">版本相对以前的</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">版本都会做一些</SPAN><SPAN lang=EN-US><FONT face=Arial>bug</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的修改和性能的优化工作。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>2.2 </FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">垃圾收集</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆的优化</SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">垃圾收集就是自动释放不再被程序所使用的对象的过程。当一个对象不再被程序所引用时，它所引用的堆空间可以被回收，以便被后续的新对象所使用。垃圾收集器必须能够断定哪些对象是不再被引用的，并且能够把它们所占据的堆空间释放出来。如果对象不再被使用，但还有被程序所引用，这时是不能被垃圾收集器所回收的，此时就是所谓的“内存泄漏”。监控应用程序是否发生了内存泄漏，有一个非常优秀的监控工具推荐给大家——</SPAN><SPAN lang=EN-US><FONT face=Arial>Quest</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">公司的</SPAN><SPAN lang=EN-US><FONT face=Arial>JProbe</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">工具，使用它来观察程序运行期的内存变化，并可产生内存快照，从而分析并定位内存泄漏的确切位置，可以精确定位到源码内。这个工具的使用我在后续的章节中还会做具体介绍。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆是指在程序运行时分配给对象生存的空间。通过</SPAN><SPAN lang=EN-US><FONT face=Arial>-mx/-Xmx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>-ms/-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">来设置起始堆的大小和最大堆的大小。根据自己</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的版本和厂家决定使用</SPAN><SPAN lang=EN-US><FONT face=Arial>-mx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>-ms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">或</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xmx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">。</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆大小决定了垃圾回收的频度和速度，</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆越大，垃圾回收的频度越低，速度越慢。同理，</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆越小，垃圾回收的频度越高，速度越快。要想设置比较理想的参数，还是需要了解一些基础知识的。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">堆的最大值不能太大，这样会造成系统内存被频繁的交换和分页。所以最大内存必须低于物理内存减去其他应用程序和进程需要的内存。而且堆设置的太大，造成垃圾回收的时间过长，这样将得不偿失，极大的影响程序的性能。以下是一些经常使用的参数设置：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo4; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>1)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">等于</SPAN><SPAN lang=EN-US><FONT face=Arial>-XmX</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的值；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo4; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>2)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">估计内存中存活对象所占的空间的大小，设置</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">等于此值，</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xmx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">四倍于此值；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo4; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">等于</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xmx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的</SPAN><SPAN lang=EN-US><FONT face=Arial>1/2</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">大小；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo4; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>4)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">设置</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">介于</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xmx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的</SPAN><SPAN lang=EN-US><FONT face=Arial>1/10</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">到</SPAN><SPAN lang=EN-US><FONT face=Arial>1/4</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">之间；</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo4; tab-stops: list 39.0pt"><FONT size=4><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>5)</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使用默认的设置。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>大家需要根据自己的运行程序的具体使用场景，来确定最适合自己的参数设置。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=4><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">除了</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xmx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">两个最重要的参数外，还有很多可能会用到的参数，这些参数通常强烈的依赖于垃圾收集的算法，所以可能因为</SPAN><SPAN lang=EN-US><FONT face=Arial>JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">的版本和厂家而有所不同。但这些参数一般在</SPAN><SPAN lang=EN-US><FONT face=Arial>Web</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">开发中用的比较少，我就不做详细介绍了。在实际的应用中注意设置</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xms</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</SPAN><SPAN lang=EN-US><FONT face=Arial>-Xmx</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">使其尽可能的优化应用程序就行了。对于性能要求很高的程序，就需要自己再多研究研究</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">虚拟机和垃圾收集算法的机制了。可以看看曹晓钢翻译的《深入</SPAN><SPAN lang=EN-US><FONT face=Arial>Java</FONT></SPAN></FONT><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT size=4>虚拟机》一书。<BR><BR>Tracker:http://www.blogjava.net/patrick/archive/2005/12/22/25117.html</FONT></SPAN></P><img src ="http://www.blogjava.net/zyb9114/aggbug/25361.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-25 13:14 <a href="http://www.blogjava.net/zyb9114/articles/25361.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle 10g SQL 优化再学习</title><link>http://www.blogjava.net/zyb9114/articles/24129.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Fri, 16 Dec 2005 01:57:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/24129.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/24129.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/24129.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/24129.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/24129.html</trackback:ping><description><![CDATA[从8i到10g，Oracle不断进化自己的SQL Tuning智能，一些秘籍级的优化口诀已经失效。<BR>&nbsp;&nbsp;&nbsp;但我喜欢失效，不用记口诀，操个<A href="http://www.quest.com/toad/">Toad for Oracle Xpert</A>&nbsp;，按照大方向舒舒服服的调优才是爱做的事情。<BR><BR><STRONG>1.Excution Plan<BR></STRONG>&nbsp;&nbsp;&nbsp;&nbsp; Excution Plan是最基本的调优概念，不管你的调优吹得如何天花乱堕，结果还是要由Excution plan来显示Oracle 最终用什么索引、按什么顺序连接各表，Full Table Scan还是Access by Rowid Index，瓶颈在什么地方。如果没有它的指导，一切调优都是蒙的。<BR><BR><BR><STRONG>2.Toad for Oracle Xpert</STRONG><BR>&nbsp;&nbsp;&nbsp; 用它来调优在真的好舒服。<A href="http://www.quest.com/">Quest </A>吞并了Lecco后，将它整合到了Toad 的SQL Tunning里面：最清晰的执行计划显示，自动生成N条等价SQL、给出优化建议，不同SQL执行计划的对比，还有实际执行的逻辑读、物理读数据等等一目了然。<BR><BR><BR><STRONG>3.索引<BR></STRONG>&nbsp;&nbsp;&nbsp;大部分的性能问题其实都是索引应用的问题，Where子句、Order By、Group&nbsp;By 都要用到索引。<BR>&nbsp;&nbsp;&nbsp;一般开发人员认为将索引建全了就可以下班回家了，实则还有颇多的思量和陷阱。<BR><BR><STRONG>3.1 索引列上不要进行计算</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这是最最普遍的失效陷阱，比如where trunc(order_date)=trunc(sysdate), i+2&gt;4。索引失效的原因也简单，索引是针对原值建的二叉树，你将列值*3/4+2折腾一番后，原来的二叉树当然就用不上了。解决的方法:<BR>　 1.　换成等价语法，比如trunc(order_date) 换成
<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"><SPAN style="COLOR: #000000">where order_date</SPAN><SPAN style="COLOR: #808080">&gt;</SPAN><SPAN style="COLOR: #000000">trunc(sysdate)</SPAN><SPAN style="COLOR: #808080">-</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">1</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #808080">and</SPAN><SPAN style="COLOR: #000000">&nbsp;order_date</SPAN><SPAN style="COLOR: #808080">&lt;</SPAN><SPAN style="COLOR: #000000">trunc(sysdate)</SPAN><SPAN style="COLOR: #808080">+</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">1</SPAN></DIV>
<P>　&nbsp;2.&nbsp;&nbsp;&nbsp; 特别为计算建立函数索引</P>
<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"><SPAN style="COLOR: #0000ff">create</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">index</SPAN><SPAN style="COLOR: #000000">&nbsp;Ｉ_XXXX&nbsp;</SPAN><SPAN style="COLOR: #0000ff">on</SPAN><SPAN style="COLOR: #000000">&nbsp;shop_order(trunc(order_date))</SPAN></DIV>
<P>&nbsp;&nbsp;&nbsp; 3.&nbsp;&nbsp;&nbsp; 将计算从等号左边移到右边<BR>　这是针对某些无心之失的纠正，把a*2&gt;4　改为a&gt;4/2；把TO_CHAR(zip) = '94002' 改为zip = TO_NUMBER('94002');<BR><BR><STRONG>3.2 CBO与索引选择性<BR></STRONG>&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语句存在多条索引可用时，只会选择其中一条。所以索引也不是越多越好：）<BR><BR><STRONG>3.3 索引重建</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;传说中数据更新频繁导致有20%的碎片时，Oracle就会放弃这个索引。宁可信其有之下，应该时常alter index &lt;INDEXNAME&gt; rebuild一下。<BR><BR><STRONG>3.4 其他要注意的地方<BR></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不要使用Not，如goods_no != 2，要改为</P>
<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"><SPAN style="COLOR: #0000ff">where</SPAN><SPAN style="COLOR: #000000">&nbsp;goods_no</SPAN><SPAN style="COLOR: #808080">&gt;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">2</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #808080">and</SPAN><SPAN style="COLOR: #000000">&nbsp;goods_no</SPAN><SPAN style="COLOR: #808080">&lt;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">2</SPAN></DIV>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;不要使用is null&nbsp;, 如WHERE DEPT_CODE IS NOT NULL&nbsp;要改为</P>
<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"><SPAN style="COLOR: #0000ff">WHERE</SPAN><SPAN style="COLOR: #000000">&nbsp;DEPT_CODE&nbsp;</SPAN><SPAN style="COLOR: #808080">&gt;=</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">0</SPAN><SPAN style="COLOR: #000000">;</SPAN></DIV>
<P><STRONG>3.5 select 的列如果全是索引列时<BR></STRONG>&nbsp;&nbsp; 又如果没有where 条件，或者where条件全部是索引列时，Oracle 将直接从索引里获取数据而不去读真实的数据表，这样子理论上会快很多，比如</P>
<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"><SPAN style="COLOR: #0000ff">select</SPAN><SPAN style="COLOR: #000000">&nbsp;order_no,order_time&nbsp;</SPAN><SPAN style="COLOR: #0000ff">from</SPAN><SPAN style="COLOR: #000000">&nbsp;shop_order&nbsp;</SPAN><SPAN style="COLOR: #0000ff">where</SPAN><SPAN style="COLOR: #000000">&nbsp;shop_no</SPAN><SPAN style="COLOR: #808080">=</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">4</SPAN></DIV>
<P>当order_no,order_time,shop_no 这三列全为索引列时，你将看到一个和平时完全不同的执行计划。<BR><BR><STRONG>3.6 位图索引<BR></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;传说中当数据值较少，比如某些表示分类、状态的列，应该建位图索引而不是普通的二叉树索引，否则效率低下。不过看执行计划，这些位图索引鲜有被Oracle临幸的。<BR>&nbsp; <BR></P>
<P><STRONG>4.减少查询往返和查询的表</STRONG><BR>这也是很简单的大道理，程序与Oracle交互的成本极高，所以一个查询能完成的不要分开两次查，如果一个循环执行１万条查询的，怎么都快不到哪里去了。<BR><BR><STRONG>4.1 封装PL/SQL存储过程<BR></STRONG>　 最高级的做法是把循环的操作封装到PL/SQL写的存储过程里，因为存储过程都在服务端执行，所以没有数据往返的消耗。<BR></P>
<P><STRONG>4.2 封装PL/SQL内部函数<BR></STRONG>&nbsp;&nbsp;有机会，将一些查询封装到函数里，而在普通SQL里使用这些函数，同样是很有效的优化。<BR><BR><STRONG>4.3 Decode/Case<BR></STRONG>　 但存储过程也麻烦，所以有case/decode把几条条件基本相同的重复查询合并为一条的用法：</P>
<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"><SPAN style="COLOR: #0000ff">SELECT</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;</SPAN><SPAN style="COLOR: #ff00ff">COUNT</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #ff00ff">CASE</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">WHEN</SPAN><SPAN style="COLOR: #000000">&nbsp;price&nbsp;</SPAN><SPAN style="COLOR: #808080">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">13</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">THEN</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">1</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">ELSE</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">END</SPAN><SPAN style="COLOR: #000000">)&nbsp;low,<BR>&nbsp;</SPAN><SPAN style="COLOR: #ff00ff">COUNT</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #ff00ff">CASE</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">WHEN</SPAN><SPAN style="COLOR: #000000">&nbsp;price&nbsp;</SPAN><SPAN style="COLOR: #808080">BETWEEN</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">13</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #808080">AND</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">15</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">THEN</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">1</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">ELSE</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">END</SPAN><SPAN style="COLOR: #000000">)&nbsp;med,<BR>&nbsp;</SPAN><SPAN style="COLOR: #ff00ff">COUNT</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #ff00ff">CASE</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">WHEN</SPAN><SPAN style="COLOR: #000000">&nbsp;price&nbsp;</SPAN><SPAN style="COLOR: #808080">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">15</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">THEN</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">1</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">ELSE</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">END</SPAN><SPAN style="COLOR: #000000">)&nbsp;high<BR></SPAN><SPAN style="COLOR: #0000ff">FROM</SPAN><SPAN style="COLOR: #000000">&nbsp;products;</SPAN></DIV>
<P><STRONG>4.4 一种Where/Update语法</STRONG></P>
<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"><SPAN style="COLOR: #0000ff">SELECT</SPAN><SPAN style="COLOR: #000000">&nbsp;TAB_NAME　</SPAN><SPAN style="COLOR: #0000ff">FROM</SPAN><SPAN style="COLOR: #000000">&nbsp;TABLES<BR></SPAN><SPAN style="COLOR: #0000ff">WHERE</SPAN><SPAN style="COLOR: #000000">&nbsp;(TAB_NAME,DB_VER)&nbsp;</SPAN><SPAN style="COLOR: #808080">=</SPAN><SPAN style="COLOR: #000000">&nbsp;（(&nbsp;</SPAN><SPAN style="COLOR: #0000ff">SELECT</SPAN><SPAN style="COLOR: #000000">&nbsp;TAB_NAME,DB_VER)<BR></SPAN><SPAN style="COLOR: #0000ff">FROM</SPAN><SPAN style="COLOR: #000000">&nbsp;TAB_COLUMNS&nbsp;</SPAN><SPAN style="COLOR: #0000ff">WHERE</SPAN><SPAN style="COLOR: #000000">&nbsp;VERSION&nbsp;</SPAN><SPAN style="COLOR: #808080">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="FONT-WEIGHT: bold; COLOR: #800000">604</SPAN><SPAN style="COLOR: #000000">)</SPAN></DIV><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"><SPAN style="COLOR: #0000ff">UPDATE</SPAN><SPAN style="COLOR: #000000">&nbsp;EMP<BR></SPAN><SPAN style="COLOR: #0000ff">SET</SPAN><SPAN style="COLOR: #000000">&nbsp;(EMP_CAT,&nbsp;SAL_RANGE)<BR></SPAN><SPAN style="COLOR: #808080">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">SELECT</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #ff00ff">MAX</SPAN><SPAN style="COLOR: #000000">(CATEGORY)</SPAN><SPAN style="COLOR: #0000ff">FROM</SPAN><SPAN style="COLOR: #000000">&nbsp;EMP_CATEGORIES)</SPAN></DIV>
<P><STRONG><BR>5.其他优化</STRONG><BR><STRONG>5.1RowID和ROWNUM</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp; 连Hibernate 新版也支持ROWID了，证明它非常有用。比如号称删除重复数据的最快写法：</P>
<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"><SPAN style="COLOR: #0000ff">DELETE</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">FROM</SPAN><SPAN style="COLOR: #000000">&nbsp;EMP&nbsp;E<BR></SPAN><SPAN style="COLOR: #0000ff">WHERE</SPAN><SPAN style="COLOR: #000000">&nbsp;E.ROWID&nbsp;</SPAN><SPAN style="COLOR: #808080">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">SELECT</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #ff00ff">MIN</SPAN><SPAN style="COLOR: #000000">(X.ROWID)<BR></SPAN><SPAN style="COLOR: #0000ff">FROM</SPAN><SPAN style="COLOR: #000000">&nbsp;EMP&nbsp;X<BR></SPAN><SPAN style="COLOR: #0000ff">WHERE</SPAN><SPAN style="COLOR: #000000">&nbsp;X.EMP_NO&nbsp;</SPAN><SPAN style="COLOR: #808080">=</SPAN><SPAN style="COLOR: #000000">&nbsp;E.EMP_NO);</SPAN></DIV>
<P>&nbsp;</P>
<P><STRONG>6.终极秘技 - </STRONG>Hints<BR>&nbsp;&nbsp; 这是Oracle DBA的玩具，也是终极武器，比如Oracle在CBO,RBO中所做的选择总不合自己心水时，可以用它来强力调教一下Oracle，结果经常让人喜出望外。<BR>&nbsp;&nbsp; 如果开发人员没那么多时间来专门学习它，可以依靠Toad SQL opmitzer 来自动生成这些提示，然后对比一下各种提示的实际效果。不过随着10g智能的进化，hints的惊喜少了。<BR><BR><STRONG>7. 找出要优化的Top SQL<BR></STRONG>&nbsp;&nbsp;&nbsp; 磨了这么久的枪，如果找不到敌人是件郁闷的事情。<BR>&nbsp;&nbsp;&nbsp; 幸亏10g这方面做得非常好。进入Web管理界面，就能看到当前或者任意一天的SQL列表，按性能排序。<BR>&nbsp;&nbsp;&nbsp; 有了它，SQL Trace和TKPROF都可以不用了。<BR><BR>Tracker: http://www.blogjava.net/calvin/archive/2005/11/11/19276.html</P><img src ="http://www.blogjava.net/zyb9114/aggbug/24129.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-16 09:57 <a href="http://www.blogjava.net/zyb9114/articles/24129.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中文&amp;编码问题小结</title><link>http://www.blogjava.net/zyb9114/articles/23469.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Mon, 12 Dec 2005 06:20:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23469.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23469.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23469.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23469.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java字符编码转换过程说明&nbsp;&nbsp;常见问题&nbsp;&nbsp;JVMJVM启动后，JVM会设置一些系统属性以表明JVM的缺省区域。user.language,user.region,file.encoding等。 可以使用System.getProperties()详细查看所有的系统属性。&nbsp;如在英文操作系统(如UNIX...&nbsp;&nbsp;<a href='http://www.blogjava.net/zyb9114/articles/23469.html'>阅读全文</a><img src ="http://www.blogjava.net/zyb9114/aggbug/23469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-12 14:20 <a href="http://www.blogjava.net/zyb9114/articles/23469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 正则表达式</title><link>http://www.blogjava.net/zyb9114/articles/23468.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Mon, 12 Dec 2005 06:19:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23468.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23468.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23468.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23468.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23468.html</trackback:ping><description><![CDATA[<H3>目录</H3>正则表达式介绍<A HREF="/zhugf000/archive/2005/12/12/23414.html#man_match_mode"><BR>匹配模式</A><BR><A HREF="/zhugf000/archive/2005/12/12/23414.html#man_char_class">字符子集</A><BR><A HREF="/zhugf000/archive/2005/12/12/23414.html#man_line_terminator">行结束符</A><BR><A HREF="/zhugf000/archive/2005/12/12/23414.html#man_group">分组和引用</A><BR><A HREF="/zhugf000/archive/2005/12/12/23414.html#man_unicode">Unicode支持</A><BR><BR><BR><A HREF="/zhugf000/archive/2005/12/12/23414.html#reference">正则表达式语法参考</A><BR>
<OL>
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_chars">字符</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_logicopr">逻辑操作符</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_backref">向后引用</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_boundmeta">边界元字符</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_repeatindicator">重复指示符</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_char_class">字符子集</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_predef_meta">预定义子集（元字符）</A> 
<LI>扩展子集（元字符） 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_chinese_meta">扩展中文子集（元字符）</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_posix_subset">POSIX字符子集（只适用于ASCII）</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#ref_unicode_category">Unicode块和分类</A><BR></LI></OL><BR>替换表达式<BR><A HREF="/zhugf000/archive/2005/12/12/23414.html#man_subexp">替换表达式<BR></A>
<OL>
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#subexp_chars">特殊字符</A> 
<LI><A HREF="/zhugf000/archive/2005/12/12/23414.html#subexp_custtbl">自定义替换表</A><BR></LI></OL>
<HR width="100%" SIZE=2>

<H3><A name=man_match_mode></A>匹配模式</H3>匹配模式指得是正则表达式引擎将以何种模式匹配字符串。<BR>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top>模式名称<BR></TD>
<TD vAlign=top>启用，禁用<BR></TD>
<TD vAlign=top>缺省启用<BR></TD>
<TD vAlign=top>说明<BR></TD></TR>
<TR>
<TD vAlign=top>UNIX_LINES<BR></TD>
<TD vAlign=top>(?d)启用，(?-d)禁用<BR></TD>
<TD vAlign=top>是<BR></TD>
<TD vAlign=top>启用Unix行模式。<BR>在此模式下，只有 <TT>'\n'</TT>被认为是行结束符。它会影响<TT>.</TT>, <TT>^</TT>, 和 <TT>$</TT> 的行为。<BR><BR></TD></TR>
<TR>
<TD vAlign=top>CASE_INSENSITIVE<BR></TD>
<TD vAlign=top>(?i)启用，(?-i)禁用<BR></TD>
<TD vAlign=top>否<BR></TD>
<TD vAlign=top>启用忽略大小写模式。<BR>缺省时，忽略大小写模式只会影响 ASCII字符的匹配。 而Unicode范围的忽略大小写匹配需要通过 UNICODE_CASE 标志与本标志联合使用。<BR>启用此模式会影响匹配性能。<BR><BR></TD></TR>
<TR>
<TD vAlign=top>COMMENTS<BR></TD>
<TD vAlign=top>(?x)启用，(?-x)禁用<BR></TD>
<TD vAlign=top>否<BR></TD>
<TD vAlign=top>允许空格和注释出现在正则表达式中。<BR>在此模式下，空格被忽略，以#开始的单行注释被忽略。 <BR></TD></TR>
<TR>
<TD vAlign=top>MULTILINE<BR></TD>
<TD vAlign=top>(?m)启用，(?-m)禁用<BR></TD>
<TD vAlign=top>是<BR></TD>
<TD vAlign=top>启用多行模式。<BR>In multiline mode the expressions <TT>^</TT> and <TT>$</TT> match just after or just before, respectively, a line terminator or the end of the input sequence. By default these expressions only match at the beginning and the end of the entire input sequence. <BR><BR></TD></TR>
<TR>
<TD vAlign=top>DOTALL<BR></TD>
<TD vAlign=top>(?s)启用，(?-s)禁用<BR></TD>
<TD vAlign=top>否<BR></TD>
<TD vAlign=top>让.可以匹配行结束符。<BR>在此模式下，元字符<TT>.</TT>可以匹配行结束符。缺省不允许如此匹配。<BR><BR><BR></TD></TR>
<TR>
<TD vAlign=top>UNICODE_CASE<BR></TD>
<TD vAlign=top>(?u)启用，(?-u)禁用<BR></TD>
<TD vAlign=top>否<BR></TD>
<TD vAlign=top>Enables Unicode-aware case folding.<BR>When this flag is specified then case-insensitive matching, when enabled by the <CODE>CASE_INSENSITIVE</CODE> flag, is done in a manner consistent with the Unicode Standard. By default, case-insensitive matching assumes that only characters in the US-ASCII charset are being matched. 启用此模式会影响性能。<BR><BR></TD></TR>
<TR>
<TD vAlign=top>CANON_EQ<BR></TD>
<TD vAlign=top>(?c)启用，(?-c)禁用<BR></TD>
<TD vAlign=top>否<BR></TD>
<TD vAlign=top>Enables canonical equivalence.<BR>When this flag is specified then two characters will be considered to match if, and only if, their full canonical decompositions match. The expression <TT>"a\u030A"</TT>, for example, will match the string <TT>"?"</TT> when this flag is specified. By default, matching does not take canonical equivalence into account. <BR>启用此模式会影响性能。<BR><BR></TD></TR></TBODY></TABLE><BR><BR>
<H3><A name=man_char_class></A>字符子集</H3>字符子集可以含有别的字符子集，并且可以通过联合操作符（缺省）和交集操作符（&amp;&amp;）实现组合。联合操作符表示某个子集匹配它的子子集所匹配的任意字符。交集操作符表明某个字符子集只匹配它的子子集都匹配的字符。<BR>字符子集所能够有的操作符的优先级如下，从高到低：<BR>
<OL>
<LI>转义符\x 
<LI>成组符 [...] 
<LI>区间符 a-z 
<LI>联合符 [a-e][i-u] 
<LI>交集符 [a-z&amp;&amp;[aeiou]]</LI></OL>注意：在字符子集[]内部的语法根本不同于正则表达式其它部分中的语法。例如，在字符子集内部，正则表达式 . 失去了它原有的含义，而是成了一个匹配.的元字符。 <BR><BR>
<H3><A name=man_line_terminator></A>行结束符</H3>行结束符是一个或两个字符序列，用以表明输入字符序列中一行的结束。下面的字符被认为是行结束符：<BR>
<UL>
<LI>一个换行符('\n')。 
<LI>一个回车符加上一个换行符("\r\n")。 
<LI>一个单独的回车符('\r')。 
<LI>代表下一行的字符('\u0085')。 
<LI>行分隔符('\u2028')，Unicode中被定义。 
<LI>一个分段符('\u2029)，Unicode中被定义。</LI></UL>如果 UNIX_LINES 模式被启用，则只有换行符被认为是行结束符。<BR>如果 MULTILINE 模式被启用，。<BR><BR>
<H3><A name=man_group></A>分组和引用</H3>字符分组以它们的左括号的出现顺序来排序。例如在表达式((A)(B(C)))，有四个分组：<BR>
<OL>
<LI>((A)(B(C))) 
<LI>(A) 
<LI>(B(C)) 
<LI>(C)</LI></OL>第0组永远表示表达式本身。<BR>分组采用这样的命名方式，是因为，在一次匹配过程中，正则表达式会被匹配多次。以前的匹配子序列有可能在将来被使用；或者在匹配结束时，程序有可能需要重新获得所有匹配的子字符序列。<BR>对于正则表达式中的某个分组而言，永远只保留最后匹配的字符序列。如果对某个分组匹配尝试失败，则会保留上次匹配成功的字符序列。例如，对于正则表达式(a(b)?)+而言，字符序列"aba"，将会让分组2匹配的字符序列为"b"。<BR>以(?开始的分组，将不会计入分组数目，也不会被后续匹配所引用。<BR><BR>
<H3><A name=man_unicode></A>Unicode支持</H3>本正则表达式匹配引擎的实现遵循了《<A href="http://www.unicode.org/unicode/reports/tr18/">Unicode技术报告：Unicode正则表达式指南</A>》，实现了该指南的第二层所需的功能，但是在细微处有一些简单语法修改。<BR>Unicode块(Block)和分类(Category)通过\p和\P通配苻表示。\p{<B><I>prop</I></B>}匹配含有<B><I>prop</I></B>的输入序列，而\P{<B><I>prop</I></B>}匹配不含有<B><I>prop</I></B>的输入序列。Unicode块通过前缀<TT>In</TT>表示，如\p{InMongolian}。Unicode分类通过可选的前缀Is表示，因此\p{L}和\p{IsL}都代表Unicode分类 letters。Unicode块和分类都可以在正则表达式子集外部和内部使用。<BR>目前支持的Unicode块和分类是《<A href="http://www.unicode.org/unicode/standard/standard.html">Unicode标准，第三版</A>》中所指定的块和分类。 Unicode块名称在《<A href="http://www.unicode.org/Public/3.0-Update/UnicodeCharacterDatabase-3.0.0.html">Unicode 字符数据库</A>》的第14章被定义，文件名称叫<A href="http://www.unicode.org/Public/3.0-Update/Blocks-3.txt">Blocks-3.txt</A>，但是名称中的空格被去掉了。例如"Basic Latin"成了"BasicLatin"。无论是标准化的还是非标准化的分类，都在该标准的第88页的第4-5表中被全部定义。<BR><BR>
<H3><A name=man_compare_perl5></A>与Perl 5正则表达式语法对比 </H3>[TBD]<BR><BR>
<HR width="100%" SIZE=2>

<H2><A name=reference></A>正则表达式参考</H2><BR>
<HR width="100%" SIZE=2>

<H3><A name=ref_chars></A>字符</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">正则表达式字符串<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">X<BR></TD>
<TD vAlign=top>字符X，包括 CJK ExtB 区汉字<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\\<BR></TD>
<TD vAlign=top>反斜杠\<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\0<B><I>n</I></B> </TD>
<TD vAlign=top>八进制0<B><I>n</I></B>代表的字符(0&lt;=n&lt;=7)<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\0<B><I>nn</I></B><BR></TD>
<TD vAlign=top>八进制0<B><I>nn</I></B>代表的字符(0&lt;=n&lt;=7)<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\0<B><I>mnn</I></B><BR></TD>
<TD vAlign=top>八进制0<B><I>mnn</I></B>代表的字符(0&lt;=m&lt;=3,0&lt;=n&lt;=7)<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\x<B><I>hh</I></B><BR></TD>
<TD vAlign=top>十六进制 0x<B><I>hh</I></B>所代表的字符<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\u<B><I>hhhh</I></B><BR></TD>
<TD vAlign=top>十六进制 0x<B><I>hhhh</I></B>所代表的字符。<FONT color=#ff0000>注意</FONT>，目前尚不支持CJK ExtB区汉字。<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\t<BR></TD>
<TD vAlign=top>制表符('\u0009')<BR></TD></TR>
<TR>
<TD vAlign=top>\n<BR></TD>
<TD vAlign=top>换行('\u000A')<BR></TD></TR>
<TR>
<TD vAlign=top>\r<BR></TD>
<TD vAlign=top>回车('\u000D')<BR></TD></TR>
<TR>
<TD vAlign=top>\a<BR></TD>
<TD vAlign=top>响铃符('\u0007')<BR></TD></TR>
<TR>
<TD vAlign=top>\e<BR></TD>
<TD vAlign=top>取消符Escape('\001B')<BR></TD></TR>
<TR>
<TD vAlign=top>\c<I><B>x</B></I><BR></TD>
<TD vAlign=top><I><B>x</B></I>所代表的控制字符<BR></TD></TR></TBODY></TABLE><BR>
<H3><A name=ref_logicopr></A>逻辑操作符</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">正则表达式字符串<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><I>XY</I><BR></TD>
<TD vAlign=top><I>X</I>后面跟随<I>Y</I><BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><I>X</I>|<I>Y</I><BR></TD>
<TD vAlign=top><I>X</I>或者<I>Y</I><BR></TD></TR>
<TR>
<TD vAlign=top width="30%">(<I>X</I>)<BR></TD>
<TD vAlign=top><I>X</I>作为分组表达式<BR></TD></TR></TBODY></TABLE><BR>
<H3><A name=ref_backref></A>向后引用</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">正则表达式字符串<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\<B>n</B><BR></TD>
<TD vAlign=top>第<B>n</B>个匹配的分组<BR></TD></TR></TBODY></TABLE><BR>
<H3><A name=ref_boundmeta></A>边界元字符</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">边界字符<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">^<BR></TD>
<TD vAlign=top>行首<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">$<BR></TD>
<TD vAlign=top>行末<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\b </TD>
<TD vAlign=top>字符边界<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\B<BR></TD>
<TD vAlign=top>非字符边界<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\A<BR></TD>
<TD vAlign=top>输入流的开始<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\G<BR></TD>
<TD vAlign=top>上次匹配的结束处<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\Z<BR></TD>
<TD vAlign=top>输入流的结束，或者是最后一个行结束符，参见<A href="file:///D:/source/jtextpro/src/dist/jtextpro/docs/regexp.html#man_line_terminator">行结束符</A>。<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\z<BR></TD>
<TD vAlign=top>输入流的结束<BR></TD></TR></TBODY></TABLE><BR>
<H3><A name=ref_repeatindicator></A>重复指示符</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">正则表达式字符串<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><B>X</B>?<BR></TD>
<TD vAlign=top><B>X</B>重复一次，或者不重复<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><B>X</B>*<BR></TD>
<TD vAlign=top><B>X</B>重复0次或多次<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><B>X</B>+ <BR></TD>
<TD vAlign=top><B>X</B>重复1次或多次<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><B>X</B>{n}<BR></TD>
<TD vAlign=top><B>X</B>重复n次，不多也不少。<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><B>X</B>{n,}<BR></TD>
<TD vAlign=top><B>X</B>至少重复n次<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><B>X</B>{n,m}<BR></TD>
<TD vAlign=top><B>X</B>至少重复n次，至多重复m次。<BR></TD></TR></TBODY></TABLE>注：<B>X</B>{n,m}、?、*、+方式可以联合使用。<BR><BR>
<H3><A name=ref_char_class></A>字符子集</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">正则表达式字符串子集<BR></TD>
<TD vAlign=top width="50%">匹配的字符串<BR></TD>
<TD vAlign=top align=left width="20%">组合方式<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">[abc]<BR></TD>
<TD vAlign=top width="60%">字符a,b或c，包括 CJK ExtB 区汉字<BR></TD>
<TD vAlign=top align=left width="20%">简单子集<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">[^abc]<BR></TD>
<TD vAlign=top width="60%">任意非a,b或c的字符。<BR></TD>
<TD vAlign=top align=left width="20%">排除<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">[a-zA-Z] </TD>
<TD vAlign=top width="60%">从a到z，或者A到Z，包含a,z,A,Z。<BR></TD>
<TD vAlign=top align=left width="20%">区间<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">[a-d[m-p]]<BR></TD>
<TD vAlign=top width="60%">从a到d，或者m到p，等于[a-dm-p]。<BR></TD>
<TD vAlign=top align=left width="20%">联合<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">[a-z&amp;&amp;[def]]<BR></TD>
<TD vAlign=top width="60%">d,e或者f。<BR></TD>
<TD vAlign=top align=left width="20%">交集<BR></TD></TR>
<TR>
<TD vAlign=top>[a-z&amp;&amp;[^bc]]<BR></TD>
<TD vAlign=top width="60%">从a到z，除了b和c，等于[ad-z]<BR></TD>
<TD vAlign=top align=left width="20%">扣除<BR></TD></TR>
<TR>
<TD vAlign=top>[a-z&amp;&amp;[^m-p]]<BR></TD>
<TD vAlign=top>从a到z，并且不包括从m到p，等于[a-lq-z]<BR></TD>
<TD vAlign=top>扣除<BR></TD></TR></TBODY></TABLE><BR>
<H3><A name=ref_predef_meta></A>预定义子集（元字符）</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">边界字符<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">.<BR></TD>
<TD vAlign=top>任意字符，可能匹配行结束符。<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\d<BR></TD>
<TD vAlign=top>数字[0-9]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\D </TD>
<TD vAlign=top>非数字[^0-9]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\s<BR></TD>
<TD vAlign=top>空白符[ \t\n\x0B\f\r]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\S<BR></TD>
<TD vAlign=top>非空白符[^\s]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\w<BR></TD>
<TD vAlign=top>单词符，包含有字母和数字[a-zA-Z_0-9]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\W<BR></TD>
<TD vAlign=top>非单词符，不包含有字母和数字。<BR></TD></TR></TBODY></TABLE><BR>
<H3>扩展子集（元字符）</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">正则表达式字符串<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%"><BR></TD>
<TD vAlign=top><BR></TD></TR></TBODY></TABLE><BR><BR>
<H3><A name=ref_chinese_meta></A>扩展中文子集（元字符）</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top>名称<BR></TD>
<TD vAlign=top>块名称（\p{InXXX}）<BR></TD>
<TD vAlign=top>简化通配符<BR></TD>
<TD vAlign=top>标准Unicode块，或者汉字列表<BR></TD></TR>
<TR>
<TD vAlign=top>任意双字节字符（汉字或全角符号）<BR></TD>
<TD vAlign=top>\p{InQuqnJiao}<BR></TD>
<TD vAlign=top>\E<BR></TD>
<TD vAlign=top>任意由GBK表示的汉字，不包括GB18030扩展部分，<BR>以及CJK ExtB区的汉字。<BR></TD></TR>
<TR>
<TD vAlign=top>任意单字节字符<BR></TD>
<TD vAlign=top>\p{InFQuanJiao}<BR></TD>
<TD vAlign=top>\~E<BR></TD>
<TD vAlign=top>任意单字节字符。<BR></TD></TR>
<TR>
<TD vAlign=top>任意全角ASCII字符<BR></TD>
<TD vAlign=top>\p{InQJAscii}<BR></TD>
<TD vAlign=top>\H<BR></TD>
<TD vAlign=top>标准HalfwidthandFullwidthForms块<BR></TD></TR>
<TR>
<TD vAlign=top>任意收录在BIG5码集中的双字节字符<BR></TD>
<TD vAlign=top>\p{InBig5}<BR></TD>
<TD vAlign=top>\I<BR></TD>
<TD vAlign=top>Big5可编码双字节字符<BR></TD></TR>
<TR>
<TD vAlign=top>匹配未收录在BIG5码集中的双字节字符</TD>
<TD vAlign=top>\p{InFBig5}<BR></TD>
<TD vAlign=top>\~I<BR></TD>
<TD vAlign=top>非Big5可编码双字节字符<BR></TD></TR>
<TR>
<TD vAlign=top>匹配任意汉字(不包括符号)<BR></TD>
<TD vAlign=top>\p{InHanziOrCJKExtB}<BR></TD>
<TD vAlign=top>\X<BR></TD>
<TD vAlign=top>任意汉字，包括GB18030扩展部分。<BR></TD></TR>
<TR>
<TD vAlign=top>匹配任意汉字(不包括符号)<BR></TD>
<TD vAlign=top>\p{InHanzi}<BR></TD>
<TD vAlign=top>\M<BR></TD>
<TD vAlign=top>任意汉字，不包括GB18030扩展部分。<BR></TD></TR>
<TR>
<TD vAlign=top>匹配非汉字的双字节字符<BR></TD>
<TD vAlign=top>\p{InFHanzi}<BR></TD>
<TD vAlign=top>\~M<BR></TD>
<TD vAlign=top>任意非汉字的双字节字符，<BR>包括GB18030扩展部分。<BR></TD></TR>
<TR>
<TD vAlign=top>地支字符<BR></TD>
<TD vAlign=top>\p{InDiZhi}<BR></TD>
<TD vAlign=top>\U<BR></TD>
<TD vAlign=top>子丑寅卯辰巳午未申酉戌亥<BR></TD></TR>
<TR>
<TD vAlign=top>匹配收录在GB码集中的双字节字符<BR></TD>
<TD vAlign=top>\p{InGB}<BR></TD>
<TD vAlign=top>\g<BR></TD>
<TD vAlign=top>收录在GB码集中的双字节字符，<BR>不包括GB18030扩展部分。<BR></TD></TR>
<TR>
<TD vAlign=top>匹配非收录在GB码集中的双字节字符<BR></TD>
<TD vAlign=top>\p{InFGB}<BR></TD>
<TD vAlign=top>\~g<BR></TD>
<TD vAlign=top>未收录在GB码集中的双字节字符，<BR>不包括GB18030扩展部分。<BR></TD></TR>
<TR>
<TD vAlign=top>匹配收录在GBK码集中的双字节字符<BR></TD>
<TD vAlign=top>\p{InGBK}<BR></TD>
<TD vAlign=top>\h<BR></TD>
<TD vAlign=top>收录在GBK码集中的双字节字符，<BR>不包括GB18030扩展部分。<BR></TD></TR>
<TR>
<TD vAlign=top>匹配非收录在GBK码集中的双字节字符<BR></TD>
<TD vAlign=top>\p{InFGBK}<BR></TD>
<TD vAlign=top>\~h<BR></TD>
<TD vAlign=top>未收录在GBK码集中的双字节字符，<BR>不包括GB18030扩展部分。<BR></TD></TR>
<TR>
<TD vAlign=top>大写希腊字母<BR></TD>
<TD vAlign=top>\p{InDaXila}<BR></TD>
<TD vAlign=top>\K<BR></TD>
<TD vAlign=top>ΑΒΓΔΕΖΗΘΙΚΛΜΝ<BR>ΞΟΠΡΣΤΥΦΧΨΩ<BR></TD></TR>
<TR>
<TD vAlign=top>日文片假名<BR></TD>
<TD vAlign=top>\p{InPianJia}<BR></TD>
<TD vAlign=top>\j<BR></TD>
<TD vAlign=top>标准Katakana块<BR></TD></TR>
<TR>
<TD vAlign=top>日文平假名<BR></TD>
<TD vAlign=top>\p{InPingJia}<BR></TD>
<TD vAlign=top>\J<BR></TD>
<TD vAlign=top>标准Hiragana块<BR></TD></TR>
<TR>
<TD vAlign=top>小写希腊字母<BR></TD>
<TD vAlign=top>\p{InXiaoXila}<BR></TD>
<TD vAlign=top>\k<BR></TD>
<TD vAlign=top>αβγδεζηθικλμν<BR>ξοπρστυφχψω<BR></TD></TR>
<TR>
<TD vAlign=top>数学符号<BR></TD>
<TD vAlign=top>\p{InMathe}<BR></TD>
<TD vAlign=top>\m<BR></TD>
<TD vAlign=top>±×÷∶∧∨∑∏∪∩∈∷√⊥∥∠⌒⊙<BR>∫∮≡≌≈∽∝≠≮≯≤≥∞∵∴<BR></TD></TR>
<TR>
<TD vAlign=top>中文数字<BR></TD>
<TD vAlign=top>\p{InCnDigit}<BR></TD>
<TD vAlign=top>\i<BR></TD>
<TD vAlign=top>〇一二三四五六七八九十百千万亿兆吉京<BR></TD></TR>
<TR>
<TD vAlign=top>大写中文数字<BR></TD>
<TD vAlign=top>\p{InDaCnDigit}<BR></TD>
<TD vAlign=top>\N<BR></TD>
<TD vAlign=top>零壹贰叁肆伍陆柒捌玖拾佰仟萬亿兆吉京<BR></TD></TR>
<TR>
<TD vAlign=top>全角标点符号<BR></TD>
<TD vAlign=top>\p{InQJBiaoDian}<BR></TD>
<TD vAlign=top>\o<BR></TD>
<TD vAlign=top>、。·ˉˇ¨〃々—～‖…‘’“”〔〕<BR>〈〉《》「」『』〖〗【】！＂＇（），<BR>－．：；＜＝＞？［］｛｜｝｀﹉﹊﹋﹌﹍﹎﹏﹐﹑﹒﹔﹕﹖﹗﹙﹚<BR>﹛﹜﹝﹞︵︶︹︺︿﹀︽︾﹁﹂﹃﹄<BR>︻︼︷︸︱︳︴<BR></TD></TR>
<TR>
<TD vAlign=top>小写俄文字母<BR></TD>
<TD vAlign=top>\p{InXiaoEWen}<BR></TD>
<TD vAlign=top>\l<BR></TD>
<TD vAlign=top>абвгдеёжзийклмн<BR>опрстуфхцчшщъыьэюя<BR></TD></TR>
<TR>
<TD vAlign=top>大写俄文字母<BR></TD>
<TD vAlign=top>\p{InDaEWen}<BR></TD>
<TD vAlign=top>\R<BR></TD>
<TD vAlign=top>АБВГДЕЁЖЗИЙКЛМНО<BR>ПРСТУФХЦЧШЩЪЫЬЭЮЯ<BR></TD></TR>
<TR>
<TD vAlign=top>中文序号<BR></TD>
<TD vAlign=top>\p{InCnSN}<BR></TD>
<TD vAlign=top>\q<BR></TD>
<TD vAlign=top>ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ<BR>ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ<BR>再加上Unicode标准EnclosedAlphanumerics块<BR></TD></TR>
<TR>
<TD vAlign=top>天干字符<BR></TD>
<TD vAlign=top>\p{InTianGan}<BR></TD>
<TD vAlign=top>\T<BR></TD>
<TD vAlign=top>甲乙丙丁戊己庚辛壬癸<BR></TD></TR>
<TR>
<TD vAlign=top>竖排标点符号<BR></TD>
<TD vAlign=top>\p{InSPBiaoDian}<BR></TD>
<TD vAlign=top>\V<BR></TD>
<TD vAlign=top>︵︶︹︺︿﹀︽︾﹁﹂﹃﹄︻︼︷︸︱︳︴<BR></TD></TR>
<TR>
<TD vAlign=top>拼音字符<BR></TD>
<TD vAlign=top>\p{InPinyin}<BR></TD>
<TD vAlign=top>\y<BR></TD>
<TD vAlign=top>āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜüêɑńňɡ<BR>GBK -&gt; 0xA8A1- 0xA8C0<BR>只是Unicode标准LatinExtended-A块的一部分。<BR></TD></TR>
<TR>
<TD vAlign=top>注音字符<BR></TD>
<TD vAlign=top>\p{InZhuyin}<BR></TD>
<TD vAlign=top>\Y<BR></TD>
<TD vAlign=top>标准Bopomofo块<BR></TD></TR>
<TR>
<TD vAlign=top>制表字符<BR></TD>
<TD vAlign=top>\p{InZhiBiao}<BR></TD>
<TD vAlign=top>\C<BR></TD>
<TD vAlign=top>标准BoxDrawing块。<BR>经检查发现 textpro 的算法含有部分非标<BR>准Unicode制表符：“∟∣≒≦≧⊿═”。<BR></TD></TR></TBODY></TABLE><BR>
<H3><A name=ref_posix_subset></A>POSIX字符子集（只适用于ASCII）</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">正则表达式字符串<BR></TD>
<TD vAlign=top>匹配的字符串<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{Lower}<BR></TD>
<TD vAlign=top>小写字母[a-z]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{Upper}<BR></TD>
<TD vAlign=top>大写字母[A-Z]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{ASCII}<BR></TD>
<TD vAlign=top>所有的ASCII字符[\x00-\x7F]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{Alpha}<BR></TD>
<TD vAlign=top>大小写字母[\p{Lower}\p{Upper}]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{Digit}<BR></TD>
<TD vAlign=top>数字[0-9]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{Alnum}<BR></TD>
<TD vAlign=top>字母数字符，包含大小写字母和数字[\p{Alpha}\p{Digit}]<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{Punct}<BR></TD>
<TD vAlign=top>标点符号，!"#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~之一。<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\p{Graph}<BR></TD>
<TD vAlign=top>可显示字符[\p{Alnum}\p{Punct}]<BR></TD></TR>
<TR>
<TD vAlign=top>\p{Print}<BR></TD>
<TD vAlign=top>可打印字符[\p{Graph}]<BR></TD></TR>
<TR>
<TD vAlign=top>\p{Blank}<BR></TD>
<TD vAlign=top>空格或者制表符[ \t]<BR></TD></TR>
<TR>
<TD vAlign=top>\p{Cntrl}<BR></TD>
<TD vAlign=top>控制字符[\x00-\x1F\x7F<BR></TD></TR>
<TR>
<TD vAlign=top>\p{XDigit}<BR></TD>
<TD vAlign=top>十六进制数字[0-9a-fA-F]<BR></TD></TR>
<TR>
<TD vAlign=top>\p{Space}<BR></TD>
<TD vAlign=top>空白符[ \t\n\x0B\f\r]<BR></TD></TR></TBODY></TABLE><BR>
<H3><A name=ref_unicode_category></A>Unicode块和分类</H3>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top>块<BR></TD>
<TD vAlign=top>中文名称（摘自Word XP）<BR></TD>
<TD vAlign=top>代码区域<BR></TD></TR>
<TR>
<TD vAlign=top>BasicLatin<BR></TD>
<TD vAlign=top>基本拉丁语<BR></TD>
<TD vAlign=top>\u0000-\u007F<BR></TD></TR>
<TR>
<TD vAlign=top>Latin-1Supplement<BR></TD>
<TD vAlign=top>拉丁语-1<BR></TD>
<TD vAlign=top>\u0080-\u00FF<BR></TD></TR>
<TR>
<TD vAlign=top>LatinExtended-A<BR></TD>
<TD vAlign=top>拉丁语扩充-A<BR></TD>
<TD vAlign=top>\u0100-\u017F<BR></TD></TR>
<TR>
<TD vAlign=top>LatinExtended-Bound<BR></TD>
<TD vAlign=top>拉丁语扩充-B<BR></TD>
<TD vAlign=top>\u0180-\u024F<BR></TD></TR>
<TR>
<TD vAlign=top>IPAExtensions<BR></TD>
<TD vAlign=top>国际音标扩充<BR></TD>
<TD vAlign=top>\u0250-\u02AF<BR></TD></TR>
<TR>
<TD vAlign=top>SpacingModifierLetters<BR></TD>
<TD vAlign=top>进格的修饰字符<BR></TD>
<TD vAlign=top>\u02B0-\u02FF<BR></TD></TR>
<TR>
<TD vAlign=top>CombiningDiacriticalMarks<BR></TD>
<TD vAlign=top>组合用发音符<BR></TD>
<TD vAlign=top>\u0300-\u036F<BR></TD></TR>
<TR>
<TD vAlign=top>Greek<BR></TD>
<TD vAlign=top>基本希腊语<BR></TD>
<TD vAlign=top>\u0370-\u03FF<BR></TD></TR>
<TR>
<TD vAlign=top>Cyrillic<BR></TD>
<TD vAlign=top>西里尔语<BR></TD>
<TD vAlign=top>\u0400-\u04FF<BR></TD></TR>
<TR>
<TD vAlign=top>Armenian<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0530-\u058F<BR></TD></TR>
<TR>
<TD vAlign=top>Hebrew<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0590-\u05FF<BR></TD></TR>
<TR>
<TD vAlign=top>Arabic<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0600-\u06FF<BR></TD></TR>
<TR>
<TD vAlign=top>Syriac<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0700-\u074F<BR></TD></TR>
<TR>
<TD vAlign=top>Thaana<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0780-\u07BF<BR></TD></TR>
<TR>
<TD vAlign=top>Devanagari<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0900-\u097F<BR></TD></TR>
<TR>
<TD vAlign=top>Bengali<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0980-\u09FF<BR></TD></TR>
<TR>
<TD vAlign=top>Gurmukhi<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0A00-\u0A7F<BR></TD></TR>
<TR>
<TD vAlign=top>Gujarati<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0A80-\u0AFF<BR></TD></TR>
<TR>
<TD vAlign=top>Oriya<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0B00-\u0B7F<BR></TD></TR>
<TR>
<TD vAlign=top>Tamil<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0B80-\u0BFF<BR></TD></TR>
<TR>
<TD vAlign=top>Telugu<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0C00-\u0C7F<BR></TD></TR>
<TR>
<TD vAlign=top>Kannada<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0C80-\u0CFF<BR></TD></TR>
<TR>
<TD vAlign=top>Malayalam<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0D00-\u0D7F<BR></TD></TR>
<TR>
<TD vAlign=top>Sinhala<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0D800-\uDFF<BR></TD></TR>
<TR>
<TD vAlign=top>Thai<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0E00-\u0E7F<BR></TD></TR>
<TR>
<TD vAlign=top>Lao<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u0E80-\u0EFF<BR></TD></TR>
<TR>
<TD vAlign=top>Tibetan<BR></TD>
<TD vAlign=top>藏语<BR></TD>
<TD vAlign=top>\u0F00-\u0FFF<BR></TD></TR>
<TR>
<TD vAlign=top>Myanmar<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1000-\u109F<BR></TD></TR>
<TR>
<TD vAlign=top>Georgian<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u10A0-\u10FF<BR></TD></TR>
<TR>
<TD vAlign=top>HangulJamo<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1100-\u11FF<BR></TD></TR>
<TR>
<TD vAlign=top>Ethiopic<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1200-\u137F<BR></TD></TR>
<TR>
<TD vAlign=top>Cherokee<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u13A0-\u13FF<BR></TD></TR>
<TR>
<TD vAlign=top>UnifiedCanadianAboriginalSyllabics<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1400-\u167F<BR></TD></TR>
<TR>
<TD vAlign=top>Ogham<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1680-\u169F<BR></TD></TR>
<TR>
<TD vAlign=top>Runic<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u16A0-\u16FF<BR></TD></TR>
<TR>
<TD vAlign=top>Khmer<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1780-\u17FF<BR></TD></TR>
<TR>
<TD vAlign=top>Mongolian<BR></TD>
<TD vAlign=top>蒙古语<BR></TD>
<TD vAlign=top>\u1800-\u18AF<BR></TD></TR>
<TR>
<TD vAlign=top>LatinExtendedAdditional<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1E00-\u1EFF<BR></TD></TR>
<TR>
<TD vAlign=top>GreekExtended<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u1F00-\u1FFF<BR></TD></TR>
<TR>
<TD vAlign=top>GeneralPunctuation<BR></TD>
<TD vAlign=top>广义标点<BR></TD>
<TD vAlign=top>\u2000-\u206F<BR></TD></TR>
<TR>
<TD vAlign=top>SuperscriptsandSubscripts<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2070-\u209F<BR></TD></TR>
<TR>
<TD vAlign=top>CurrencySymbols<BR></TD>
<TD vAlign=top>货币符号<BR></TD>
<TD vAlign=top>\u20A0-\u20CF<BR></TD></TR>
<TR>
<TD vAlign=top>CombiningMarksforSymbols<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u20D0-\u20FF<BR></TD></TR>
<TR>
<TD vAlign=top>LetterlikeSymbols<BR></TD>
<TD vAlign=top>类似字母的符号<BR></TD>
<TD vAlign=top>\u2100-\u214F<BR></TD></TR>
<TR>
<TD vAlign=top>NumberForms<BR></TD>
<TD vAlign=top>数字形式<BR></TD>
<TD vAlign=top>\u2150-\u218F<BR></TD></TR>
<TR>
<TD vAlign=top>Arrows<BR></TD>
<TD vAlign=top>箭头<BR></TD>
<TD vAlign=top>\u2190-\u21FF<BR></TD></TR>
<TR>
<TD vAlign=top>MathematicalOperators<BR></TD>
<TD vAlign=top>数学运算符<BR></TD>
<TD vAlign=top>\u2200-\u22FF<BR></TD></TR>
<TR>
<TD vAlign=top>MiscellaneousTechnical<BR></TD>
<TD vAlign=top>零杂技术用符号<BR></TD>
<TD vAlign=top>\u2300-\u23FF<BR></TD></TR>
<TR>
<TD vAlign=top>ControlPictures<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2400-\u243F<BR></TD></TR>
<TR>
<TD vAlign=top>OpticalCharacterRecognition<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2440-\u245F<BR></TD></TR>
<TR>
<TD vAlign=top>EnclosedAlphanumerics<BR></TD>
<TD vAlign=top>带括号的字母数字<BR></TD>
<TD vAlign=top>\u2460-\u24FF<BR></TD></TR>
<TR>
<TD vAlign=top>BoxDrawing<BR></TD>
<TD vAlign=top>制表符<BR></TD>
<TD vAlign=top>\u2500-\u257F<BR></TD></TR>
<TR>
<TD vAlign=top>BlockElements<BR></TD>
<TD vAlign=top>方块图形<BR></TD>
<TD vAlign=top>\u2580-\u259F<BR></TD></TR>
<TR>
<TD vAlign=top>GeometricShapes<BR></TD>
<TD vAlign=top>几何图形<BR></TD>
<TD vAlign=top>\u25A0-\u25FF<BR></TD></TR>
<TR>
<TD vAlign=top>MiscellaneousSymbols<BR></TD>
<TD vAlign=top>零杂丁贝符（示意符等）<BR></TD>
<TD vAlign=top>\u2600-\u26FF<BR></TD></TR>
<TR>
<TD vAlign=top>Dingbats<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2700-\u27BF<BR></TD></TR>
<TR>
<TD vAlign=top>BraillePatterns<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2800-\u28FF<BR></TD></TR>
<TR>
<TD vAlign=top>CJKRadicalsSupplement<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2E80-\u2EFF<BR></TD></TR>
<TR>
<TD vAlign=top>KangxiRadicals<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2F00-\u2FDF<BR></TD></TR>
<TR>
<TD vAlign=top>IdeographicDescriptionCharacters<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u2FF0-\u2FFF<BR></TD></TR>
<TR>
<TD vAlign=top>CJKSymbolsandPunctuation<BR></TD>
<TD vAlign=top>CJK符号和标点<BR></TD>
<TD vAlign=top>\u3000-\u303F<BR></TD></TR>
<TR>
<TD vAlign=top>Hiragana<BR></TD>
<TD vAlign=top>平假名<BR></TD>
<TD vAlign=top>\u3040-\u309F<BR></TD></TR>
<TR>
<TD vAlign=top>Katakana<BR></TD>
<TD vAlign=top>片假名<BR></TD>
<TD vAlign=top>\u30A0-\u30FF<BR></TD></TR>
<TR>
<TD vAlign=top>Bopomofo<BR></TD>
<TD vAlign=top>注音<BR></TD>
<TD vAlign=top>\u3100-\u312F<BR></TD></TR>
<TR>
<TD vAlign=top>HangulCompatibilityJamo<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u3130-\u318F<BR></TD></TR>
<TR>
<TD vAlign=top>Kanbun<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\u3190-\u319F<BR></TD></TR>
<TR>
<TD vAlign=top>BopomofoExtended<BR></TD>
<TD vAlign=top>扩展注音<BR></TD>
<TD vAlign=top>\u31A0-\u31BF<BR></TD></TR>
<TR>
<TD vAlign=top>EnclosedCJKLettersandMonths<BR></TD>
<TD vAlign=top>带括号的CJK字母及月份<BR></TD>
<TD vAlign=top>\u3200-\u32FF<BR></TD></TR>
<TR>
<TD vAlign=top>CJKCompatibility<BR></TD>
<TD vAlign=top>CJK兼容字符<BR></TD>
<TD vAlign=top>\u3300-\u33FF <BR></TD></TR>
<TR>
<TD vAlign=top>CJKUnifiedIdeographsExtensionA<BR></TD>
<TD vAlign=top>CJK统一汉字扩展-A<BR></TD>
<TD vAlign=top>\u3400-\u4dBF<BR></TD></TR>
<TR>
<TD vAlign=top>CJKUnifiedIdeographs<BR></TD>
<TD vAlign=top>CJK统一汉字<BR></TD>
<TD vAlign=top>\u4E00-\u9fAF<BR></TD></TR>
<TR>
<TD vAlign=top>YiSyllables<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uA000-\uA48F<BR></TD></TR>
<TR>
<TD vAlign=top>YiRadicals<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uA490-\uA4CF<BR></TD></TR>
<TR>
<TD vAlign=top>HangulSyllables<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uAC00-\uD7A3<BR></TD></TR>
<TR>
<TD vAlign=top>HighSurrogates<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uD800-\uDB7F<BR></TD></TR>
<TR>
<TD vAlign=top>HighPrivateUseSurrogates<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uDB80-\uDBFF<BR></TD></TR>
<TR>
<TD vAlign=top>LowSurrogates<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uDC00-\uDFFF<BR></TD></TR>
<TR>
<TD vAlign=top>PrivateUse<BR></TD>
<TD vAlign=top>专用区<BR></TD>
<TD vAlign=top>\uE000-\uF8FF<BR></TD></TR>
<TR>
<TD vAlign=top>CJKCompatibilityIdeographs<BR></TD>
<TD vAlign=top>CJK兼容汉字<BR></TD>
<TD vAlign=top>\uF900-\uFAFF<BR></TD></TR>
<TR>
<TD vAlign=top>AlphabeticPresentationForms<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uFB00-\uFB4F<BR></TD></TR>
<TR>
<TD vAlign=top>ArabicPresentationForms-A<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uFB50-\uFDFF<BR></TD></TR>
<TR>
<TD vAlign=top>CombiningHalfMarks<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uFE20-\uFE2F<BR></TD></TR>
<TR>
<TD vAlign=top>CJKCompatibilityForms<BR></TD>
<TD vAlign=top>CJK兼容形式<BR></TD>
<TD vAlign=top>\uFE30-\uFE4F<BR></TD></TR>
<TR>
<TD vAlign=top>SmallFormVariants<BR></TD>
<TD vAlign=top>小写变体<BR></TD>
<TD vAlign=top>\uFE50-\uFE6F<BR></TD></TR>
<TR>
<TD vAlign=top>ArabicPresentationForms-Bound<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uFE70-\ufeFF<BR></TD></TR>
<TR>
<TD vAlign=top>Specials<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>\uFFF0-\uFFFF<BR></TD></TR>
<TR>
<TD vAlign=top>HalfwidthandFullwidthForms<BR></TD>
<TD vAlign=top>半形及全形字符<BR></TD>
<TD vAlign=top>\uFF00-\uFFEF<BR></TD></TR></TBODY></TABLE><BR><BR>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top>分类<BR></TD>
<TD vAlign=top>全称<BR></TD>
<TD vAlign=top>说明<BR></TD></TR>
<TR>
<TD vAlign=top>Cn<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>UNASSIGNED<BR></TD></TR>
<TR>
<TD vAlign=top>Lu<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>UPPERCASE_LETTER<BR></TD></TR>
<TR>
<TD vAlign=top>Ll<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>LOWERCASE_LETTER<BR></TD></TR>
<TR>
<TD vAlign=top>Lt<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>TITLECASE_LETTER<BR></TD></TR>
<TR>
<TD vAlign=top>Lm<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>MODIFIER_LETTER<BR></TD></TR>
<TR>
<TD vAlign=top>Lo<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>OTHER_LETTER<BR></TD></TR>
<TR>
<TD vAlign=top>Mn<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>NON_SPACING_MARK<BR></TD></TR>
<TR>
<TD vAlign=top>Me<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>ENCLOSING_MARK<BR></TD></TR>
<TR>
<TD vAlign=top>Mc<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>COMBINING_SPACING_MARK<BR></TD></TR>
<TR>
<TD vAlign=top>Nd<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>DECIMAL_DIGIT_NUMBER<BR></TD></TR>
<TR>
<TD vAlign=top>Nl<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>LETTER_NUMBER<BR></TD></TR>
<TR>
<TD vAlign=top>No<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>OTHER_NUMBER<BR></TD></TR>
<TR>
<TD vAlign=top>Zs<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>SPACE_SEPARATOR<BR></TD></TR>
<TR>
<TD vAlign=top>Zl<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>LINE_SEPARATOR<BR></TD></TR>
<TR>
<TD vAlign=top>Zp<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>PARAGRAPH_SEPARATOR<BR></TD></TR>
<TR>
<TD vAlign=top>Cc<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>CNTRL<BR></TD></TR>
<TR>
<TD vAlign=top>Cf<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>FORMAT<BR></TD></TR>
<TR>
<TD vAlign=top>Co<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>PRIVATE_USE<BR></TD></TR>
<TR>
<TD vAlign=top>Cs<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>SURROGATE<BR></TD></TR>
<TR>
<TD vAlign=top>Pd<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>DASH_PUNCTUATION<BR></TD></TR>
<TR>
<TD vAlign=top>Ps<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>START_PUNCTUATION<BR></TD></TR>
<TR>
<TD vAlign=top>Pe<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>END_PUNCTUATION<BR></TD></TR>
<TR>
<TD vAlign=top>Pc<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>CONNECTOR_PUNCTUATION<BR></TD></TR>
<TR>
<TD vAlign=top>Po<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>OTHER_PUNCTUATION<BR></TD></TR>
<TR>
<TD vAlign=top>Sm<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>MATH_SYMBOL<BR></TD></TR>
<TR>
<TD vAlign=top>Sc<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>CURRENCY_SYMBOL<BR></TD></TR>
<TR>
<TD vAlign=top>Sk<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>MODIFIER_SYMBOL<BR></TD></TR>
<TR>
<TD vAlign=top>So<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>OTHER_SYMBOL<BR></TD></TR>
<TR>
<TD vAlign=top>L<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>LETTER<BR></TD></TR>
<TR>
<TD vAlign=top>M<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>MARK<BR></TD></TR>
<TR>
<TD vAlign=top>N<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>NUMBER<BR></TD></TR>
<TR>
<TD vAlign=top>Z<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>SEPARATOR<BR></TD></TR>
<TR>
<TD vAlign=top>C<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>CONTROL<BR></TD></TR>
<TR>
<TD vAlign=top>P<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>PUNCTUATION<BR></TD></TR>
<TR>
<TD vAlign=top>S<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>SYMBOL</TD></TR>
<TR>
<TD vAlign=top>LD<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>LETTER_OR_DIGIT<BR></TD></TR>
<TR>
<TD vAlign=top>L1<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>Latin-1<BR></TD></TR>
<TR>
<TD vAlign=top>all<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>ALL<BR></TD></TR>
<TR>
<TD vAlign=top>ASCII<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>ASCII<BR></TD></TR>
<TR>
<TD vAlign=top>Alnum<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>字母数字(0-9,a-z,A-Z)<BR></TD></TR>
<TR>
<TD vAlign=top>Alpha<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>字母(a-z,A-Z)<BR></TD></TR>
<TR>
<TD vAlign=top>Blank<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>空格和制表符(' '|\t)<BR></TD></TR>
<TR>
<TD vAlign=top>Cntrl<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>控制字符，不可打印<BR></TD></TR>
<TR>
<TD vAlign=top>Digit<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>数字(0-9)<BR></TD></TR>
<TR>
<TD vAlign=top>Graph<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>可打印且可视字母（例如空格' '是可打印的但不是可视字母，而 `a' 两者都是。）<BR></TD></TR>
<TR>
<TD vAlign=top>Lower<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>小写字母<BR></TD></TR>
<TR>
<TD vAlign=top>Print<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>可打印字母（非控制字符）<BR></TD></TR>
<TR>
<TD vAlign=top>Punct<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>标符号（字母、数字、控制、空白符以外的字母），如：!@#$%}{&lt;&gt;,./?[]等等。<BR></TD></TR>
<TR>
<TD vAlign=top>Space<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>空白符(' ',\t,0x09,0x0A,0x0B,0x0C,0x0D,0x20)<BR></TD></TR>
<TR>
<TD vAlign=top>Upper<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>大写字母<BR></TD></TR>
<TR>
<TD vAlign=top>XDigit<BR></TD>
<TD vAlign=top><BR></TD>
<TD vAlign=top>十六进制数字(0-9，a-f, A-F)<BR></TD></TR></TBODY></TABLE><BR>
<HR width="100%" SIZE=2>
<BR><BR><BR>
<H3><A name=man_subexp></A>替换表达式</H3><A name=subexp_chars></A>特殊字符<BR>
<TABLE cellSpacing=2 cellPadding=2 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="30%">特殊字符介绍<BR></TD>
<TD vAlign=top>描述<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\n<BR></TD>
<TD vAlign=top>换行<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\b<BR></TD>
<TD vAlign=top>向前删除一个字符。当这个字符位于替换串之首时，将删除匹配串之前的一个字符。若匹配串位于行首，将使匹配串所在行与前一行相合并。<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\d<BR></TD>
<TD vAlign=top>向后删除一个字符。当这个字符位于替换串之末时，将删除匹配串之后的一个字符。若匹配串位于行末，将使匹配串所在行与下一行相合并。<BR></TD></TR>
<TR>
<TD vAlign=top width="30%">\e<BR></TD>
<TD vAlign=top>插入一个ESC字符<BR></TD></TR>
<TR>
<TD vAlign=top>\t<BR></TD>
<TD vAlign=top>插入一个TAB字符<BR></TD></TR>
<TR>
<TD vAlign=top>\<I><B>n</B></I><BR></TD>
<TD vAlign=top>n代表查找正则表达式中的子表达式（组）。\1代表第一个子表达式，\2代表第二个子表达式，依次类推。\0代表整个匹配到的字符串。<BR></TD></TR>
<TR>
<TD vAlign=top>\v<BR></TD>
<TD vAlign=top>大写下一个字母<BR></TD></TR>
<TR>
<TD vAlign=top>\U<BR></TD>
<TD vAlign=top>全部大写以后的字母，直到碰到其它指示符为止。<BR></TD></TR>
<TR>
<TD vAlign=top>\l<BR></TD>
<TD vAlign=top>小写下一个字母<BR></TD></TR>
<TR>
<TD vAlign=top>\L<BR></TD>
<TD vAlign=top>全部小写以后的字母，直到碰到其它指示符为止。<BR></TD></TR>
<TR>
<TD vAlign=top>\E<BR></TD>
<TD vAlign=top>取消所有的字母大小写指示符。<BR></TD></TR></TBODY></TABLE><BR><BR><A name=subexp_custtbl></A>自定义替换表<BR><BR>在查找／替换中使用自定义替换表 <BR>有的时候，上述简单的自定义替换功能是不够的。例如，用户可能希望只把出现在括号内的源串替换为目标串。这种文本处理可以通过在查找/替换中使用自定义替换表来解决。 <BR><BR>在查找/替换功能中使用自定义替换表的替换函数是\Tn，其中n是0-9的数字， 注意n为0表示第10张替换表。如果略去n，其效果相当于\T1，即使用第一张替换表。例如要把所有放在方括号中的汉字替换为拼音，可以查找“\[(\E)\]”，替换为“\T{\1}”。即把第一个子表达式的匹配内容按自定义替换表转换。注意，如果\T函数的参数不在替换表的源串中，\T函数的结果与源串相同，即不做任何变换。 <BR><BR>有些情况下，用户可能希望只使用替换表的一部分内容。还是以拼音为例，前面给出的替换表中包含了拼音的音调，如果在替换时不希望加上这些音调数字，可以使用“过滤”功能。所谓过滤，其实是用一个正则表达式去分析替换表的目标串，并把其中的某个子表达式取出来。 <BR><BR>使用“过滤”时，在“设置自定义替换表”对话框中，点“过滤”按钮，在弹出的对话框中填入一个正则表达式。再以拼音为例，表达式可以写为“(\p{Alpha}+)(\d)”，其中第一对括号中的是不含音调的拼音，第二对括号是音调。在调用\T函数时，JTextPro会在目标串中查找这个正则表达式。但是如何把其中的子表达式取出来呢？\T函数还有一个可选的下标，取第n个子表达式的值就写作\T{...}[n]。所以，把放在方括号中的汉字替换为不带调的拼音，可以查找“\[(\E)\]”，替换为“\T{\1}[1]”<BR><BR>Tracker:http://www.blogjava.net/zhugf000/archive/2005/12/12/23414.html<img src ="http://www.blogjava.net/zyb9114/aggbug/23468.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-12 14:19 <a href="http://www.blogjava.net/zyb9114/articles/23468.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AJAX技术汇总</title><link>http://www.blogjava.net/zyb9114/articles/23357.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sun, 11 Dec 2005 08:15:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23357.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23357.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23357.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23357.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23357.html</trackback:ping><description><![CDATA[<SPAN class=top11>&nbsp;
<P>AJAX全称为“Asynchronous JavaScript and XML”（异步JavaScript和XML），是指一种创建交互式网页应用的网页开发技术。它有机地包含了以下几种技术： 
<P>Ajax（Asynchronous JavaScript + XML）的定义</P>
<P>基于web标准（standards-based presentation）XHTML+CSS的表示； <BR><BR>使用 DOM（Document Object Model）进行动态显示及交互； <BR><BR>使用 XML 和 XSLT 进行数据交换及相关操作； <BR><BR>使用 XMLHttpRequest 进行异步数据查询、检索； <BR><BR>使用 JavaScript 将所有的东西绑定在一起。<BR><BR>类似于DHTML或LAMP，AJAX不是指一种单一的技术，而是有机地利用了一系列相关的技术。事实上，一些基于AJAX的“派生/合成”式（derivative/composite）的技术正在出现，如“AFLAX”。</P>
<P>AJAX的应用使用支持以上技术的web浏览器作为运行平台。这些浏览器目前包括：Mozilla、Firefox、Internet Explorer、Opera、Konqueror及Safari。但是Opera不支持XSL格式对象，也不支持XSLT。[1]</P>
<P><STRONG>与传统的web应用比较</STRONG></P>
<P>传统的web应用允许用户填写表单(form)，当提交表单时就向web服务器发送一个请求。服务器接收并处理传来的表单，然后返回一个新的网页。这个做法浪费了许多带宽，因为在前后两个页面中的大部分HTML代码往往是相同的。由于每次应用的交互都需要向服务器发送请求，应用的响应时间就依赖于服务器的响应时间。这导致了用户界面的响应比本地应用慢得多。</P>
<P>与此不同，AJAX应用可以仅向服务器发送并取回必需的数据，它使用SOAP或其它一些基于XML的web service接口，并在客户端采用JavaScript处理来自服务器的响应。因为在服务器和浏览器之间交换的数据大量减少，结果我们就能看到响应更快的应用。同时很多的处理工作可以在发出请求的客户端机器上完成，所以Web服务器的处理时间也减少了。<BR><BR><IMG height=455 hspace=5 src="http://www.51cto.com/files/uploadimg/20051123/0952450.png" width=475 align=baseline><BR><BR>传统web应用与AJAX应用的比较：处理用户交互</P>
<P><IMG class="" height=598 hspace=5 src="http://www.51cto.com/files/uploadimg/20051123/0952451.png" width=475 align=baseline><BR class="">传统web应用与AJAX应用的比较：交互模式</P>
<P><SPAN class=top11><STRONG>微软的Ajax</STRONG> </P>
<P></P>
<P>微软目前目前对于通过Ajax风格的编程在浏览器中实现日益流行的富客户端应用比较感兴趣。今后的IE中将拥有Ajax的所有东西——DHTML、JScript和XmlHttp。实际上Outlook Web Acces从1998年开始就已经提供了这种伟大的浏览体验了。在ASP.NET 2.0中，微软使用异步回调及舒适的Ajax风格的应用程序的编写更加简单，并且，微软为此提供了内建的控件。</P>
<P>最近，几乎所有的浏览器都提供了Ajax所需的技术，使用这种模式的富客户端应用程序也不断出现。今天，世界上出现了不计其数的Ajax风格的站点，包括Google的很多站点、A9和Flickr。微软的很多站点也使用了这项技术，如Start.com和MSN虚拟地球。</P>
<P>Ajax的风行说明用户对于丰富的Web体验的需求日益增长。然而，开发和调试Ajax风格的Web应用程序是一项非常艰难的工作。要编写一个丰富的Web UI，开发者需要详细地掌握DHTML和JavaScript，并且还要掌握各种浏览器之间在设计细节上的不同。然而没有那些工具能够简化这些应用程序的设计和开发。最后，调试和测试这些应用程序会变得异常困难。</P>
<P>微软致力于简化Ajax风格Web应用的开发，并提供丰富的、可交互的和个性化的用户体验。开发者可以对客户端脚本不甚了解；但他们可以很容易地开发和调试这种应用程序。</P>
<P>出于这一目的，微软启动了一个新的项目，研发代号“Atlas”。Atlas为开发这带来了如下特性：<BR class="">·Atlas客户端脚本框架<BR class="">·Atlas的ASP.NET服务器控件<BR class="">·ASP.NET Web Services集成<BR class="">·Atlas的ASP.NET构建块<BR class="">·客户端构建块服务</P>
<P>你可能会问的一个问题是，Atlas如何在Avalon和智能客户端上使用？</P>
<P>我们可以看到，Atlas是编写丰富的、可交互的和个性化的Web浏览器应用程序的最好方式。而Avalon是微软的下一代表现层模型，可以在Windows平台上提供最丰富的用户体验。Avalon将使用最新的媒体集成功能和硬件加速设备，提供卓越的视觉体验。Avalon将带来超越浏览器的体验。</P>
<P>当然，当你构建Avalon应用程序的时候，你依然可以重用ASP.NET和Atlas中的编程模型。例如，Avalon客户端上依然可以使用ASP.NET构建块服务和客户端构建块服务。这种模型可以使你平滑地过渡到下一代应用程序上。</P>
<P>微软提供了一个工具包，用来完成Ajax的功能，称作Atlas。从微软的Scott Guthrie的blog上看来，这个东西应该是ASP.NET 2.0里面的。Scott肯定地表示，“Atlas客户端脚本框架（Client Script Framework）可以运行在所有的现代浏览器上并且何以与任何Web服务器交互”，这说明他们正在以跨浏览器的态度来开发Ajax风格的远程脚本，这无疑是一个巨大的转变；过去的微软，把任何东西都搞成了特定于IE的，而一旦其开发工具能够真的提供彻底的跨浏览器支持，将能够笼络更多的ASP.ENT开发者，他们无需了解任何细节就可以创建跨浏览器代码。</P>
<P>Atlas客户端脚本框架是可扩展的，100%面向对象的JavaScript客户端脚本框架，允许开发这很容易地构建拥有丰富的UI工能并且可以连接Web Services的Ajax风格浏览器应用程序。使用Atlas，开发者可以使用DHTML、JavaScript和XMLHTTP来编写Web应用程序，而无须掌握这些技术的细节。</P>
<P>Atlas客户端脚本框架可以在所有的现代浏览器上运行，而不需要Web服务器。它还完全不需要安装，只要在页面中引用正确的脚本文件即可。</P>
<P>Atlas客户端脚本框架包含下列组件：<BR class="">·一个可扩展的和新框架，其中为JavaScript添加了很多新特性，如生存期管理、集成、多播事件处理器和接口<BR class="">·一个基础类库，提供了通用特性，如丰富的字符串操作功能、计时器和运行任务等<BR class="">·一个UI框架，可以跨浏览器实现动态行为<BR class="">·一个网络栈，用于简化对服务器的连接和对Web Services的访问<BR class="">微软为ASP.NET应用程序专门设计了一组Ajax风格的服务器控件，并且加强了现有的ASP.NET页面框架和控件，以便支持Atlas客户端脚本框架。<BR class="">ASP.NET 2.0中有一项称作异步客户端回调的新特性，使得构建无中断的页面变得很容易。异步客户端回调包装了XMLHTTP，能够在很多浏览器上工作。ASP.NET本身包括了很多使用回调的控件，包括具有客户端分页和排序功能的GridView和DetalsView控件，以及TreeView空间的虚拟列表支持。<BR class="">Atlas客户端脚本框架将完全支持ASP.NET 2.0回调，但微软希望进一步增强浏览器和服务器之间的集成性。例如，你可以将Atlas客户端控件的数据绑定指定为服务器上的ASP.NET数据源控件，并且可以从客户端异步地控制Web页面的个性化特征。</P>
<P>和任何客户端应用程序一样，一个Ajax风格的Web应用程序通常也需要访问Web服务器的一些功能。Atlas应用程序连接服务器的模型和其他平台类似，都是使用Web Services来实现。</P>
<P>通过ASP.NET Web Services集成，Atlas应用程序将可以在任何支持XMLHTTP的浏览器上通过Atlas客户端将本框架来直接访问任何宿主于ASP.NET的asmx或Indigo服务。该框架将会自动处理代理和脚本到对象、对象到脚本的序列化问题。通过使用Web Services集成，开发者可以使用单一的编程模型来编写Web Services，并且在任何应用程序中使用它们，不论是基于浏览器的站点上还是智能客户端应用程序中。</P>
<P>在ASP.NET 2.0中，微软构建了一组丰富的构建块服务（Building Block Services），这使得构建强大、个性化的Web应用程序变得不可思议的简单。这些构建块极大地降低了在开发通用的Web应用程序过程中需要编写的代码数量，比如管理用户、通过角色验证用户和存储用户的个性化设置信息等。</P>
<P>使用Atlas，我们可以在任何浏览器上的任何客户端应用程序中向访问Web Services那样访问这些功能。例如，如果你正在开发一个站点，来显示用户的TO-DO项目，你可以使用ASP.NET的Profile服务来将他们存放在服务器上的用户自定义配置文件中。这样即使用户从一台机器上转移到另一台机器上，也同样可以访问这些项目。</P>
<P>微软将提供的服务包括（全部是基于ASP.NET 2.0的）：<BR class="">- Profile：在服务器上存放每个用户特有的数据<BR class="">- UI个性化：在服务器上存放个性化的UI设置信息<BR class="">- 验证：验证用户<BR class="">- 角色：基于用户的角色验证用户任务和提供不同的UI<BR class="">由于这些构建块是服务器端的，开发者需要对他们应用和其他站点一样的安全模型。这些服务不需要客户端下在任何东西——只要在浏览器中引用脚本代理即可。所有的ASP.NET 2.0构建块服务都是可插拔的，这使用一种通用的提供者模型可扩展模式在后台实现。微软提供的内建提供程序允许开发这使用SQL Server数据库或Active Directory作为存储容器，开发者也可以很容易地插接自己的提供程序。例如，你可能希望使用集群而不是数据库服务器来存放用户的配置文件，这时你只需将你的提供程序插接近来即可。</P>
<P>除了DHTML、JScript和XMLHTTP，微软还提供了一组附加的服务来加强客户端的功能并提供增强的体验。对于这样的服务，本地浏览器缓存就是一个很好的例子。当启用了本地浏览器缓存时，Web站点就可以将内容存储到患从中，并在需要的时候很快地取出。但浏览器并未提供向缓存中存放数据的API，而且象Google Map或OWA这样的应用程序不得不通过很多工作产生一个唯一的URL才能使浏览器缓存它。在Atlas中，微软提供了可编程的本地存储/缓存，因此应用程序可以很方便、有效并且安全在本地缓存数据。</P>
<P>同其他应用程序的集成是检验Web体验是否丰富的另一个新的标准。例如，当一个用户浏览一个拍卖网站并对一件商品出价时，他可能想随时知道这个拍卖什么时候结束，但他如何才能将这个事件添加到他们个人的日历程序中？Atlas带来了一系列客户端构建块服务，当用于选择“添加到日历”时，浏览器将调用接驳点来获取日历数据，并将其传递到本地的日历程序中。此时页面上无须下载或运行任何特殊的代码或执行任何初始化动作，因此，这比ActiveX要安全得多。<BR><BR><SPAN class=top11><STRONG>基于Ajax的应用程序架构</STRONG> </P>
<P></P>
<P>浏览器端框架被划分成两大类：</P>
<P>·应用程序框架：提供浏览器的功能，但是常以包括窗口小部件抽象和另外的部件而出名，其功能主要围绕桌面GUI框架。</P>
<P>·基本结构框架：提供基本的管道和可移植的浏览器抽象，让开发者去创建内容。典型的功能：</P>
<P>* 针对XMLHttpRequest的包装器以封装浏览器-服务器的交互。(所有的框架都提供这一功能)。</P>
<P>* XML操作和查询。</P>
<P>* 根据来自XMLHttpRequest的应答执行DOM操作。</P>
<P>* 在一些情况中，与另外的浏览器端技术如Flash(和潜在的Java applets)集成在一起。</P>
<P>而服务器端框架通常以下面两种方式工作(尽管它们在这里根据语言的不同进行了分类)：</P>
<P>·HTML/JS生成：服务器提供完整的HTML/Javascript代码生成和浏览器-服务器协调，结果是只有浏览器端编码可以被定制。</P>
<P>·远程调用：Javascript调用直接被路由到服务器端功能(例如Java方法)并返回到Javascript回叫处理器；或者Javascript调用服务器以提取信息，例如会话细节，数据库查询等。</P>
<P><STRONG>1 纯Javascript：应用程序框架</STRONG></P>
<P>1.1 Bindows(自从2003年)</P>
<P>网址是：<A href="http://www.bindows.net/">http://www.bindows.net</A>，Bindows是一个软件开发包(SDK)，它，通过强力联合DHTML，JavaScript，CSS和XML等技术，能生成高度交互的互联网应用程序-成为现代的桌面应用程序的强有力对手。Bindows应用程序不要求下载和也不需要在用户端安装-仅要求有一个浏览器(也不需要Java，Flash或者ActiveX)。Bindows有可能领导面向对象开发的AJAX应用程序的平台。</P>
<P>·它是商业化的，使用来自于MB的技术(总部位于GA USA，主要开发中心在瑞典，成立于2002年)。</P>
<P>Bindows框架提供给你：</P>
<P>·基于类的面向对象的API</P>
<P>·一套完整的窗口系统，提供宽范围的窗口小部件支持，包括菜单、表单、格子、滑动条、量程，甚至更多</P>
<P>·用于开发zero-footprint SOA客户端应用程序的领先的工具箱</P>
<P>·本机的XML，SOAP和XML-RPC支持</P>
<P>·单用户到企业级的支持</P>
<P>·内建的对AJAX的支持</P>
<P>Bindows开发环境：</P>
<P>·支持企业级规模的工程开发</P>
<P>·跨浏览器，跨平台支持</P>
<P>·服务器独立结构</P>
<P>·与新的和现有资源的互操作性</P>
<P>·一致性开发方法学</P>
<P>1.2 BackBase(自从2003年)</P>
<P>网址是：<A href="http://www.backbase.com/">http://www.backbase.com</A>，是一个全面的浏览器端框架，支持丰富的浏览器功能以及与.NET和Java的集成。</P>
<P>·商业化，来自于Backbase B.V(总部在Amsterdam，成立于2003年)。</P>
<P>1.3 DOJO(开发中;自从2004年9月)</P>
<P>网址是：<A href="http://dojotoolkit.org/">http://dojotoolkit.org/</A>，提供全面窗口小组件和浏览器-服务器消息支持。</P>
<P>·为创建定制的Javascript窗口小组件提供框架支持。 </P>
<P>·预置的窗口小组件库。</P>
<P>·浏览器-服务器消息支持-XMLHttpRequest和另外的机制。</P>
<P>·支持浏览器中的URL操纵功能。</P>
<P>·开源许可(学术自由许可2.1(<A href="http://opensource.org/licenses/afl-2.1.php">http://opensource.org/licenses/afl-2.1.php</A>))，由JotSpot(<A href="http://www.jot.com/">http://www.jot.com/</A>)的Alex Russell(<A href="http://alex.dojotoolkit.org/">http://alex.dojotoolkit.org/</A>)所领导。</P>
<P>1.4 Open Rico(开发中;自从2005年5月;基于早期的私有框架)</P>
<P>网址是：<A href="http://openrico.org/demos.page">http://openrico.org/demos.page</A>，是一多用途框架，支持Ajax基础结构和用户交互。</P>
<P>·一个XMLHttpRequest应答能被路由到一个或者更多回叫操作，DOM对象，或者Javascript对象。</P>
<P>·容易鼠标拖动支持。</P>
<P>·Ajax动画，例如缩放和变换。</P>
<P>·"行为"-实质上是窗口小组件库。</P>
<P>·使用指南(<A href="http://www.mirimar.net/mailbrowser/">http://www.mirimar.net/mailbrowser/</A>)，由RussMirimar的Yonah所提供</P>
<P>·开源。源于Sabre航空公司解决方案，由Bill Scott(<A href="http://looksgoodworkswell.blogspot.com/">http://looksgoodworkswell.blogspot.com</A>)，Darren James及另外一些人所支持。</P>
<P>1.5 qooxdoo(开发中;自从2005年5月)</P>
<P>网址是：<A href="http://qooxdoo.sourceforge.net/">http://qooxdoo.sourceforge.net/</A>，是另一个雄心勃勃的框架，提供宽范围的UI支持和正在开发中的基础结构特性。</P>
<P>·基础结构：</P>
<P>* DOM和事件/焦点管理的可移植的抽象。</P>
<P>* 调试支持。</P>
<P>* 易于时间调度的Timer类。 </P>
<P>* Getter/Setter支持。</P>
<P>·UI：</P>
<P>* 窗口小组件框架和预置的窗口小组件库。</P>
<P>* 布局管理器。</P>
<P>* 图像缓冲和可移植的PNG透明性。</P>
<P>·开源(LGPL)。来自多方面的贡献者。</P>
<P>1.6 Tibet(开发中;自从2005年6月)</P>
<P>网址是：<A href="http://www.technicalpursuit.com/">http://www.technicalpursuit.com/</A>，目的是提供高度可移植的和全面的Javascript API，结果是，可能自动生成大量的客户端代码。自称是"企业级Ajax"。</P>
<P>·远程脚本运行在XMLHttpRequest包装之上-通过协调调用结果支持工作流管理，例如应答可以发生在只有当两个分离的调用返回时。</P>
<P>·URI支持。</P>
<P>·所有的HTTP方法-不仅是"GET"和"POST"。</P>
<P>·低级的协议-File://和WebDav以及HTTP。</P>
<P>·Web服务调用-SOAP，XML-RPC，等等。</P>
<P>·预置的针对Google API，Amazon API等等服务的支持。</P>
<P>·由高级Javascript对象组成一个巨大的库。</P>
<P>·许多XML操作。</P>
<P>·IDE和开发工具。</P>
<P>·开源许可(显然经过OSI认证，但是细节不多)。<BR><BR><SPAN class=top11><STRONG>2 纯Javascript：基础结构框架</STRONG> </P>
<P></P>
<P>2.1 AjaxCaller(Alpha版本;自从5月2005年)</P>
<P>网址是：<A href="http://ajaxify.com/run/testAjaxCaller/">http://ajaxify.com/run/testAjaxCaller/</A>，是一基本的线程安全的XMLHttpRequest包装器，主要针对Ajax新手，仍处于原始的alpha开发阶段，目前仅与AjaxPatterns的在线搜索范例一起打包。</P>
<P>·实现对服务器的调用(GET/POST/PUT/DELETE)，用路由到一个回叫操作的plain-text或者XML完成。</P>
<P>·使用过的XMLHttpRequest对象的析构。</P>
<P>·Response缓冲(计划的)。</P>
<P>·针对Ajax新手-并非强调性能优化，该库主要用于实现易读的基础代码并将提供调试支持。</P>
<P>·开源许可。由Michael Mahemoff(<A href="http://softwareas.com/">http://softwareas.com</A>)(具有John Wehr和Richard Schwartz的一些思想)维护。</P>
<P>2.2 Flash JavaScript集成包</P>
<P>网址是：<A href="http://www.osflash.org/doku.php?id=flashjs">http://www.osflash.org/doku.php?id=flashjs</A>，允许JavaScript和Flash内容的集成：</P>
<P>·使JavaScript能够调用ActionScript功能和反过来的实现。</P>
<P>·所有主要的数据类型能在这两种环境之间传递。</P>
<P>·开源许可。由多个开源Flash贡献者提供支持。</P>
<P>2.3 Google AJAXSLT(发行于2005年6月)</P>
<P>网址是：<A href="http://goog-ajaxslt.sourceforge.net/">http://goog-ajaxslt.sourceforge.net/</A>，是一个Javascript框架，用来执行XSLT转换以及XPath查询。</P>
<P>·建立在Google地图工作基础之上。</P>
<P>·开源许可(BSD)。由一家创新搜索方案公司支持，自称为"Google"。</P>
<P>2.4 HTMLHttpRequest(Beta版；始于2005年)</P>
<P>HtmlHttpRequest(<A href="http://www.twinhelix.com/javascript/htmlhttprequest/">http://www.twinhelix.com/javascript/htmlhttprequest/</A>)，它使用了XMLHttpRequest和Iframes以改进兼容性。</P>
<P>·测试过并能工作在:IE6/Win，IE5.5/Win，IE5/Win，IE4/Win，Mozilla/Win，Opera7/Win，Safari/Mac，IE5/Mac。</P>
<P>·未测试，可能能工作在：IE4/Mac，Mozilla/Mac，Opera/Other，Konqueror/Linux。你正在使用这些之一吗？作者正在请求兼容性信息。</P>
<P>·开源许可(LGPL)。由Twin Helix Designs(<A href="http://www.twinhelix.com/">http://www.twinhelix.com/</A>)的Angus Turnbull维护。</P>
<P>2.5 交互式网站框架(自从2005年5月)</P>
<P>交互式网站框架(<A href="http://sourceforge.net/projects/iwf/">http://sourceforge.net/projects/iwf/</A>，是一个项目，目的是从浏览器端对Ajax基础结构的多方面予以支持。自描述为"使用javascript，css，xml，和html来创造高度交互网站的框架。包括一个定制的针对高度可读的javascript的xml分析器。实质上，是建立基于AJAX的网站的基础，还有另外一些通用脚本"。</P>
<P>·线程安全的XMLHttpRequest实现。</P>
<P>·针对XML文档的包装器，以便你能够创建更具可读性的代码：</P>
<P>var node = doc.groceries.frozen[0].pizza[0].size;&lt;/pre&gt;</P>
<P>代替手工的导航：</P>
<P>var node = doc.documentElement.firstChild.firstChild.getAttribute("size");&lt;/pre&gt;</P>
<P>·开源许可。由Weaver(<A href="http://circaware.com|brock/">http://circaware.com|Brock</A>)维护。</P>
<P>2.6 LibXMLHttpRequest(发行于2003年6月)</P>
<P>libXmlRequest(<A href="http://www.whitefrost.com/servlet/connector?file=reference/2003/06/17/libXmlRequest.html">http://www.whitefrost.com/servlet/connector?file=reference/2003/06/17/libXmlRequest.html</A>)，是XMLHttpRequest的一个瘦包装器。</P>
<P>·getXML()和postXML()方法。</P>
<P>·XMLHttpRequest对象池支持。</P>
<P>·Response缓冲。</P>
<P>·可用源码(明显)，但是受标准版权的保护，由Stephen W.Coate(<A href="http://www.whitefrost.com/index.jsp">http://www.whitefrost.com/index.jsp</A>)所维护。</P>
<P>2.7 RSLite(x)</P>
<P>网站是：<A href="http://www.ashleyit.com/rs/main.htm">http://www.ashleyit.com/rs/main.htm</A>，是一个针对XMLHttpRequest的瘦包装器。</P>
<P>·一个简单的组件，作为Brent Ashley的更全面的远程脚本工作(参见Javascript远程脚本-JSRS在多语言服务器端)的一部分发行。</P>
<P>2.8 Sack(在开发中，自从2005年5月)</P>
<P>网站是：<A href="http://twilightuniverse.com/2005/05/sack-of-ajax/">http://twilightuniverse.com/2005/05/sack-of-ajax/</A>，是一个针对XMLHttpRequest的瘦包装器。</P>
<P>·调用者能指定回叫函数或者回叫DOM对象。借助于回叫DOM，应答文本直接被推入到DOM中</P>
<P>2.9 Sarissa(发行于2月，2003年)</P>
<P>网站是：<A href="http://sarissa.sf.net/">http://sarissa.sf.net</A>，是一种Javascript API，它封装了在浏览器端可以独立调用XML的功能。</P>
<P>·可移植的XMLHttpRequest创建</P>
<P>·可移植的XPath查询</P>
<P>·可移植的DOM操作</P>
<P>·可移植的XSLT</P>
<P>·可移植的XML串行化</P>
<P>·开源(GPL2.0和LGPL2.1)。来自多方面贡献者。</P>
<P>2.10 XHConn(发行于自从4月，2005年)</P>
<P>网站是：<A href="http://xkr.us/code/javascript/XHConn/">http://xkr.us/code/javascript/XHConn/</A>，是一个对XMLHttpRequest的瘦包装器。</P>
<P>·例如</P>
<P>ew XHConn().connect("mypage.php"，"POST"，"foo=bar&amp;baz=qux"，fnWhenDone);</P>
<P>·开源许可。由Brad Fults所维护。<BR><BR><SPAN class=top11><STRONG>3 服务器端：多种语言</STRONG> </P>
<P></P>
<P>3.1 跨平台异步的接口工具箱(5月2005年)</P>
<P>CPAINT：<A href="http://cpaint.sourceforge.net/">http://cpaint.sourceforge.net/</A>，是一真正的支持PHP和ASP/Vbscript的Ajax实现和JSRS(JavaScript远程脚本)实现。CPAINT提供给你需求的代码在后台实现AJAX和JSRS，而返回的数据以JavaScript形式在前台操作，格式化和显示。这允许你创建能提供接近实时的反馈给用户的web应用程序。</P>
<P>·支持PHP&amp;ASP</P>
<P>·针对所有函数的一致的JavaScript文件</P>
<P>·支持远程脚本和XML</P>
<P>·支持本地和远程函数</P>
<P>·单个或者多个XMLHTTP对象</P>
<P>·以文本或者JavaScript XML/DOM文档对象方式返回后台数据</P>
<P>·能支持POST和GET请求</P>
<P>·后台代理函数来访问远程函数和数据</P>
<P>·在所有的主要浏览器上测试过</P>
<P>·在GNU GPL&amp;LGPL保护下发行</P>
<P>3.2 SAJAX(可用，但是不是1.0版本;自从3月2005年)</P>
<P>网站是：<A href="http://www.modernmethod.com/sajax/">http://www.modernmethod.com/sajax/</A>，直接把调用从Javascript发送到你的服务器端语言并再次回返。例如，调用一个javascript方法x_calculateBudget()，将先到达服务器和调用一个Java calculateBudget()方法，然后以javascript方式把值返回到x_calculateBudget_cb()。</P>
<P>·便利从Javascript代理函数到后台操作的映射。</P>
<P>·能够代理对众多服务器端平台（ASP/ColdFusion/Io/Lua/Perl/PHP/Python/Ruby）的调用。</P>
<P>·开源许可。来自多方面贡献者。</P>
<P>3.3 Javascipt对象标志(JSON)和JSON-RPC</P>
<P>JSON(<A href="http://www.crockford.com/JSON/index.html">http://www.crockford.com/JSON/index.html</A>)，是一个"胖的自由的XML选择"，而JSON-RPC(<A href="http://www.json-rpc.org/">http://www.json-rpc.org/</A>)是一种远程过程协议，类似于XML-RPC，强有力支持Javascript客户。</P>
<P>·实现多服务器端平台(<A href="http://www.json-rpc.org/impl.xhtml">http://www.json-rpc.org/impl.xhtml</A>)：Java，Python，Ruby，Perl。</P>
<P>·针对每种平台有独立的打包和许可，如JSON-RPC-Java(<A href="http://oss.metaparadigm.com/jsonrpc/">http://oss.metaparadigm.com/jsonrpc/</A>)。</P>
<P>3.4 Javascript远程脚本(JSRS)(自从2000年)</P>
<P>网址是：<A href="http://www.ashleyit.com/rs/jsrs/test.htm">http://www.ashleyit.com/rs/jsrs/test.htm</A>，直接把调用从Javascript发送到你的服务器端语言并再次回返。</P>
<P>·知名的浏览器：IE4+，NS4.x，NS6.x，Mozilla，Opera7和Galeon。</P>
<P>·服务器端支持：ASP，ColdFusion，PerlCGI，PHP,Python和JSP(servlet)。</P>
<P>·开源许可。由Brent Ashley(<A href="http://www.ashleyit.com/">http://www.ashleyit.com/</A>)提供支持。</P>
<P><STRONG>4 服务器端：Java</STRONG></P>
<P>注意：许多现有的框架最近正在添加Java支持(例如struts)，我将在后面指出。</P>
<P>4.1 WebORB for Java(自从2005年8月)</P>
<P>网址：<A href="http://www.themidnightcoders.com/weborb/aboutWeborb.htm">http://www.themidnightcoders.com/weborb/aboutWeborb.htm</A>，是一个平台，支持开发AJAX和基于Flash的胖客户端应用程序，并可以把它们与Java对象和XML Web服务相系起来。在线举例(http：//www.themidnightcoders.com/examples)</P>
<P>·WebORB包括一个称作丰富的客户系统(<A href="http://www.themidnightcoders.com/rcs/index.htm">http://www.themidnightcoders.com/rcs/index.htm</A>)的客户端库。该丰富的客户系统提供一简单的在线api来绑定到并调用任何Java对象，XML Web服务或者EJB上的方法。</P>
<P>·支持同步的和异步的方法调用。</P>
<P>·并不要求在服务器端代码上作任何修改，不需要定制方法属性，特别的签名或者参数类型。★不要求设计时生成代理。</P>
<P>·同步调用返回来自于该调用(不需要回叫)的数据。异步的调用依赖于一个回叫实现。</P>
<P>·任何服务器端方法能被同步地或者异步地调用。</P>
<P>·客户应用程序能向服务器对象请求指定的活动方式。结果，对象能被轻易地创建而不需任何特殊的编程。</P>
<P>·提供一个特定API来处理数据库查询结果-服务器代码能返回Data集合或者Data表，而客户端以一个特殊RecordSet JavaScript对象来显示这个结果。该对象提供一个方法以检索列名和行数据。</P>
<P>·支持数据分页技术。客户应用程序能检索页面中的数据。</P>
<P>·支持所有的服务器端参数类型并返回值-原型，字符串，复合类型，数组，本机.net集合，远程参考。</P>
<P>·共有两种版本可用：标准版(自由)和专业版(商业许可)</P>
<P>4.2 Echo 2(自从3月2005年)</P>
<P>网址是：<A href="http://www.nextapp.com/products/echo2/">http://www.nextapp.com/products/echo2/</A>，允许你用纯Java代码编写Ajax应用软件(范例(<A href="http://demo.nextapp.com/InteractiveTest/ia">http://demo.nextapp.com/InteractiveTest/ia</A>))。</P>
<P>自动地生成HTML和Javascript。</P>
<P>·协调浏览器和服务器之间的消息。消息形式为XML。</P>
<P>·如果需要，可以手工编写定制的Javascript部件。</P>
<P>·开源许可(Mozilla公共许可或者GNU LGPL)。源于Next App,Inc.(<A href="http://www.nextapp.com/">http://www.nextapp.com/</A>)。</P>
<P>4.3 Direct Web Remoting (DWR)(2005年)</P>
<P>网址是：<A href="http://www.getahead.ltd.uk/dwr/">http://www.getahead.ltd.uk/dwr/</A>，是一个框架，用于直接从Javascript代码中调用Java方法。</P>
<P>·象SAJAX，能把Javascript中的调用传递到Java方法，并返回到Javascript回叫。</P>
<P>·能与任何web框架（Struts，Tapestry，等等）一起使用。</P>
<P>·开源许可(Apache(<A href="http://www.apache.org/LICENSE.txt">http://www.apache.org/LICENSE.txt</A>))。由Joe Walker(<A href="http://www.getahead.ltd.uk/sg/space/joe/">http://www.getahead.ltd.uk/sg/space/joe/</A>)所支持。被加入到WebWork(<A href="http://www.opensymphony.com/webwork/">http://www.opensymphony.com/webwork/</A>)版本。</P>
<P>4.4 SWATO(2005年)</P>
<P>网址是：<A href="http://swato.dev.java.net/">http://swato.dev.java.net/</A>，是一套可重用的和良好集成的Java/JavaScript库，它实现了一种更容易的方式来改变你的web应用程序的交互，它是通过AJAX方式实现。</P>
<P>·服务器端Java库能被容易地配置到所有的Servlet 2.3+匹配的容器中。</P>
<P>·客户端JavaScript库能工作在支持HttpXMLRequest的各种浏览器中。</P>
<P>·使用JSON来在服务器端编组你的POJO数据。这样你能存取在任何JavaScript环境(HTML，XUL，SVG)中的远程数据，这种存取可以容易地通过硬编码或者与某种成熟的JavaScript库集成来实现。</P>
<P>·提供一个简单的接口来使你的JavaScript代码可以与暴露在客户端的远程POJO交互(RPC等)。</P>
<P>·使用web.xml中的&lt;servlet&gt;和&lt;filter&gt;的容易且灵活的配置，并能(但不是依赖)与Spring集成到一起。</P>
<P>·提供了几个可帮助你快速开发web应用程序的组件(如自动完成的文本框，在线表单，在线列表，等等)。<BR><BR><SPAN class=top11><STRONG>5 服务器端：Lisp</STRONG> </P>
<P></P>
<P>5.1 CL-Ajax</P>
<P>网址：<A href="http://cliki.net/cl-ajax">http://cliki.net/cl-ajax</A>，实现Javascript直接调用服务器端Lisp函数。</P>
<P>·如下输出函数：</P>
<P>(export-函数 #’my-函数) </P>
<P>·可以产生带有参数的Javascript代理。</P>
<P>·能回叫Javascript函数或者DOM对象。</P>
<P>·可以被集成进SAJAX。</P>
<P>·开源(定制，非常灵活，许可)。由[Richard Newman](<A href="http://www.holygoat.co.uk/">http://www.holygoat.co.uk/</A>)所维护。</P>
<P><STRONG>6 服务器端：.NET</STRONG></P>
<P>6.1 WebORB for.NET(自从8月2005年)</P>
<P>网址：<A href="http://www.themidnightcoders.com/weborb/aboutWeborb.htm">http://www.themidnightcoders.com/weborb/aboutWeborb.htm</A>，是一个平台，用于开发AJAX和基于Flash的胖客户端应用程序，并能把它们连接到.NET对象和XML Web服务。(在线举例(<A href="http://www.themidnightcoders.com/examples">http://www.themidnightcoders.com/examples</A>))</P>
<P>·WebORB包括一个客户端库，名叫Rich Client System(<A href="http://www.themidnightcoders.com/rcs/index.htm">http://www.themidnightcoders.com/rcs/index.htm</A>)。Rich Client System提供一简单的在线api以绑定到和调用任何.NET对象或者XML Web服务上的任何方法。</P>
<P>·支持同步和异步的方法调用</P>
<P>·并不要求在服务器端代码上作任何修改，不需要定制方法属性，特别的签名或者参数类型。**不要求设计时代理生成。</P>
<P>·同步调用返回来自于该调用的数据(不需要回叫)。异步的调用依赖于一个回叫实现。</P>
<P>·任何服务器端方法能被同步地或者异步地调用。</P>
<P>·客户应用程序能向服务器对象请求指定的活动方式。结果，对象能被轻易地创建而不需任何特殊的编程。</P>
<P>·提供一个特定API来处理数据库查询结果-服务器代码能返回DataSet或者DataTable，而客户端以一个特殊RecordSet JavaScript对象来显示这个结果。该对象提供一个方法以检索列名和行数据</P>
<P>·支持数据页面技术。客户端应用程序能检索页面中的数据。</P>
<P>·支持所有的服务器端参数类型并返回值-原型，字符串，复合类型，数组，本机.net集合，远程参考</P>
<P>·共有两种版本可用的：标准版(自由)和专业版(商业许可)</P>
<P>6.2 Ajax.NET(自从3月2005年)</P>
<P>网址是：<A href="http://ajax.schwarz-interactive.de/">http://ajax.schwarz-interactive.de/</A>，是一个库，实现从Javascript到服务器端.NET的存取。</P>
<P>·象SAJAX，能把Javascript中的调用传递到.NET方法，并返回到Javascript回叫。</P>
<P>·能存取来自于JavaScript的会话数据。</P>
<P>·缓存结果</P>
<P>·自由使用，可用的源码，未指定使用许可。由Michael Schwarz(<A href="http://weblogs.asp.net/mschwarz/">http://weblogs.asp.net/mschwarz/</A>)所维护。</P>
<P>·不允许改变源代码，用属性标记方法</P>
<P>·完整的类支持以返回客户端JavaScript值</P>
<P>·使用HtmlControls来进行输入和返回值</P>
<P>·可以返回数据表，数据集，数据视图，数组和集合</P>
<P><STRONG>7 服务器端：PHP</STRONG></P>
<P>7.1 AjaxAC(自从2005年4月)</P>
<P>网址是：<A href="http://ajax.zervaas.com.au/">http://ajax.zervaas.com.au/</A>，用单个的PHP类封装了完整的应用程序。</P>
<P>·所有的应用程序代码是自包含在单个类中(附加另外一些JavaScript库)</P>
<P>·干净利索地调用PHP文件/HTML页面。只需创建应用程序类，然后参照应用程序JavaScript和依附任何需要的HTML元素到该应用程序。 </P>
<P>·容易地处理JavaScript事件的内嵌功能</P>
<P>·创建子需要并处理它们的内嵌功能</P>
<P>·允许定制的配置值，因此某些单元能在运行时间设置</P>
<P>·无凌乱的JavaScript代码夹杂在调用HTML的代码中-所有的事件是被动态依附的</P>
<P>·由于以上两个原因容易和模板引擎集成到一起</P>
<P>·容易钩到（hook in to）已有的PHP类或者MySQL数据库以返回来自于子需求的数据</P>
<P>·能够容易地进一步生成JavaScript对象的可扩展的窗口小组件结构(但是还需要做一些工作)</P>
<P>背景：</P>
<P>·开源许可(Apache2.0)。由Zervaas Enterprises(<A href="http://ajax.zervaas.com.au/">http://ajax.zervaas.com.au/</A>)支持</P>
<P>7.2 JPSpan</P>
<P>网址是：<A href="http://jpspan.sourceforge.net/wiki/doku.php">http://jpspan.sourceforge.net/wiki/doku.php</A>，直接把Javascript调用传递到PHP函数。</P>
<P>·进行了严肃的单元测试。</P>
<P>·开源许可(PHP)。</P>
<P>7.3 XAJAX</P>
<P>网址是：<A href="http://xajax.sf.net/">http://xajax.sf.net</A>，直接把Javascript调用传递到PHP函数。</P>
<P>·使用Javascript代理来调用PHP脚本。</P>
<P>·开源。由J.Max Wilson所创。</P>
<P>8 服务器端：Ruby</P>
<P>Ruby On Rails(<A href="http://www.rubyonrails.org/">http://www.rubyonrails.org/</A>)是一个通常的强力支持Ajax的web框架：</P>
<P>·当Ajax出现的时候Rails还处于其发展的早期，因此Ajax可能逐渐成为Rails框架的核心。</P>
<P>·生成浏览器中大多数/全部的窗口小组件和动画的Javascript脚本。</P>
<P>·支持服务器端调用。</P>
<P>·调度支持。　</P>
<P>·开源许可。</P></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN><img src ="http://www.blogjava.net/zyb9114/aggbug/23357.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-11 16:15 <a href="http://www.blogjava.net/zyb9114/articles/23357.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA中参数是传址的</title><link>http://www.blogjava.net/zyb9114/articles/23355.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sun, 11 Dec 2005 08:06:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23355.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23355.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23355.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23355.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23355.html</trackback:ping><description><![CDATA[<SPAN class=content id=ContentBody style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><FONT color=#000000>在不同的java新闻组中，参数是传值还是传址一直是一个经常被争辩的话题。误解的中心是以下两个事实：<BR><BR>对象是传引用的 <BR>参数是传值的<BR>这两个能够同时成立吗？一个字：是！在java中，你从来没有传递对象，你传递的仅仅是对象的引用！一句话，java是传引用的。然而，当你传递一个参数，那么只有一种参数传递机制：传值！<BR><BR>通常，当程序员讨论传值和传引用时，他们是指语言的参数传递机制，c++同时支持这两种机制，因此，以前使用过c++的程序员开始好像不能确定的java是如何传参数的。java语言为了事情变得简单只支持参数传值的机制。 <BR><BR>java中的变量有两种类型：引用类型和原始类型。当他们被作为参数传递给方法时，他们都是传值的。这是一个非常重要的差别，下面的代码范例将说明这一点。在继续前，我们有必要定义一下传值和传引用。<BR><BR>传值意味着当参数被传递给一个方法或者函数时，方法或者函数接收到的是原始值的副本。因此，如果方法或者函数修改了参数，受影响的只是副本，原始值保持不变。<BR><BR>关于java中的参数传递的混乱是因为很多java程序员是从c++转变过来的。c++有引用和非引用类型的变量，并且分别是通过传引用和传值得。java语言有原始类型和对象引用，那么，按照逻辑，java对于原始类型使用传值而对引用是传引用的，就像c++一样。毕竟，你会想到如果你正在传递一个引用，那么它一定是传引用的。这是一个很诱惑人的想法，但是是错误的！<BR><BR>在c++和java中，当函数的参数不是引用时，你传递的是值得副本（传值）。但是对于引用类型就不同了。在c++中，当参数是引用类型，你传递的是引用或者内存地址（传引用），而在java中，传递一个引用类型的参数的结果只是传递引用的副本（传值）而非引用自身。<BR><BR>这是一个非常重要的区别！java不考虑参数的类型，一律传递参数的副本。仍然不信？如果java中是传引用，那么下面的范例中的swap方法将交换他们的参数。因为是传值，因此这个方法不是像期望的那样正常工作。<BR><BR>class Swap<BR>{<BR>public static void main(String args[]) <BR>{ <BR>Integer a, b; <BR>int i,j;<BR>a = new Integer(10);<BR>b = new Integer(50); <BR>i = 5;<BR>j = 9; <BR>System.out.println(\"Before Swap, a is \" + a); <BR>System.out.println(\"Before Swap, b is \" + b); <BR>swap(a, b); <BR>System.out.println(\"After Swap a is \" + a); <BR>System.out.println(\"After Swap b is \" + b); <BR>System.out.println(\"Before Swap i is \" + i); <BR>System.out.println(\"Before Swap j is \" + j); <BR>swap(i,j); <BR>System.out.println(\"After Swap i is \" + i);<BR>System.out.println(\"After Swap j is \" + j); <BR>}<BR>public static void swap(Integer ia, Integer ib)<BR>{<BR>Integer temp = ia; <BR>ia = ib; <BR>ib = temp; <BR>}<BR>public static void swap(int li, int lj) <BR>{ <BR>int temp = li; <BR>li = lj; <BR>lj = temp; <BR>} <BR>} <BR><BR>上面程序的输出是: <BR><BR>Before Swap, a is 10 <BR>Before Swap, b is 50<BR>After Swap a is 10 <BR>After Swap b is 50 <BR>Before Swap i is 5 <BR>Before Swap j is 9 <BR>After Swap i is 5 <BR>After Swap j is 9 <BR><BR>因为swap方法接收到的是引用参数的副本（传值），对他们的修改不会反射到调用代码。<BR><BR>译者注：在传递引用和原始类型时还是有不同的，考虑以下的代码：<BR><BR>class Change<BR>{<BR>public static void main(String args[]) <BR>{ <BR>StringBuffer a=new StringBuffer(\"ok\"); <BR>int i;<BR>i = 5;<BR>System.out.println(\"Before change, a is \" + a); <BR>change(a); <BR>System.out.println(\"After change a is \" + a); <BR>System.out.println(\"Before change i is \" + i); <BR>change(i); <BR>System.out.println(\"After change i is \" + i);<BR>}<BR>public static void change(StringBuffer ia)<BR>{<BR>ia.append(\" ok?\");<BR>}<BR>public static void change(int li) <BR>{ <BR>li = 10; <BR>} <BR>}<BR><BR>程序的输出为：<BR><BR>Before change, a is ok<BR><BR>After change a is ok ok?<BR>Before change i is 5<BR>After change i is 5<BR><BR>即如果传递的是引用，那么可以修改引用对象的内容，这个改变会影响到原来的对象，而传递的如果是原始类型则不会有影响。这个也是造成误解的原因之一吧。 </FONT>
<DIV style="WIDTH: 100%; TEXT-ALIGN: right"><FONT style="FONT-SIZE: 12px; BACKGROUND: #ffffff; TEXT-DECORATION: none" face=宋体>海边的贝壳</FONT></DIV></SPAN><img src ="http://www.blogjava.net/zyb9114/aggbug/23355.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-11 16:06 <a href="http://www.blogjava.net/zyb9114/articles/23355.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样用Java实现MSN Messager的功能</title><link>http://www.blogjava.net/zyb9114/articles/23354.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sun, 11 Dec 2005 08:05:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23354.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23354.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23354.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23354.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23354.html</trackback:ping><description><![CDATA[现在的即时通讯软件琳琅满目，大家耳熟能详的无非就是腾讯公司的QQ，微软公司的MSN Messenger以及网易的泡泡，就用户量而言这三者应该是名列前茅的。但是腾讯公司的QQ以及网易的泡泡由于并没有公开其客户端与服务<SPAN id=tech_art_center><!-- Copyright 1999-2000 ThruPort Technologies <img align=absmiddle src=image/url.gif border=0><a target=_blank href=http://www.thruport.com>http://www.thruport.com</a> --><!-- end dynamic banner insert --></SPAN>器之间的通讯协议导致开发者很难利用起这一庞大的用户群体来开辟另外的服务渠道。<BR><BR>MSN Messenger这一由世界头号软件商-微软公司开发的即时通讯软件，凭借其与windows操作系统和整个微软产品家族的紧密结合，简单实用、性能稳定、世界通用等特点，很快被中国用户接受，目前其用户正在以几何数字增长。但是让开发者雀跃的是该软件同时也提供了开放的API以及开放的通讯协议。<BR><BR>著名的MSN Plus就是一款利用其API开发的用于扩展MSN Messenger功能的插件。而我们今天要介绍的jMSN则是封装了MSN Messenger开放的通讯协议的Java API，通过这个API开发者完全可以使用Java语言模拟出MSN Messenger软件，API的作者也提供一个用Java语言编写的在某方面功能甚至比MSN Messenger还强大的MSN 客户端软件。由于采用了跨平台的Java语言开发，因此该软件也可同时运行于其他操作系统，目前已经经过测试的有各种Linux系统以及Mac OS上，当然还有视窗操作系统。<BR><BR>jMSN是一个韩国人开发的开放源码的API，可以从<IMG src="http://www.waynet.cn/conch/image/url.gif" align=absMiddle border=0><A href="http://sourceforge.net/projects/jmsn/" target=_blank>http://sourceforge.net/projects/jmsn/</A>站点上下载，该项目的首页基本上以韩文为主，包括它的API文档的说明都是韩文。这个让我非常头疼，不过没有关系，因为jMSN非常简单，如果没有什么特殊情况下不看那些说明也没有关系。<BR><BR>jmsn是一个完整的Java应用程序，下载解压后可以直接运行，运行的界面跟微软的MSN Messenger很类似，包括操作上都非常一致，如果你的操作系统是Linux或者其他那都可以直接用它来替代微软的程序。另外一个是msnm-lib，这个就是我们今天要介绍的API，它仅仅是一个开发包，在jmsn组件中已经包含了这个包。<BR><BR>你可能想先体验一下jmsn自带的程序看看到底能完成什么样的功能吧？解压jmsn压缩包后的目录中会有一个可执行文件，不过如果你的JDK不是使用安装程序安装的，建议你不用执行它，它会找不到jre的。你可以使用命令行来启动这个程序，这样做有个好处是你还可以看到运行中打印出来的信息。<BR><BR>应该说界面跟MSN Messenger是非常类似的。用户可以通过它发送和接收消息等。在启动jMSN的命令行窗口中可以看到jMSN与服务器之间通讯的详细信息。<BR><BR>前面我们主要在介绍jMSN大概的情况，介绍它能完成什么样的功能。下面我们开始来了解怎么利用jMSN自带的API：msnm-lib来实现这些功能。我们可以通过msnm-lib来完成与MSN服务器之间的通讯而不需要我们去操心具体的通讯协议的细节。<BR><BR>事实上msnm-lib给我们做了更多的事情使得我们使用msnm-lib来开发一个MSN应用程序变得非常的简单，这也就是我前面提到的我们完全可以不去可能它所提供的韩文API文档的缘故，因为使用它实在是太简单了。<BR><BR>闲话说了那么多，现在我们就开始来开发我们自己基于Java的跨平台的MSN客户端程序。相信听到这句大家都会觉得血脉膨胀，没错，还有什么比动手写程序更让人兴奋的事情呢？何况还是基于Java的、跨平台的！<BR><BR>我们先给出一段可运行的代码来完成一个最简单的功能：当有人把它加入好友时，程序自动将之加入好友，当有人给它发送信息，程序自动回复一条相同的信息。完成这么简单的功能的代码如下：<BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>/* 
* Created on 2003-11-21 by Liudong 
*/ 
package jmsn.demo; 

import rath.msnm.MSNMessenger; 
import rath.msnm.SwitchboardSession; 
import rath.msnm.UserStatus; 
import rath.msnm.entity.MsnFriend; 
import rath.msnm.event.MsnAdapter; 
import rath.msnm.msg.MimeMessage; 
/** 
* MSN演示程序 
* @author Liudong 
*/ 
public class MSNDaemon extends Thread
{ 
private static MSNMessenger msn; 

public static void main(String[] args) 
{ 
msn = new MSNMessenger
("youraccount@hotmail.com", "password"); 
msn.setInitialStatus(UserStatus.ONLINE); 
msn.addMsnListener(new MSNAdapter(msn)); 
msn.login(); 
System.out.println
("Waiting for the response...."); 
//捕捉Ctrl+C的输入以便注销MSN的登录 
Runtime.getRuntime().
addShutdownHook(new MSNDaemon()); 
} 
/** 
* 用户中止程序执行 
*/ 
public void run() 
{ 
msn.logout(); 
System.out.println("MSN Logout OK"); 
} 
} 
/** 
* MSN消息事件处理类 
* @author Liudong 
*/ 
class MSNAdapter extends MsnAdapter
{ 

MSNMessenger messenger; 

public MSNAdapter(MSNMessenger messenger)
{ 
this.messenger = messenger; 
} 
/** 
* 某人正在输入信息 
*/ 
public void progressTyping( 
SwitchboardSession ss, 
MsnFriend friend, 
String typingUser)
{ 
System.out.println
(friend.getLoginName() + "正在输入信息..."); 
} 
/** 
* 收到消息的时候执行该方法 
*/ 
public void instantMessageReceived( 
SwitchboardSession ss, 
MsnFriend friend, 
MimeMessage mime) 
{ 
System.out.print("接收到消息：
" + friend.getFriendlyName() + "-&gt;"); 
System.out.println(mime.getMessage()); 
try { 
//发送相同的回复信息给发送者 
messenger.sendMessage
(friend.getLoginName(), mime); 
} catch (Exception e)
{ 
e.printStackTrace(); 
} 
} 
/** 
* 登录成功后执行该方法 
*/ 
public void loginComplete(MsnFriend own)
{ 
System.out.println
(own.getLoginName() + " Login OK"); 
} 
/** 
* 登录失败后执行该方法 
*/ 
public void loginError(String header)
{ 
System.out.println
("Login Failed: " + header); 
} 
/** 
* 好友离线时执行该方法 
*/ 
public void userOffline(String loginName)
{ 
System.out.println
("USER " + loginName + " Logout."); 
} 
/** 
* 好友上线时执行该方法 
*/ 
public void userOnline(MsnFriend friend)
{ 
System.out.println
("USER "+friend.getFriendlyName()+" Login."); 
} 
/** 
* 有人加我为好友时执行 
*/ 
public void whoAddedMe(MsnFriend friend)
{ 
System.out.println
("USER " + friend.getLoginName() + " Addme."); 
try { 
messenger.addFriend(friend.getLoginName()); 
} catch (Exception e)
{ 
e.printStackTrace(); 
} 
} 
/** 
* 有人把我从好友列表中删除时执行 
*/ 
public void whoRemovedMe(MsnFriend friend)
{ 
System.out.println
("USER "+friend.getLoginName()+" Remove me."); 
try { 
messenger.removeFriend(friend.getLoginName()); 
} catch (Exception e) 
{ 
e.printStackTrace(); 
} 
} 
}</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>除了两个常用的对象MsnFriend以及MimeMessage分别用来表示我的好友以及MSN信息外，其他我们需要了解的也就是MSNMessenger以及MsnAdapter了。当然了前提是我们不需要除了聊天外的其他功能，例如文件传输等等。 <BR><BR>类MSNMessenger对应着一个帐号的一次登录会话。我们仅仅是需要告诉MSNMessenger类我们登录所用的帐号、密码、登录后的初始状态以及我们怎么来处理从MSN服务器上接收到的任何信息。 <BR><BR>在msnm-lib中，处理MSN信息是通过一个叫MsnAdapter类来处理的，这个类定义了如何处理例如收到消息、有人加我为好友等等的事件，开发者可以重载这些方法以便进行自行处理。 <BR><BR>我们自行扩展MsnAdapter的类必须告诉MSNMessenger实例知道，这也就是我们前面代码中的 <BR><BR>
<CENTER><CCID_NOBR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>msn.addMsnListener(new MSNAdapter(msn));</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></CENTER><BR><BR>自行扩展MsnAdapter的类是用来处理被动消息的，例如有人给我发消息等。当我们要发送消息给别人的时候就需要用到MSNMessenger的实例，这也就是我们为什么要把MSNMessenger的实例传递给MSNAdapter的原因，因为当我们接收到任何消息时要给发送人回复一条相同的信息。到此我们前面提出的简单功能已经完成了，读者可以在自己的机器上进行测试，运行时需要用到msnm-lib库，也就是msnm.jar文件。 <BR><BR>关于多人聊天： <BR><BR>MSN有另外一个不错的功能就是多人同时聊天，msnm-lib对这个功能支持也非常好。在MsnAdapter中定义的方法instantMessageReceived的第一个参数类型为SwitchboardSession。当接收到消息时，我们可以从这个参数中获取多人聊天的一个会话标识，同时可以通过getMsnFriends来读取参与当前聊天的所有好友。当你要主动发送消息的时候你就必须从SwitchboardSession中读取所有的好友并给他们一一发送信息。 <BR><BR>关于文件传输： <BR><BR>可能这是我发现的关于msnm-lib的唯一不足，或者说还不够完善的部分。经过测试发现使用微软的MSN程序可以正常传输文件的两台机器用jMSN却无法传输，错误信息都是说连接超时，这两台机器不在同一个子网。 <BR><BR>相信msnm-lib对这个功能并没有进行处理。由于并没有两台直接连接Internet的机器，因此关于jMSN的文件传输一直都没有办法来做一个试验，希望新版本的msnm-lib能解决好这个问题。 <BR>
<DIV style="WIDTH: 100%; TEXT-ALIGN: right"><FONT style="FONT-SIZE: 12px; BACKGROUND: #ffffff; TEXT-DECORATION: none" face=宋体>海边的贝壳</FONT></DIV><img src ="http://www.blogjava.net/zyb9114/aggbug/23354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-11 16:05 <a href="http://www.blogjava.net/zyb9114/articles/23354.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax程序设计入门</title><link>http://www.blogjava.net/zyb9114/articles/23353.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sun, 11 Dec 2005 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23353.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23353.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23353.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23353.html</trackback:ping><description><![CDATA[<STRONG>一、使用Ajax的主要原因<BR><BR></STRONG>
<DIV></DIV>
<DIV>　　1、通过适当的Ajax应用达到更好的用户体验；<BR><BR>　　2、把以前的一些服务器负担的工作转嫁到客户端，利于客户端闲置的处理能力来处理，减轻服务器和带宽的负担，从而达到节约ISP的空间及带宽租用成本的目的。<BR></DIV>
<DIV><BR>　　<B>二、引用</B><BR><BR></DIV>
<DIV>　　Ajax这个概念的最早提出者Jesse James Garrett认为：<BR><BR>　　Ajax是Asynchronous JavaScript and XML的缩写。<BR><BR>　　Ajax并不是一门新的语言或技术,它实际上是几项技术按一定的方式组合在一在同共的协作中发挥各自的作用,它包括：<BR><BR>　　·使用XHTML和CSS标准化呈现;<BR><BR>　　·使用DOM实现动态显示和交互;<BR><BR>　　·使用XML和XSLT进行数据交换与处理;<BR><BR>　　·使用XMLHttpRequest进行异步数据读取;<BR><BR>　　·最后用JavaScript绑定和处理所有数据;<BR><BR>　　Ajax的工作原理相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。</DIV>
<DIV>&nbsp;</DIV>
<P align=center><A onfocus=this.blur() href="http://www.waynet.cn/conch/Upfiles/200581060929.png" target=_blank><IMG alt=按此在新窗口浏览图片 src="http://www.waynet.cn/conch/Upfiles/200581060929.png" onload="javascript:if(this.width>screen.width-333)this.width=screen.width-333" border=0></A></P>
<DIV>　　<STRONG>三、概述<BR><BR></STRONG>
<DIV>　　虽然Garrent列出了7条Ajax的构成技术，但个人认为，所谓的Ajax其核心只有JavaScript、XMLHTTPRequest和DOM，如果所用数据格式为XML的话，还可以再加上XML这一项(Ajax从服务器端返回的数据可以是XML格式，也可以是文本等其他格式)。<BR><BR>　　在旧的交互方式中,由用户触发一个HTTP请求到服务器,服务器对其进行处理后再返回一个新的HTHL页到客户端,每当服务器处理客户端提交的请求时,客户都只能空闲等待,并且哪怕只是一次很小的交互、只需从服务器端得到很简单的一个数据,都要返回一个完整的HTML页,而用户每次都要浪费时间和带宽去重新读取整个页面。<BR><BR>　　而使用Ajax后用户从感觉上几乎所有的操作都会很快响应没有页面重载（白屏）的等待。<BR><BR>　　1、XMLHTTPRequest<BR><BR>　　Ajax的一个最大的特点是无需刷新页面便可向服务器传输或读写数据(又称无刷新更新页面),这一特点主要得益于XMLHTTP组件XMLHTTPRequest对象。这样就可以向再发桌面应用程序只同服务器进行数据层面的交换,而不用每次都刷新界面也不用每次将数据处理的工作提交给服务器来做,这样即减轻了服务器的负担又加快了响应速度、缩短了用户等候时间。<BR><BR>　　最早应用XMLHTTP的是微软,IE（IE5以上）通过允许开发人员在Web页面内部使用XMLHTTP ActiveX组件扩展自身的功能,开发人员可以不用从当前的Web页面导航而直接传输数据到服务器上或者从服务器取数据。这个功能是很重要的,因为它帮助减少了无状态连接的痛苦,它还可以排除下载冗余HTML的需要,从而提高进程的速度。Mozilla（Mozilla1.0以上及NetScape7以上）做出的回应是创建它自己的继承XML代理类：XMLHttpRequest类。Konqueror (和Safari v1.2,同样也是基于KHTML的浏览器)也支持XMLHttpRequest对象,而Opera也将在其v7.6x+以后的版本中支持XMLHttpRequest对象。对于大多数情况，XMLHttpRequest对象和XMLHTTP组件很相似,方法和属性也类似,只是有一小部分属性不支持。<BR><BR>　　XMLHttpRequest的应用：<BR><BR>
<DIV>　　·XMLHttpRequest对象在JS中的应用<BR><BR>
<P class=code>var xmlhttp = new XMLHttpRequest();</P><BR>　　·微软的XMLHTTP组件在JS中的应用<BR><BR>
<P class=code>var xmlhttp = new ActiveXObject(Microsoft.XMLHTTP);<BR>var xmlhttp = new ActiveXObject(Msxml2.XMLHTTP);</P>XMLHttpRequest 对象方法<BR>
<P class=code>/**<BR>* Cross-browser XMLHttpRequest instantiation.<BR>*/<BR><BR>if (typeof XMLHttpRequest == ’undefined’) {<BR>　XMLHttpRequest = function () {<BR>　　var msxmls = [’MSXML3’, ’MSXML2’, ’Microsoft’]<BR>　　for (var i=0; i &lt; msxmls.length; i++) {<BR>　　　try {<BR>　　　　return new ActiveXObject(msxmls[i]+’.XMLHTTP’)<BR>　　　} catch (e) { }<BR>　　}<BR>　　throw new Error("No XML component installed!")<BR>　}<BR>}<BR>function createXMLHttpRequest() {<BR>　try {<BR>　　// Attempt to create it "the Mozilla way" <BR>　　if (window.XMLHttpRequest) {<BR>　　　return new XMLHttpRequest();<BR>　　}<BR>　　// Guess not - now the IE way<BR>　　if (window.ActiveXObject) {<BR>　　　return new ActiveXObject(getXMLPrefix() + ".XmlHttp");<BR>　　}<BR>　}<BR>　catch (ex) {}<BR>　return false;<BR>};<BR></P>　　XMLHttpRequest 对象方法 <BR><BR>
<TABLE class=tdAjax cellSpacing=1 width="80%" align=center bgColor=#00ffff>
<TBODY>
<TR>
<TD><FONT size=2>方法</FONT></TD>
<TD><FONT size=2>描述</FONT></TD></TR>
<TR>
<TD><FONT size=2>abort()</FONT></TD>
<TD><FONT size=2>停止当前请求</FONT></TD></TR>
<TR>
<TD><FONT size=2>getAllResponseHeaders()</FONT></TD>
<TD><FONT size=2>作为字符串返问完整的headers</FONT></TD></TR>
<TR>
<TD><FONT size=2>getResponseHeader("headerLabel")</FONT></TD>
<TD><FONT size=2>作为字符串返问单个的header标签</FONT></TD></TR>
<TR>
<TD><FONT size=2>open("method","URL"[,asyncFlag[,"userName"[, "password"]]])</FONT></TD>
<TD><FONT size=2>设置未决的请求的目标 URL, 方法, 和其他参数</FONT></TD></TR>
<TR>
<TD><FONT size=2>send(content)</FONT></TD>
<TD><FONT size=2>发送请求</FONT></TD></TR>
<TR>
<TD><FONT size=2>setRequestHeader("label", "value")</FONT></TD>
<TD><FONT size=2>设置header并和请求一起发送</FONT></TD></TR></TBODY></TABLE><BR>　　XMLHttpRequest 对象属性 <BR><BR>
<TABLE class=tdAjax cellSpacing=1 width="80%" align=center bgColor=#00ffff>
<TBODY>
<TR>
<TD><FONT size=2>属性</FONT></TD>
<TD><FONT size=2>描述</FONT></TD></TR>
<TR>
<TD><FONT size=2>onreadystatechange</FONT></TD>
<TD><FONT size=2>状态改变的事件触发器</FONT></TD></TR>
<TR>
<TD><FONT size=2>readyState</FONT></TD>
<TD><FONT size=2>对象状态(integer):<BR>0 = 未初始化<BR>1 = 读取中<BR>2 = 已读取<BR>3 = 交互中<BR>4 = 完成</FONT></TD></TR>
<TR>
<TD><FONT size=2>responseText</FONT></TD>
<TD><FONT size=2>服务器进程返回数据的文本版本</FONT></TD></TR>
<TR>
<TD><FONT size=2>responseXML</FONT></TD>
<TD><FONT size=2>服务器进程返回数据的兼容DOM的XML文档对象</FONT></TD></TR>
<TR>
<TD><FONT size=2>status</FONT></TD>
<TD><FONT size=2>服务器返回的状态码, 如：404 = "文件末找到" 、200 ="成功"</FONT></TD></TR>
<TR>
<TD><FONT size=2>statusText</FONT></TD>
<TD><FONT size=2>服务器返回的状态文本信息</FONT></TD></TR></TBODY></TABLE><BR>　　2、JavaScript<BR><BR>　　JavaScript是一在浏览器中大量使用的编程语言，，他以前一直被贬低为一门糟糕的语言（他确实在使用上比较枯燥），以在常被用来作一些用来炫耀的小玩意和恶作剧或是单调琐碎的表单验证。但事实是，他是一门真正的编程语言，有着自已的标准并在各种浏览器中被广泛支持。<BR><BR>　　3、DOM<BR><BR>　　Document Object Model。<BR><BR>　　DOM是给 HTML 和 XML 文件使用的一组 API。它提供了文件的结构表述，让你可以改变其中的內容及可见物。其本质是建立网页与 Script 或程序语言沟通的桥梁。<BR><BR>　　所有WEB开发人员可操作及建立文件的属性、方法及事件都以对象来展现（例如，document 就代表“文件本身“这个对像，table 对象则代表 HTML 的表格对象等等）。这些对象可以由当今大多数的浏览器以 Script 来取用。<BR><BR>　　一个用HTML或XHTML构建的网页也可以看作是一组结构化的数据，这些数据被封在DOM（Document Object Model）中，DOM提供了网页中各个对象的读写的支持。<BR><BR>　　4、XML<BR><BR>　　可扩展的标记语言（Extensible Markup Language）具有一种开放的、可扩展的、可自描述的语言结构，它已经成为网上数据和文档传输的标准。它是用来描述数据结构的一种语言，就正如他的名字一样。他使对某些结构化数据的定义更加容易，并且可以通过他和其他应用程序交换数据。<BR><BR>　　5、综合<BR><BR>　　Jesse James Garrett提到的Ajax引擎，实际上是一个比较复杂的JavaScript应用程序，用来处理用户请求，读写服务器和更改DOM内容。<BR><BR>　　JavaScript的Ajax引擎读取信息，并且互动地重写DOM，这使网页能无缝化重构，也就是在页面已经下载完毕后改变页面内容，这是我们一直在通过JavaScript和DOM在广泛使用的方法，但要使网页真正动态起来，不仅要内部的互动，还需要从外部获取数据，在以前，我们是让用户来输入数据并通过DOM来改变网页内容的，但现在，XMLHTTPRequest，可以让我们在不重载页面的情况下读写服务器上的数据，使用户的输入达到最少。<BR><BR>　　基于XML的网络通讯也并不是新事物，实际上FLASH和JAVA Applet都有不错的表现，现在这种富交互在网页上也可用了，基于标准化的并被广泛支持和技术，并且不需要插件或下载小程序。<BR><BR>　　Ajax是传统WEB应用程序的一个转变。以前是服务器每次生成HTML页面并返回给客户端（浏览器）。在大多数网站中，很多页面中至少90%都是一样的，比如：结构、格式、页头、页尾、广告等，所不同的只是一小部分的内容，但每次服务器都会生成所有的页面再返回给客户端，这无形之中是一种浪费，不管是对于用户的时间、带宽、CPU耗用，还是对于ISP的高价租用的带宽和空间来说。如果按一页来算，只能几K或是几十K可能并不起眼，但像SINA每天要生成几百万个页面的大ISP来说，可以说是损失巨大的。而AJAX可以所为客户端和服务器的中间层，来处理客户端的请求，并根据需要向服务器端发送请求，用什么就取什么、用多少就取多少，就不会有数据的冗余和浪费，减少了数据下载总量，而且更新页面时不用重载全部内容，只更新需要更新的那部分即可，相对于纯后台处理并重载的方式缩短了用户等待时间，也把对资源的浪费降到最低，基于标准化的并被广泛支持和技术，并且不需要插件或下载小程序，所以Ajax对于用户和ISP来说是双盈的。<BR><BR>　　Ajax使WEB中的界面与应用分离（也可以说是数据与呈现分离），而在以前两者是没有清晰的界限的，数据与呈现分离的分离，有利于分工合作、减少非技术人员对页面的修改造成的WEB应用程序错误、提高效率、也更加适用于现在的发布系统。也可以把以前的一些服务器负担的工作转嫁到客户端，利于客户端闲置的处理能力来处理。<BR></DIV>
<DIV><BR>　　<B>四、应用</B><BR><BR></DIV>
<DIV>　　Ajax理念的出现，揭开了无刷新更新页面时代的序幕，并有代替传统web开发中采用form(表单)递交方式更新web页面的趋势，可以算是一个里程碑。但Ajax都不是适用于所有地方的，它的适用范围是由它的特性所决定的。<BR><BR>　　举个应用的例子，是关于级联菜单方面的Ajax应用。<BR><BR>　　我们以前的对级联菜单的处理是这样的：<BR><BR>　　为了避免每次对菜单的操作引起的重载页面，不采用每次调用后台的方式，而是一次性将级联菜单的所有数据全部读取出来并写入数组，然后根据用户的操作用JavaScript来控制它的子集项目的呈现，这样虽然解决了操作响应速度、不重载页面以及避免向服务器频繁发送请求的问题，但是如果用户不对菜单进行操作或只对菜单中的一部分进行操作的话，那读取的数据中的一部分就会成为冗余数据而浪费用户的资源，特别是在菜单结构复杂、数据量大的情况下（比如菜单有很多级、每一级菜又有上百个项目），这种弊端就更为突出。<BR><BR>　　如果在此案中应用Ajax后，结果就会有所改观：<BR><BR>　　在初始化页面时我们只读出它的第一级的所有数据并显示，在用户操作一级菜单其中一项时，会通过Ajax向后台请求当前一级项目所属的二级子菜单的所有数据，如果再继续请求已经呈现的二级菜单中的一项时，再向后面请求所操作二级菜单项对应的所有三级菜单的所有数据，以此类推……这样，用什么就取什么、用多少就取多少，就不会有数据的冗余和浪费，减少了数据下载总量，而且更新页面时不用重载全部内容，只更新需要更新的那部分即可，相对于后台处理并重载的方式缩短了用户等待时间，也把对资源的浪费降到最低。<BR><BR>　　此外，Ajax由于可以调用外部数据，也可以实现数据聚合的功能（当然要有相应授权），比如微软刚刚在3月15日发布的在线RSS阅读器BETA版；还可以利于一些开放的数据，开发自已的一些应用程序，比如用Amazon的数据作的一些新颖的图书搜索应用。<BR><BR>　　总之，Ajax适用于交互较多，频繁读数据，数据分类良好的WEB应用。<BR></DIV>
<DIV><BR>　　<B>五、Ajax的优势</B><BR><BR></DIV>
<DIV>　　1、减轻服务器的负担。因为Ajax的根本理念是“按需取数据”，所以最大可能在减少了冗余请求和响影对服务器造成的负担；<BR><BR>　　2、无刷新更新页面，减少用户实际和心理等待时间；<BR>
<P align=center><A onfocus=this.blur() href="http://www.waynet.cn/conch/Upfiles/200581084750.jpg" target=_blank><IMG alt=按此在新窗口浏览图片 src="http://www.waynet.cn/conch/Upfiles/200581084750.jpg" onload="javascript:if(this.width>screen.width-333)this.width=screen.width-333" border=0></A></P><BR>　　首先，“按需取数据”的模式减少了数据的实际读取量，打个很形象的比方，如果说重载的方式是从一个终点回到原点再到另一个终点的话，那么Ajax就是以一个终点为基点到达另一个终点；<BR></DIV>
<DIV>　　其次，即使要读取比较大的数据，也不用像RELOAD一样出现白屏的情况，由于Ajax是用XMLHTTP发送请求得到服务端应答数据，在不重新载入整个页面的情况下用Javascript操作DOM最终更新页面的，所以在读取数据的过程中，用户所面对的也不是白屏，而是原来的页面状态（或者可以加一个LOADING的提示框让用户了解数据读取的状态），只有当接收到全部数据后才更新相应部分的内容，而这种更新也是瞬间的，用户几乎感觉不到。总之用户是很敏感的，他们能感觉到你对他们的体贴，虽然不太可能立竿见影的效果，但会在用户的心中一点一滴的积累他们对网站的依赖。<BR><BR>　　3、更好的用户体验；<BR><BR>　　4、也可以把以前的一些服务器负担的工作转嫁到客户端，利于客户端闲置的处理能力来处理，减轻服务器和带宽的负担，节约空间和带宽租用成本；<BR><BR>　　5、Ajax由于可以调用外部数据；<BR><BR>　　6、基于标准化的并被广泛支持和技术，并且不需要插件或下载小程序；<BR><BR>　　7、Ajax使WEB中的界面与应用分离（也可以说是数据与呈现分离）；<BR><BR>　　8、对于用户和ISP来说是双盈的。<BR>
<DIV><BR>　　<B>六、Ajax的问题</B><BR><BR></DIV>
<DIV>　　1、一些手持设备（如手机、PDA等）现在还不能很好的支持Ajax；<BR><BR>　　2、用JavaScript作的Ajax引擎，JavaScript的兼容性和DeBug都是让人头痛的事；<BR><BR>　　3、Ajax的无刷新重载，由于页面的变化没有刷新重载那么明显，所以容易给用户带来困扰――用户不太清楚现在的数据是新的还是已经更新过的；现有的解决有：在相关位置提示、数据更新的区域设计得比较明显、数据更新后给用户提示等；<BR><BR>　　4、对流媒体的支持没有FLASH、Java Applet好；<BR></DIV>
<DIV><BR>　　<B>七、结束语</B><BR><BR></DIV>
<DIV>　　更好的Ajax应用，需要更多的客户端的开发，和对当前的WEB应用理念的思考，而且良好的用户体验，来源于为处处用户考虑的理念，而不单纯是某种技术。</DIV></DIV></DIV></DIV>
<DIV style="WIDTH: 100%; TEXT-ALIGN: right"><FONT style="FONT-SIZE: 12px; BACKGROUND: #ffffff; TEXT-DECORATION: none" face=宋体>海边的贝壳</FONT></DIV><img src ="http://www.blogjava.net/zyb9114/aggbug/23353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-11 16:04 <a href="http://www.blogjava.net/zyb9114/articles/23353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简化Java应用程序的打包和发布</title><link>http://www.blogjava.net/zyb9114/articles/23351.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sun, 11 Dec 2005 08:00:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23351.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23351.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23351.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23351.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23351.html</trackback:ping><description><![CDATA[发布Java应用程序时你会感到困难？好在Java提供了一系列打包和发布工具，可以显著的简化发布过程<BR><BR><BR>该文章提供了打包Java&nbsp;code的几种方法，我们将会探讨Java&nbsp;manifest&nbsp;文件，给出用于管理JAR文件所依赖文件、估计跨平台发布所需的CLasspath的合适方法.我也会解释如何使用manifest包版本特性来确认包的兼容性...<BR><BR>什么是JAR文件？<BR><BR>在开发过程中，我们可以直接使用Java&nbsp;class文件来运行程序，但这并不是一个好方式，好在Java&nbsp;提供了&nbsp;JAR(Java&nbsp;Archive)文件来提供发布和运行。<BR><BR>jar&nbsp;文件实际上是class&nbsp;文件的ZIP压缩存档，这种格式被广泛使用，因此易与使用，有很多中工具可以操作这种格式的文件。也正是因为这个原因，jar文件本身并不能表达所包含应用程序的标签信息。<BR><BR>Manifest&nbsp;因此得以出现<BR>为了要提供存档的标签信息，jar&nbsp;文件指定了一个特定目录来存放标签信息：META-INF&nbsp;目录，其中我们来关注该目录中的MANIFEST.MF文件，他就是JAR的manifest文件，他包含了JAR文件的内容描述，并在运行时向JVM提供应用程序的信息，大多数JAR文件含有一个默认生成的manifest&nbsp;文件,执行JAR命令或使用zip工具，都可以产生它<BR>如果是由jar命令产生的&nbsp;manifest&nbsp;文件，形如:<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:1.4.0-beta<BR>(Sun&nbsp;Microsystems&nbsp;Inc.)&nbsp;<BR>这些信息没甚么用,仅仅告诉我们使用的是1.0的manifest文件,第一行定义manifest的格式，第二行说明使用&nbsp;SUN&nbsp;的JDK1.4的jar工具生成该文件，如果manifest文件是由其他&nbsp;（如ant）&nbsp;创建的，那将会出现&nbsp;“Created-By:&nbsp;Ant&nbsp;1.2”&nbsp;之类的内容，如果你是自己创建manifest文件，你可以加入自己的一些相关信息.<BR><BR>基础格式<BR><BR>manifest&nbsp;文件的格式&nbsp;是很简单的，每一行都是&nbsp;名－值&nbsp;对应的:属性名开头，接着是&nbsp;":"&nbsp;，然后是属性值，每行最多72个字符，如果需要增加，你可以在下一行续行，续行以空格开头，以空格开头的行都会被视为前一行的续行。<BR>所有在开头的属性都是全局的，你也可以定义特定class&nbsp;或package的属性，稍后将介绍这种<BR>把manifest文件插入JAR文件<BR>使用&nbsp;m&nbsp;选项，把指定文件名的manifest文件&nbsp;传入，例如<BR>jar&nbsp;cvfm&nbsp;myapplication.jar&nbsp;myapplication.mf&nbsp;-C&nbsp;classdir&nbsp;<BR><BR>如果你使用ant来创建时，在ant&nbsp;的build.xml&nbsp;加入如下条目<BR>&lt;target&nbsp;name="jar"&gt;<BR>&lt;jar&nbsp;jarfile&nbsp;="myapplication.jar"<BR>manifest="myapplication.mf"&gt;<BR>&lt;fileset&nbsp;dir="classdir"<BR>includes="**/*.class"/&gt;<BR>&lt;/jar&gt;<BR>&lt;/target&gt;&nbsp;<BR>运行Java程序<BR>现在我们来体验一下manifest文件的作用，如果现在我们有一个Java&nbsp;应用程序打包在myapplication.jar中，&nbsp;main&nbsp;class为&nbsp;com.example.myapp.MyAppMain&nbsp;，那么我们可以用以下的命令来运行<BR>java&nbsp;-classpath&nbsp;myapplication.jar&nbsp;com.example.myapp.MyAppMain<BR>这显然太麻烦了，现在我们来创建自己的manifest文件，如下：<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:&nbsp;JDJ&nbsp;example<BR>Main-Class:&nbsp;com.example.myapp.MyAppMain<BR>这样我们就可以使用如下的命令来运行程序了：（明显简单多了，也不会造成无谓的拼写错误）<BR>java&nbsp;-jar&nbsp;myapplication.jar<BR>管理JAR的依赖资源<BR>很少Java应用会仅仅只有一个jar文件，一般还需要&nbsp;其他类库。比如我的应用程序用到了Sun&nbsp;的&nbsp;Javamail&nbsp;classes&nbsp;，在classpath中我需要包含activation.jar&nbsp;和&nbsp;mail.jar,这样在运行程序时,相比上面的例子,我们要增加一些:<BR>java&nbsp;-classpath&nbsp;mail.jar:activation.jar&nbsp;-jar&nbsp;myapplication.jar<BR>在不同的操作系统中,jar包间的分隔符也不一样，在UNIX用“：”，在window中使用&nbsp;“；”，这样也不方便<BR>同样，我们改写我们的manifest文件，如下<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:&nbsp;JDJ&nbsp;example<BR>Main-Class:&nbsp;com.example.myapp.MyAppMain<BR>Class-Path:&nbsp;mail.jar&nbsp;activation.jar<BR>（加入了Class-Path:&nbsp;mail.jar&nbsp;activation.jar，用空格分隔两个jar包）<BR>这样我们仍然可以使用和上例中相同的命令来执行该程序：<BR>java&nbsp;-jar&nbsp;myapplication.jar<BR>Class-Path属性中包含了用空格分隔的jar文件，在这些jar文件名中要对特定的字符使用逃逸符，比如空格，要表示成"%20"，在路径的表示中，都采用“/”来分隔目录，无论是在什么操作系统中，(即使在window中)，而且这里用的是相对路径（相对于本身的JAR文件）：<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:&nbsp;JDJ&nbsp;example<BR>Main-Class:&nbsp;com.example.myapp.MyAppMain<BR>Class-Path:&nbsp;ext/mail.jar&nbsp;ext/activation.jar&nbsp;<BR>Multiple&nbsp;Main&nbsp;Classes（多主类）<BR>还有一种Multiple&nbsp;Main&nbsp;Classes情况，如果你的应用程序可能有命令行版本&nbsp;和GUI版本，或者一些不同的应用却共享很多相同的代码，这时你可能有多个Main&nbsp;Class，我们建议你采取这样的策略：把共享的类打成lib包，然后把不同的应用打成不同的包，分别标志主类：如下<BR>Manifest&nbsp;for&nbsp;myapplicationlib.jar:<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:&nbsp;JDJ&nbsp;example<BR>Class-Path:&nbsp;mail.jar&nbsp;activation.jar&nbsp;<BR>Manifest&nbsp;for&nbsp;myappconsole.jar:<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:&nbsp;JDJ&nbsp;example<BR>Class-Path:&nbsp;myapplicationlib.jar<BR>Main-Class:&nbsp;com.example.myapp.MyAppMain&nbsp;<BR>Manifest&nbsp;for&nbsp;myappadmin.jar:<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:&nbsp;JDJ&nbsp;example<BR>Class-Path:&nbsp;myapplicationlib.jar<BR>Main-Class:&nbsp;com.example.myapp.MyAdminTool&nbsp;<BR>在myappconsole.jar&nbsp;和&nbsp;myappadmin.jar的manifest文件中分别注明各自的&nbsp;Main&nbsp;Class<BR>Package&nbsp;Versioning<BR>完成发布后，如果使用者想了解&nbsp;，哪些代码是谁的？目前是什么版本？使用什么版本的类库？解决的方法很多&nbsp;，manifest提供了一个较好的方法，你可以在manifest文件中描述每一个包的信息。<BR>Java&nbsp;秉承了实现说明与描述分离的原则，package&nbsp;的描述&nbsp;定义了package&nbsp;是什么，实现说明&nbsp;定义了谁提供了描述的实现，描述和实现包含&nbsp;名、版本号和提供者。要得到这些信息，可以查看JVM的系统属性（使用&nbsp;java.lang.System.getProperty()&nbsp;）<BR>在manifest文件中，我可以为每个package定义描述和实现版本，声明名字，并加入描述属性和实现属性，这些属性是<BR>Specification-Title&nbsp;<BR>Specification-Version&nbsp;<BR>Specification-Vendor&nbsp;<BR>Implementation-Title&nbsp;<BR>Implementation-Version&nbsp;<BR>Implementation-Vendor&nbsp;<BR>当要提供一个类库或编程接口时，描述信息显得是很重要，见以下范例：<BR>Manifest-Version:&nbsp;1.0<BR>Created-By:&nbsp;JDJ&nbsp;example<BR>Class-Path:&nbsp;mail.jar&nbsp;activation.jar&nbsp;<BR>Name:&nbsp;com/example/myapp/<BR>Specification-Title:&nbsp;MyApp<BR>Specification-Version:&nbsp;2.4<BR>Specification-Vendor:&nbsp;example.com<BR>Implementation-Title:&nbsp;com.example.myapp<BR>Implementation-Version:&nbsp;2002-03-05-A<BR>Implementation-Vendor:&nbsp;example.com<BR>Package&nbsp;Version&nbsp;查询<BR>在manifest文件中加入package描述后，就可以使用Java提供的java.lang.Package&nbsp;class进行Package&nbsp;的信息查询，这里列举3个最基本的获取package&nbsp;object的方法<BR>1.Package.getPackages():返回系统中所有定义的package列表<BR>2.Package.getPackage(String&nbsp;packagename):按名返回package<BR>3.Class.getPackage():返回给定class所在的package<BR>使用者这方法就可以动态的获取package信息.<BR>需要注意的是如果给定的package中没有class被加载,则也无法获得package&nbsp;对象<BR><BR>Manifest&nbsp;技巧<BR>总是以Manifest-Version属性开头<BR>每行最长72个字符，如果超过的化，采用续行<BR>确认每行都以回车结束，否则改行将会被忽略<BR>如果Class-Path&nbsp;中的存在路径，使用"/"分隔目录，与平台无关<BR>使用空行分隔主属性和package属性<BR>使用"/"而不是"."来分隔package&nbsp;和class&nbsp;,比如&nbsp;com/example/myapp/<BR>class&nbsp;要以.class结尾，package&nbsp;要以&nbsp;/&nbsp;结尾<img src ="http://www.blogjava.net/zyb9114/aggbug/23351.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-11 16:00 <a href="http://www.blogjava.net/zyb9114/articles/23351.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[ORACLE] 8080端口被占用</title><link>http://www.blogjava.net/zyb9114/articles/23283.html</link><dc:creator>月亮的太阳</dc:creator><author>月亮的太阳</author><pubDate>Sat, 10 Dec 2005 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/zyb9114/articles/23283.html</guid><wfw:comment>http://www.blogjava.net/zyb9114/comments/23283.html</wfw:comment><comments>http://www.blogjava.net/zyb9114/articles/23283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyb9114/comments/commentRss/23283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyb9114/services/trackbacks/23283.html</trackback:ping><description><![CDATA[<SPAN class=Stil8>Oracle XMLDB 占用了8080端口<BR>
<P>解决办法：</P>
<OL>
<LI>修改XMLDB的端口设置 
<LI>禁止XMLDB监听端口 </LI></OL><BR>Change XMLDB Ports</SPAN><BR><BR>This document explains how to change the default ports (8080 for HTTP and 2100 for FTP) in XMLDB.<BR>Oracle XMLDB uses the ports 2100/8080 by default. Sometimes there are problem with other webservers (e.g. JBOSS) running on the same port.<BR><BR>Even if the package dbms_xdb is granted to PUBLIC you need DBA privileges to change the ports.<BR><BR><STRONG>-- change HTTP port from 8080 to 8083</STRONG><BR>call dbms_xdb.cfg_update(updateXML(dbms_xdb.cfg_get(), '/xdbconfig/sysconfig/protocolconfig/httpconfig/http-port/text()', 8083));<BR><BR><STRONG>-- change FTP port from 2100 to 2111</STRONG><BR>call dbms_xdb.cfg_update(updateXML( dbms_xdb.cfg_get(), '/xdbconfig/sysconfig/protocolconfig/ftpconfig/ftp-port/text()' , 2111));<BR><BR><STRONG>-- refresh settings</STRONG><BR>exec dbms_xdb.cfg_refresh;<BR><img src ="http://www.blogjava.net/zyb9114/aggbug/23283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyb9114/" target="_blank">月亮的太阳</a> 2005-12-10 17:29 <a href="http://www.blogjava.net/zyb9114/articles/23283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>