??xml version="1.0" encoding="utf-8" standalone="yes"?>午夜精品三级视频福利,中文在线天堂网,中文字幕va一区二区三区http://www.aygfsteel.com/zdygis/category/14775.htmlJavaGis大草?/description>zh-cnFri, 02 Mar 2007 07:42:33 GMTFri, 02 Mar 2007 07:42:33 GMT60深入剖析Java~程中的中文问题及徏议最优解x?-上篇http://www.aygfsteel.com/zdygis/articles/67570.htmlzdygiszdygisMon, 04 Sep 2006 06:03:00 GMThttp://www.aygfsteel.com/zdygis/articles/67570.htmlhttp://www.aygfsteel.com/zdygis/comments/67570.htmlhttp://www.aygfsteel.com/zdygis/articles/67570.html#Feedback0http://www.aygfsteel.com/zdygis/comments/commentRss/67570.htmlhttp://www.aygfsteel.com/zdygis/services/trackbacks/67570.html

AbstractQ?/b>本文深入分析了JavaE序设计中Java~译器对java源文件和JVM对classcL件的~码/解码q程Q通过此过E的解析透视ZJava~程中中文问题生的Ҏ原因Q最后给Z的最优化的解决Java中文问题的方法?/p>

1、中文问题的来源
    计算机最初的操作pȝ支持的编码是单字节的字符~码Q于是,在计机中一切处理程序最初都是以单字节编码的英文为准q行处理。随着计算机的发展Qؓ了适应世界其它民族的语aQ当然包括我们的汉字Q,Z提出了UNICODE~码Q它采用双字节编码,兼容英文字符和其它民族的双字节字W编码,所以,目前Q大多数国际性的软g内部均采用UNICODE~码Q在软gq行Ӟ它获得本地支持系l(多数旉是操作系l)默认支持的编码格式,然后再将软g内部的UNICODE转化为本地系l默认支持的格式昄出来。Java的JDK和JVMx如此Q我q里说的JDK是指国际版的JDKQ我们大多数E序员用的是国际化的JDK版本Q以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节~码语言Qؓ了能让计机处理中文Q我们自己制定的gb2312、GBK、GBK2K{标准以适应计算机处理的需求。所以,大部分的操作pȝZ适应我们处理中文的需求,均定制有中文操作pȝQ它们采用的是GBK,GB2312~码格式以正显C我们的汉字。如Q中文Win2K默认采用的是GBK~码昄Q在中文WIN2k中保存文件时默认采用的保存文件的~码格式也是GBK的,卻I所有在中文WIN2K中保存的文g它的内部~码默认均采用GBK~码Q注意:GBK是在GB2312基础上扩充来的?br />    ׃Java语言内部采用UNICODE~码Q所以在JAVAE序q行Ӟ存在着一个从UNICODE~码和对应的操作pȝ及浏览器支持的编码格式{换输入、输出的问题Q这个{换过E有着一pd的步骤,如果其中M一步出错,则显C出来的汉字׃出是qQ这是我们常见的JAVA中文问题?br />    同时QJava是一个跨q_的编E语aQ也x们编写的E序不仅能在中文windows上运行,也能在中文Linux{系l上q行Q同时也要求能在英文{系l上q行Q我们经常看到有人把在中文win2k上编写的JAVAE序Q移植到英文Linux上运行)。这U移植操作也会带来中文问题?br />    q有Q有Z用英文的操作pȝ和英文的IE{浏览器Q来q行带中文字W的E序和浏览中文网,它们本n׃支持中文Q也会带来中文问题?br />    有,几乎所有的览器默认在传递参数时都是以UTF-8~码格式来传递,而不是按中文~码传递,所以,传递中文参数时也会有问题,从而带来ؕ码现象?br />    MQ以上几个方面是JAVA中的中文问题的主要来源,我们把以上原因造成的程序不能正运行而生的问题UCQJAVA中文问题?br />2、JAVA~码转换的详l过E?
    我们常见的JAVAE序包括以下cdQ?br />     *直接在console上运行的c?包括可视化界面的c?
     *JSP代码c(注:JSP是Servletscȝ变型Q?br />     *Serveletsc?br />     *EJBc?br />     *其它不可以直接运行的支持c?br />    q些cL件中Q都有可能含有中文字W串Qƈ且我们常用前三类JAVAE序和用L接交互,用于输出和输入字W,如:我们在JSP和Servlet中得到客L送来的字W,q些字符也包括中文字W。无些JAVAcȝ作用如何Q这些JAVAE序的生命周期都是这LQ?br />    *~程人员在一定的操作pȝ上选择一个合适的~辑软g来实现源E序代码q以.java扩展名保存在操作pȝ中,例如我们在中文win2k中用C本编辑一个java源程序;
     *~程人员用JDK中的javac.exe来编译这些源代码QŞ?classc?JSP文g是由容器调用JDK来编译的)Q?br />     *直接q行q些cL这些类布v到WEB容器中去q行Qƈ输出l果?br />    那么Q在q些q程中,JDK和JVM是如何将q些文g如何~码和解码ƈq行的呢Q?br />    q里Q我们以中文win2k操作pȝZ说明JAVAcL如何来编码和被解码的?br />    W一步,我们在中文win2k中用~辑软g如记事本~写一个Java源程序文?包括以上五类JAVAE序)Q程序文件在保存旉认采用了操作pȝ默认支持GBK~码格式(操作pȝ默认支持的格式ؓfile.encoding格式)形成了一?java文gQ也卻IjavaE序在被~译前,我们的JAVA源程序文件是采用操作pȝ默认支持的file.encoding~码格式保存的,java源程序中含有中文信息字符和英文程序代码;要查看系l的file.encoding参数Q可以用以下代码Q?br />public class ShowSystemDefaultEncoding {
public static void main(String[] args) {
String encoding = System.getProperty("file.encoding");
System.out.println(encoding);
}}
    W二步,我们用JDK的javac.exe文g~译我们的Java源程序,׃JDK是国际版的,在编译的时候,如果我们没有?encoding参数指定我们的JAVA源程序的~码格式Q则javac.exe首先获得我们操作pȝ默认采用的编码格式,也即在编译javaE序Ӟ若我们不指定源程序文件的~码格式QJDK首先获得操作pȝ的file.encoding参数(它保存的是操作pȝ默认的编码格式,如WIN2kQ它的gؓGBK)Q然后JDK把我们的java源程序从file.encoding~码格式转化为JAVA内部默认的UNICODE格式攑օ内存中。然后,javac把{换后的unicode格式的文件进行编译成.classcLӞ此时.class文g是UNICODE~码的,它暂攑֜内存中,紧接着QJDK此以UNICODE~码的编译后的class文g保存到我们的操作pȝ中Ş成我们见到的.class文g。对我们来说Q我们最l获得的.class文g是内容以UNICODE~码格式保存的类文gQ它内部包含我们源程序中的中文字W串Q只不过此时它己l由file.encoding格式转化为UNICODE格式了?br />    q一步中Q对于JSP源程序文件是不同的,对于JSPQ这个过E是q样的:即WEB容器调用JSP~译器,JSP~译器先查看JSP文g中是否设|有文g~码格式Q如果JSP文g中没有设|JSP文g的编码格式,则JSP~译器调用JDK先把JSP文g用JVM默认的字W编码格?也即WEB容器所在的操作pȝ的默认的file.encoding)转化Z时的Servletc,然后再把它编译成UNICODE格式的classc,q保存在临时文g夹中。如Q在中文win2k上,WEB容器把JSP文g从GBK~码格式转化为UNICODE格式Q然后编译成临时保存的Servletc,以响应用Lh?br />    W三步,q行W二步编译出来的c,分ؓ三种情况Q?br />    A?直接在console上运行的c?br />    B?EJBcd不可以直接运行的支持c?如JavaBeanc?
    C?JSP代码和Servletc?br />    D?JAVAE序和数据库之间
    下面我们分这四种情况来看?br />    A、直接在console上运行的c?br />    q种情况Q运行该c首先需要JVM支持Q即操作pȝ中必d装有JRE。运行过E是q样的:首先java启动JVMQ此时JVMd操作pȝ中保存的class文gq把内容d内存中,此时内存中ؓUNICODE格式的classc,然后JVMq行它,如果此时此类需要接收用戯入,则类会默认用file.encoding~码格式对用戯入的串进行编码ƈ转化为unicode保存入内存(用户可以讄输入的~码格式Q。程序运行后Q生的字符ԌUNICODE~码的)再回交给JVMQ最后JRE把此字符串再转化为file.encoding格式(用户可以讄输出的~码格式)传递给操作pȝ昄接口q输出到界面上?br />    对于q种直接在console上运行的c,它的转化q程可用?更加明确的表C出来:

?
    以上每一步的转化都需要正的~码格式转化Q才能最l不出现q现象?br />    B、EJBcd不可以直接运行的支持c?如JavaBeanc?
    ׃EJBcd不可以直接运行的支持c,它们一般不与用L接交互输入和输出Q它们常怸其它的类q行交互输入和输出,所以它们在W二步被~译后,Ş成了内容是UNICODE~码的类保存在操作系l中了,以后只要它与其它的类之间的交互在参数传递过E中没有丢失Q则它就会正的q行?br />q种EJBcd不可以直接运行的支持c? 它的转化q程可用?更加明确的表C出来:

    

?
C、JSP代码和Servletc?br />    l过W二步后QJSP文g也被转化为ServletscLӞ只不q它不像标准的Servlets一校存在于classes目录中,它存在于WEB容器的时目录中Q故q一步中我们也把它做为Servlets来看?br />    对于ServletsQ客Lh它时QWEB容器调用它的JVM来运行ServletQ首先,JVM把Servlet的classcMpȝ中读出ƈ装入内存中,内存中是以UNICODE~码的Servletcȝ代码Q然后JVM在内存中q行该Servletc,如果Servlet在运行的q程中,需要接受从客户端传来的字符如:表单输入的值和URL中传入的|此时如果E序中没有设定接受参数时采用的编码格式,则WEB容器会默认采用ISO-8859-1~码格式来接受传入的值ƈ在JVM中{化ؓUNICODE格式的保存在WEB容器的内存中。Servletq行后生成输出,输出的字W串是UNICODE格式的,紧接着Q容器将Servletq行产生的UNICODE格式的串Q如html语法Q用戯出的串等Q直接发送到客户端浏览器上ƈ输出l用P如果此时指定了发送时输出的编码格式,则按指定的编码格式输出到览器上Q如果没有指定,则默认按ISO-8859-1~码发送到客户的浏览器上。这UJSP代码和Servletc,它的转化q程可用?更加明确地表C出来:

?
    D、JavaE序和数据库之间
    对于几乎所有数据库的JDBC驱动E序Q默认的在JAVAE序和数据库之间传递数据都是以ISO-8859-1为默认编码格式的Q所以,我们的程序在向数据库内存储包含中文的数据ӞJDBC首先是把E序内部的UNICODE~码格式的数据{化ؓISO-8859-1的格式,然后传递到数据库中Q在数据库保存数据时Q它默认即以ISO-8859-1保存Q所以,q是Z么我们常常在数据库中d的中文数据是q?br />    对于JAVAE序和数据库之间的数据传递,我们可以用图4清晰地表C出?/p>

?
    3、分析常见的JAVA中文问题几个必须清楚的原?/b>
    首先Q经q上面的详细分析Q我们可以清晰地看到QQ何JAVAE序的生命期中,其编码{换的关键q程是在于:最初编译成class文g的{码和最l向用户输出的{码过E?br />    其次Q我们必M解JAVA在编译时支持的、常用的~码格式有以下几U:
    *ISO-8859-1Q?-bit, ?859_1,ISO-8859-1,ISO_8859_1{编?br />    *Cp1252Q美国英语编码,同ANSI标准~码
    *UTF-8Q同unicode~码
    *GB2312Q同gb2312-80,gb2312-1980{编?br />    *GBK , 同MS936Q它是gb2312的扩?br />    及其它的~码Q如韩文、日文、繁体中文等。同Ӟ我们要注意这些编码间的兼容关体系如下Q?br />    unicode和UTF-8~码是一一对应的关pRGB2312可以认ؓ是GBK的子集,即GBK~码是在gb2312上扩展来的。同ӞGBK~码包含?0902个汉字,~码范围为:0x8140-0xfefeQ所有的字符可以一一对应到UNICODE2.0中来?br />    再次Q对于放在操作系l中?java源程序文Ӟ在编译时Q我们可以指定它内容的编码格式,具体来说?encoding来指定。注意:如果源程序中含有中文字符Q而你?encoding指定为其它的~码字符Q显然是要出错的。用-encoding指定源文件的~码方式为GBK或gb2312Q无论我们在什么系l上~译含有中文字符的JAVA源程序都不会有问题,它都会正地中文{化ؓUNICODE存储在class文g中?br />    
然后Q我们必L楚,几乎所有的WEB容器在其内部默认的字W编码格式都是以ISO-8859-1为默认值的Q同Ӟ几乎所有的览器在传递参数时都是默认以UTF-8的方式来传递参数的。所以,虽然我们的Java源文件在出入口的地方指定了正的~码方式Q但其在容器内部q行时还是以ISO-8859-1来处理的?br />



zdygis 2006-09-04 14:03 发表评论
]]>
提升J2EE的性能http://www.aygfsteel.com/zdygis/articles/67272.htmlzdygiszdygisSat, 02 Sep 2006 06:36:00 GMThttp://www.aygfsteel.com/zdygis/articles/67272.htmlhttp://www.aygfsteel.com/zdygis/comments/67272.htmlhttp://www.aygfsteel.com/zdygis/articles/67272.html#Feedback0http://www.aygfsteel.com/zdygis/comments/commentRss/67272.htmlhttp://www.aygfsteel.com/zdygis/services/trackbacks/67272.html你的J2EE应用是不是运行的很慢Q它们能不能承受住不断上升的讉K量?本文讲述了开发高性能、高Ҏ的JSP面和Servlet的性能优化技术。其意思是建立可能快的ƈ能适应数量增长的用户及其请求。在本文中,我将带领你学习已l实践和得到证实的性能调整技术,它将大大地提高你的servlet和jsp面的性能Q进而提升J2EE的性能。这些技术的部分用于开发阶D,例如Q设计和~码阶段。另一部分技术则与配|相兟?

  技?Q在HttpServletinit()Ҏ中缓存数?/p>

  服务?/u>会在创徏servlet实例之后和servlet处理Mh之前调用servlet的init()Ҏ。该Ҏ在servlet的生命周期中仅调用一ơ。ؓ了提高性能Q在init()中缓存静态数据或完成要在初始化期间完成的代h昂贵的操作。例如,一个最佛_跉|使用实现了javax.sql.DataSource接口的JDBCq接池?/p>

  DataSource从JNDI树中获得。每调用一ơSQLp使用JNDI查找DataSource是非常昂늚工作Q而且严重影响了应用的性能。Servlet的init()Ҏ可以用于获取DataSourceq缓存它以便之后的重用:

publicclassControllerServletextendsHttpServlet
{
privatejavax.sql.DataSourcetestDS=null;

publicvoidinit(ServletConfigconfig)throwsServletException
{
super.init(config);
Contextctx=null;
try
{
ctx=newInitialContext();
testDS=(javax.sql.DataSource)ctx.lookup("jdbc/testDS");
}
catch(NamingExceptionne)
{
ne.printStackTrace();
}
catch(Exceptione)
{
e.printStackTrace();
}
}

publicjavax.sql.DataSourcegetTestDS()
{
returntestDS;
}
...
...
}

  技?Q禁用servlet和Jsp的自动装载功?/p>

  当每ơ修改了Servlet/JSP之后Q你不得不重新启动服务?/u>。由于自动装载功能减开发时_该功能被认ؓ在开发阶D|非常有用的。但是,它在q行阶段是非常昂늚Qservlet/JSP׃不必要的装蝲Q增加类装蝲器的负担而造成很差的性能。同Pq会使你的应用由于已被某U类装蝲器装载的cM能和当前c装载器装蝲的类不能怺协作而出现奇怪的冲突现象。因此,在运行环境中Z得到更好的性能Q关闭servlet/JSP的自动装载功能?/p>

  技?Q控制HttpSession

  许多应用需要一pd客户端的hQ因此他们能互相相关联。由于HTTP协议是无状态的Q所以基于Web的应用需要负责维护这样一个叫做session的状态。ؓ了支持必ȝ护状态的应用QJavaservlet技术提供了理session和允许多U机制实现session的API。HttpSession对象扮演了sessionQ但是用它需要成本。无Z时HttpSession被用和重写Q它都由servletd。你可以通过使用下面的技术来提高性能Q?br />l在JSP面中不要创建默认的HttpSession:默认情况下,JSP面创徏HttpSession。如果你在JSP面中不用HttpSessionQؓ了节省性能开销Q用下边的面指o可以避免自动创徏HttpSession对象Q?br />Q?a href="mailto:%@pagesession="false"%">%@pagesession="false"%Q?/p>

  1) 不要大的对象图存储在HttpSession中:如果你将数据当作一个大的对象图存储在HttpSession中,应用服务?/u>每次不得不处理整个HttpSession对象。这迫使Java序列化和增加计算开销。由于序列化的开销Q随着存储在HttpSession对象中数据对象的增大Q系l的吞吐量将会下降?/p>

  2) 用完后释放HttpSessionQ当不在使用HttpSessionӞ使用HttpSession.invalidate()Ҏ使sesion失效?/p>

  3) 讄时|一个servlet引擎有一个默认的时倹{如果你不删除session或者一直把session用到它超时的时候,servlet引擎把session从内存中删除。由于在内存和垃圾收集上的开销Qsession的超时D大,它对pȝҎ和性能的媄响也大。试着session的超时D|的可能低?/p>

  技?Q用gzip压羃

  压羃是删除冗余信息的作法Q用可能小的空间描qC的信息。用gzipQGNUzipQ压~文档能有效地减下载HTML文g的时间。你的信息量小Q它们被送出的速度快。因此,如果你压~了׃web应用产生的内容,它到辄户ƈ昄在用户屏q上的速度p快。不是Q?a href="http://www.baidu.com/baidu?tn=sayyes&word=览? target="_blank">览?/u>都支持gzip压羃的,但检查一?a href="http://www.baidu.com/baidu?tn=sayyes&word=览? target="_blank">览?/u>是否支持它ƈ发送gzip压羃内容?a href="http://www.baidu.com/baidu?tn=sayyes&word=览? target="_blank">览?/u>是很Ҏ的事情。下边的代码D说明了如何发送压~的内容?/p>

publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsIOException,ServletException
{

OutputStreamout=null

//ChecktheAccepting-EncodingheaderfromtheHTTPrequest.
//Iftheheaderincludesgzip,chooseGZIP.
//Iftheheaderincludescompress,chooseZIP.
//Otherwisechoosenocompression.

Stringencoding=request.getHeader("Accept-Encoding");

if(encoding!=null&&encoding.indexOf("gzip")!=-1)
{
response.setHeader("Content-Encoding","gzip");
out=newGZIPOutputStream(response.getOutputStream());
}
elseif(encoding!=null&&encoding.indexOf("compress")!=-1)
{
response.setHeader("Content-Encoding","compress");
out=newZIPOutputStream(response.getOutputStream());
}
else
{
out=response.getOutputStream();

}
...
...
}

  技?Q不要用SingleThreadModel

  SingleThreadModel保证servlet一ơ仅处理一个请求。如果一个servlet实现了这个接口,servlet引擎ؓ每个新的h创徏一个单独的servlet实例Q这引起大量的pȝ开销。如果你需要解决线E安全问题,请用其他的办法替代q个接口。SingleThreadModel在Servlet2.4中是不再提倡用?/p>

  技?Q用线E池

  servlet引擎为每个请求创Z个单独的U程Q将该线E指zservice()ҎQ然后在service()Ҏ执行完后删除该线E。默认情况下Qservlet引擎可能为每个请求创Z个新的线E。由于创建和删除U程的开销是很昂贵的,于是q种默认行ؓ降低了系l的性能。我们可以用线E池来提高性能。根据预期的q发用户数量Q配|一个线E池Q设|好U程池里的线E数量的最和最大g及增长的最和最大倹{v初,servlet引擎创徏一个线E数与配|中的最线E数量相{的U程池。然后servlet引擎把池中的一个线E指z一个请求而不是每ơ都创徏新的U程Q完成操作之后,servlet引擎把线E放回到U程池中。用线E池Q性能可以显著地提高。如果需要,ҎU程的最大数和增长数Q可以创建更多的U程?/p>

  技?Q选择正确的包括机?/p>

  在JSP面中,有两中方式可以包括文Ӟ包括指o(Q?a href="mailto:%@includefile="test.jsp"%">%@includefile="test.jsp"%Q?和包括动?Qjsp:includepage="test.jsp"flush="true"/Q?。包括指令在~译阶段包括一个指定文件的内容Q例如,当一个页面编译成一个servlet时。包括动作是指在h阶段包括文g内容Q例如,当一个用戯求一个页面时。包括指令要比包括动作快些。因此除非被包括的文件经常变动,否则使用包括指o会获得更好的性能?/p>

  技?Q在useBean动作中用合适的范围

  使用JSP面最强大方式之一是和JavaBeanlg协同工作。JavaBean使用Qjsp:useBeanQ标{֏以嵌入到JSP面中。语法如下:

Qjsp:useBeanid="name"scope="page|request|session|application"class=
"package.className"type="typeName"Q?br />Q?jsp:useBeanQ?

  scope属性说明了bean的可见范围。scope属性的默认值是page。你应该Ҏ你应用的需求选择正确的范_否则它将影响应用的性能?/p>

  例如Q如果你需要一个专用于某些h的对象,但是你把范围讄成了sessionQ那么那个对象将在请求结束之后还保留在内存中。它一直保留在内存中除非你明确地把它从内存中删除、session无效或session时。如果你没有选择正确的范围属性,׃内存和垃圾收集的开销会影响性能。因此ؓ对象讄合适的范围q在用完它们之后立即删除?/p>

  杂项技?/p>

  1) 避免字符串连接:׃String对象是不可变对象Q用“+”操作符会D创徏大量的零时对象。你使用的“+”越多,产出的零时对象就多Q这媄响性能。当你需要连接字W串Ӟ使用StringBuffer替代“+”操作?/p>

  2) 避免使用System.out.printlnQSystem.out.println同步处理盘输入/输出Q这大大地降低了pȝ吞吐量。尽可能地避免用System.out.println。尽有很多成熟的调试工具可以用Q但有时System.out.printlnZ跟踪、或调试的情况下依然很有用。你应该配置System.out.println仅在错误和调试阶D|开它。用finalBoolean型的变量Q当配置成falseӞ在编译阶D完成优化检查和执行跟踪输出?/p>

  3) ServletOutputStream与PrintWriter比较Q由于字W输出流和把数据~码成字节,使用PrintWriter引入了小的性能开销。因此,PrintWriter应该用在所有的字符集都正确地{换做完之后。另一斚wQ当你知道你的servlet仅返回二q制数据Q用ServletOutputStreamQ因为servlet容器不编码二q制数据Q这样你p消除字符集{换开销?/p>

  ȝ

  本文的目的是展示l你一些实늚和已l证实的用于提高servlet和JSP性能的性能优化技术,q些提高你的J2EE应用的整体性能。下一步应该观察其他相x术的性能调整Q如EJB、JMS和JDBC{?/p>

zdygis 2006-09-02 14:36 发表评论
]]>
J2EE性能试与优化(转蝲Q?/title><link>http://www.aygfsteel.com/zdygis/articles/67271.html</link><dc:creator>zdygis</dc:creator><author>zdygis</author><pubDate>Sat, 02 Sep 2006 06:32:00 GMT</pubDate><guid>http://www.aygfsteel.com/zdygis/articles/67271.html</guid><wfw:comment>http://www.aygfsteel.com/zdygis/comments/67271.html</wfw:comment><comments>http://www.aygfsteel.com/zdygis/articles/67271.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/zdygis/comments/commentRss/67271.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/zdygis/services/trackbacks/67271.html</trackback:ping><description><![CDATA[ <p>本文的目的是说明如何在典型的J2EE环境下实现可伸羃性测试,性能试和优化?</p> <p><strong>定义</strong></p> <p>响应旉——从初始的请求到回应下蝲的完成(h整个|页Q之间的旉?br />负蝲——系l用的度。当服务器的应用可以承受J重的通讯量时被称为可以承受“高负蝲”?<br />可׾~性——可伸羃的应用应该拥有随负蝲U性增长的响应旉。这L应用可以通过U性的Q不是指数性的Q增加硬件设施来处理来多的数据量?<br />自动试工具——通过模拟用户h|页或在你的|站上遍历预~程的工作流Q链接)的工P如Segue软g的SilkQWebLoad{等Q?<br />负蝲试工具——大多数自动试工具同时也是负蝲试工具Q如WebLoad。这些工具可以模拟Q意数量的用户使用你的站点Qƈ且可以提供重要的分析数据如^均响应时间等?<br />ProfilerQ程序刨析器Q——Profiler是在你的应用E序q行时进行检的E序。它能提供你有用的运行时M息如Ҏ代码块的q行旉Q内?堆利用率Q内存中Ҏ对象的实例数目等{?</p> <p><strong>性能试的过E?</strong></p> <p>1Q?功能试。大多数应用E序的测试首先是对完成功能的试。即保应用E序中所有的试用例/工作正常工作?<br />2Q?负蝲和可伸羃性测试。负载和可׾~性测试有两种方式Q?br />☆ 在增加数据库数据量的同时试响应旉?br />☆ 在增加当前用h量的同时试响应旉?br />3Q?解释l果。在各种数据库容量和不同的负载下试q响应时间后Q就可以在这些测试的q_响应旉和测试中服务器的资源利用率的基础上来做出解释?br />4Q?优化。在上一步完成后识别出问题所在,然后解释l果q捕捉问题?/p> <p><strong>负蝲和可伸羃性测?/strong></p> <p>负蝲和可伸羃性测试的目的是确保你的应用程序在使用的高峰时期拥有较好的响应旉。你q可以测试你的应用程序在蝲时的行ؓQ因Z的站点的数据库中会有来多的数据)。在试之前Q先~写一些脚本,向数据库中填充^均数量的数据Q运行性能试Q测量响应时间。然后向数据库中填充大量的数据(大约是三q内可预见数据量的三到四倍)Q再ơ运行性能试。如果第二次试的响应时间特别长Q那么肯定有问题?/p> <p>在进行性能试Ӟ你可能会x拟不同负载下服务器的使用情况。根据经验,可以模拟低负载(1-5q发用户Q、中负蝲Q?0-50q发用户Q、大负蝲Q?00q发用户Q和重负载(1000以上q发用户Q。注意这些数字是不确定的Q根据你的商业需求而定。另外,使用负蝲试软g模拟10个ƈ发用户ƈ不就真正代表?0个ƈ发用P因ؓ在负载测试中每个“机器h”在再次命中服务器之前会{待几个毫秒。这L话,使用负蝲试工具模拟10个ƈ发用户差不多代表实际|上冲浪中的30-40个用戗?</p> <p>在测试过了这三种负蝲U别后,可以比较在q几U情况下的^均响应时_考察你的服务器是否可承受大访问量Q即q_响应旉是否U性增ѝ?/p> <p><strong>解释l果 </strong></p> <p>性能试q程中最有趣的就是解释负载测试的l果。让我们来看看几U不同的可能性: </p> <p>1Q当数据库的数据量大量增长超q一定程度时Q响应时间g长很多?/p> <p>当数据库中的记录?00行增加到50Q?00Ӟ响应旉不应该有明显的增加。数据库索引技术得从表中查找一条记录只需耗费几毫U的旉Q即使该表有成千上万条记录也一栗这是_从一个适度数据量的数据库增加到拥有量数据的数据库Ӟ如果响应旉大大廉Q那么你可能q没有烦引适当的列?/p> <p>2Q负载增长时响应旉呈指数化增长</p> <p>如果在增加ƈ发用h量时pȝ变得不可用,那么你的pȝ׃是可伸羃的。这个结果的解释比较困难Q因为问题原因可能是g、发布^台的配置、系l体pȝ构等{。一定要在测试过E中监控以下服务器资源:<br />?监控内存h?br />?监控CPU使用情况?</p> <p>如果CPU是超负荷使用的,需要更快的或更多的处理器。如果CPU利用率比较低Q那么就可能是相关的输入输出问题Q检查测试系l的数据库连接、线E数、网l配|等{?</p> <p>查过配置Q确定不是硬件瓶颈,体系l构和代码都l过了优化,如果问题仍然存在的话Q就该进行代码运行时监测了(使用profilerQ?</p> <p><strong>优化 </strong></p> <p>数据库、体pȝ构、配|和g都是需要优化的对象。上面已l提q,D服务器负h受能力低的最单的p是数据库没有经q优化。数据库理员(DBAQ对M开发组来说都是臛_重要的,如果没有的话Q可以考虑q样做:</p> <p>察看所有的EJBQ核实数据库没有执行M~码的SQL语句的线性搜索。可以拷贝代码中的SQL语句到数据库的SQL查询工具H口中,执行EXPLAIN子句Q?/p> <p>Explain select * from table where tablefield = somevalue </p> <p>管Explain的语法根据数据库的不同各有差异,但L一些东西是怼的。数据库会告诉你该语句是Ҏ索引查询q是U性查询。确保验证了数据库的每一个SQL语句都用了索引。如果没有用,建立索引?/p> <p>优化数据库后再优化硬仉|,下一步再使用profiler优化代码?/p> <p>ProfilerE序在你的应用程序运行时分析它,q提供给你用其它方法无法得到的信息Q如Q?</p> <p>1Q每个类在内存中有多个对象和垃圾收集器的行为?/p> <p>?q些信息可以帮助你识别那些类应该被缓存?br />?可以帮助你调整Java内存堆?/p> <p>2Q?应用E序在具体的cMp了多时间?/p> <p>q是非常重要的特征。Profiler可以指出那个cL瓉?/p> <p>有一个这LprofilerE序叫做Optimize-It。Optimize-It可以用于MJavaE序或基于Java的应用服务器。它可以很容易的和WebLogic配置CP也可以用来刨析远E服务器上的应用E序?/p> <p>优化体系l构和具体的目密不可分。不q其中有一些小的技巧: </p> <p>_保|络调用最,特别是数据库调用?<br />   ?一个大的数据库调用比很多小的调用要好得多?<br />   ?保ejbStore没有为只L作保存Q何信息?<br />   ?使用Details Objects获取Entity Bean状态?/p> <p>  ⑵.保在尽可能的情况下利用Cache?<br />  应用服务器可能允许在内存中用Entity Bean~存Q确保利用了q些特征Q因为它可以显著减少数据库调用ƈ加速数据存取?</p> <p>  Ӟ保使用Session Bean作ؓEntity Bean的封装?br />  可以把一个完整的实例的工作流装C个网l调用中Q作Z个Session BeanQ和一个事务)的一个方法?</p> <p>  <strong>l论</strong><br /><br />  应用E序的性能试与优化是一个挑战。幸q的是,市场上有很多工具可以使这个过E变得简单。用这些工h照本文提到的单步骤,你可以有效的捕获pȝ的瓶颈所在?/p> <img src ="http://www.aygfsteel.com/zdygis/aggbug/67271.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/zdygis/" target="_blank">zdygis</a> 2006-09-02 14:32 <a href="http://www.aygfsteel.com/zdygis/articles/67271.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2EE性能调优Q{载)http://www.aygfsteel.com/zdygis/articles/67270.htmlzdygiszdygisSat, 02 Sep 2006 06:31:00 GMThttp://www.aygfsteel.com/zdygis/articles/67270.htmlhttp://www.aygfsteel.com/zdygis/comments/67270.htmlhttp://www.aygfsteel.com/zdygis/articles/67270.html#Feedback0http://www.aygfsteel.com/zdygis/comments/commentRss/67270.htmlhttp://www.aygfsteel.com/zdygis/services/trackbacks/67270.html性能问题的最明显表现是网늚响应旉变慢。在J2EEpȝ中,l常体现有下面更为基本的症状Q?/p>
  • 应用服务器资源的使用情况
  • JVM堆的使用情况
  • pȝ资源的用情?
  • 数据库资源的使用情况
  • |络zd

            q些现象表明J2EE应用依赖很多外部资源Qƈ且是q行在一个层ơ化的执行模式的环境中:


            ׃Java虚拟机和应用服务器掩盖了操作pȝ和硬件的Ҏ,所以在设计软gpȝӞ架构工程师更应该深刻理解整个操作环境?

            在设计Y件系l时Q架构工E师应把性能和可扩展性放在首位,然后开始寻扑֮易解决的问题Q反应时间缓慢通常的原因是讉K数据库效率低和过多地调用q程对象和方法。接下来Q架构工E师可l寻找不明显的原因,例如法的篏U媄响和不必要的开销?/p>

            现在市场上的各个J2EE应用服务器有很多配置目。这里只单介l一些常见的性能优化配置目?/p>

            很多应用服务器都有一些与J2EE规范有关的操作系l配|项目或非标准的Ҏ,q可以提高系l性能。应该化旉来理解这些性能配置?/p>

    Java虚拟机堆和垃圑֛收设|?/h3>

            MJava应用的性能调整基础都涉及到堆的大小和垃圑֛收设|。(q里主要讨论Sun HotSpor JVMQ?

            堆可分ؓ三代Q年ȝQ新的)Q年老的和持久的。Hotspot JVM的内存基本配|包括最大堆大小Q初始堆大小和年M代堆的大。当配置最大堆大小时可参考下面一些指|

  • 最大大应于物理内存Q避免虚存的面调度?
  • 需要减d他进E用的内存
  • 在负载测试时q行优化

            注意不要最大堆大小讄得过大。堆大Q内存中保存的对象越多。内存中对象多Q回收过E时间越ѝ?/p>

            配置初试堆大的一般性策略包括:

  • 初始大设|ؓ最大堆大小
  • 初始大设|ؓ最大堆大小?/4?/2

            对于q轻一代堆大小QSun 推荐是设|ؓ最大堆大小?/3?/p>

            也可以选择不同的垃圑֛收算法。首先是增量垃圾回收。该法的意思是减少单个对象回收停顿旉Q这Ll果是整体回收性能的下降。该法相互引用的对象分组Q然后尝试按l回收。尝试回收的部分小Q回收处理的旉往往会越?/p>

            1.4.1版的HotSpot JVM增加了两个垃圑֛收算法:q行法和ƈ发算法?/p>

            在年M代堆中实Cq行法。在多处理器的机器上Q这U回收算法用了多线E来提高性能。虽然这个算法会暂停所有的应用U程Q但是由于利用了多个CPU使得回收旉非常快。在q轻一代堆中,该算法显著地减少了回收带来的停顿?/p>

            在年老一代堆中实Cq发法。在应用中最大限度地执行q发。回收过E分?个阶D,覆盖了可回收对象的标记和清除操作。前两个q程会暂停应用线E,后两阶段可与应用q发执行。ƈ发垃圑֛收算法的"最大限度ƈ?特点可以使JVM利用更大的堆和多个CPU。因此应x׃采用~省的mark-compact(标记-压羃)和stop-the-worldQ停所有处理){垃圑֛收算法所带来的gq和吞吐量问题?/p>

    处理U程

            J2EE应用服务器是多线E的应用。应用服务器的线E是一U资源池Q处理请求和和应用服务器的内部功能等d׃nq些资源?/p>

            很多应用服务器允ؓ特定的Q务或应用配置不同大小的线E池。通常需要增加这些线E池的大以满应用负蝲的需要?/p>

            架构工程师应该避免将U程池大设|过大,q是因ؓ会增加上下文交换的次敎ͼ从而降低应用的性能。线E池的大通常应该能最大利用机器上的CPUQ同时又不能使CPUq蝲?/p>

    EJB配置目

             在应用服务器中,很多不同cd的EJB是以资源池的方式实现的。通常q些池大和初始Bean的数量会明显影响应用的性能?/p>

            架构工程师应该避免将q些池大设|的q大Q这样会D不必要地消耗JVM和操作系l内存。另外,初始Bean数量讄q高会得应用服务器的启动时间长的难以接受?/p>

            在应用服务器中,~存很多不同cd的EJB。缓存大和时讄通常也会对应用性能带来显著影响?/p>

             架构工程师应该避免将~寸大小讄q大Q这同样会不必要地消耗大量JVM和操作系l内存。此外,应避免设|过长的时--例如当EJB不用Ӟ仍被~存---Q这也会D不必要地消耗大量内存?/p>

    数据库配|项?/h3>

            J2EE规范要求应用服务器厂商必L供数据库q接资源池功能。通常增加数据库连接池的大会提高性能。架构工E师应该考虑不同cd的SQL操作Q例如事务型和批处理型)应用不同的q接池。如果一个消息Bean执行批处理操作,那么应该为此另创Z个连接池Q而不要与事务型操作用同一个连接池?/p>

            很多J2EE应用服务器提供了Prepared Statement 的缓存功能。创建Prepared Statement是很耗费资源的。在事务型的J2EE应用中通常执行很多同样的SQL语句Q只是参C同而已。所以在应用中应发挥数据库配|项目的作用Q尽量用Prepared Statement?/p>

  •  

  • 好的开始是成功的一半。对于J2EE同样如此Q我们知道当开发应用时Q在架构设计阶段的决定将对应用的性能和可扩展性生深q的影响?/p>

            现在当开发一个应用项目时Q我们越来越多地注意C性能和可扩展性的问题。应用性能的问题比应用功能的不丰富问题往往更ؓ严重Q前者会影响到所有用P而后者只会媄响到y使用该功能的那些用户?/p>

            作ؓ应用pȝ的负责hQ一直被要求"要少花钱多办?----用更的gQ更的|络带宽Q以及更短的旉完成更多的Q务。J2EE通过提供lg方式和通用的中间g服务是目前首选的最优方式。而要能够构徏一个具有高性能和可扩展性的J2EE应用Q需要遵循一些基本的架构{略?

    ~存(Caching)Q?/h3>

            单地_~存中存攄频繁讉K的数据,在应用的整个生命周期中,q些数据存放在持久性存储器或存攑֜内存中。在实际环境中,典型的现象是在分布式pȝ中每个JVM中有一个缓存的实例或者在多个JVM中有一个缓存的实例?

            ~存数据是通过避免讉K持久性存储器来提高性能的,否则会导致过多的盘讉K和过于频J网l数据传输?/p>

    复制Q?/h3>

            复制是通过在多台物理机器上创徏指定应用服务的多个拷贝来获得整体更大吞吐效率。理Z看,如果一个服务被复制成两个服务,那么pȝ可处理两倍的h?/p>

            复制是通过单一服务的多个实例的方式从而减每个服务的负蝲来提高性能的?/p>

    q行处理

            q行处理一个Q务分解ؓ更ؓ单的子Q务,q能够同时在不同的线E中执行?/p>

            q行处理是通过利用J2EE层执行模式的多线E和多CPU特点来提高性能。与使用一个线E或CPU处理d相比Q以q行方式处理多个子Q务可以操作pȝ在多个线E或处理器中q行分配q些子Q务?/p>

    异步处理

            应用功能通常被设计ؓ同步或串行方式。异步处理只处理那些非常重要的Q务部分,然后控制立卌回给调用者,其他d部分在E后执行?/p>

            异步处理是通过~短那些在将控制q回l用户之前必d理的旉来提高性能的。虽焉做同样多的事情,但是用户不必{到整个q程完成可以l发求了?/p>

    资源?/h3>

            资源池技术用的是一套准备好的资源。与在请求和资源之间l持1Q?的关pȝ不同Q这些资源可被所有请求所׃n?/p>

            资源池的使用是有条g的,需要衡量下面两U方式的代hQ?/p>

            A,l持一套可被所有请求共享资源的代h

            B,为每个请求都重新创徏一个资源的代h

            当前者小于后者时Q用资源池才是有效率的?/p>


  •         构徏高性能的J2EE应用不但需要了解常用的实施技巧。下面介l最常用?0U有效方法,可帮助架构设计师们快速成斚w的专家?/p>

    Java性能的基----内存理

            MJava应用Q单机的或J2EE的性能基础都可归结C的应用是如何理内存的问题。Java的内存管理包括两个重要Q务:内存的分配和内存的回收。在内存的分配中Q目标是要减需要创建的对象?内存回收是导致性能下降的普遍原因。也是_内存中的对象多Q垃圑֛收越困难。所以我们对创徏对象的态度应该保守越好?

            在J2EE应用中常见的两个内存有关的问题是Q游ȝ对象Q也被称为内存泄Ԍ和对象@环(指大量频J创建和删除-在Java中体Cؓ解除引用---对象Q?/p>

            我们应注意确保所有可到达的对象实际是zȝQ即q些对象不但在内存中Q而且也要在执行的代码中是存在的。当对象在应用中已经没有用了Q而我们却忘记了删除对该对象的引用Ӟ游离的对象就出现了?

            我们知道垃圾回收会占用CPU旉。短期对象的大量创徏增加了垃圑֛收的频率会造成性能下降?/p>

    不要在Servlet中实C务逻辑

            在构建J2EE应用Ӟ架构工程师通常会用到J2EE的基本部分,Servlet?/p>

            如果架构师不使用Session Beans, Entity Beans, ?Message Beans, 那么改进性能的方法就很少。只能采用增加CPU或更多的物理服务器等Ҏ。EJB使用了缓存(cacheQ和资源池等Ҏ可以提高性能和扩展性?/p>

    可能用本地接口访问EJB

            在早期的J2EE Q遵循EJB1.X规范Q应用中Q访问EJB是`通过RMI使用q程接口实现的。随着EJB2.0的出玎ͼ可以通过本地接口讉KEJBQ不再用RMIQ在同一个JVM中用远E方法已l少多了。但是现在还是有一些用EJB1.X实现的应用和不知道用本地接口的一些EJB新手。ؓ说明q点Q我们作个比较:

            1. 客户端应用调用本地Stub

            2. 该Stub装配参数

            3. 该Stub传到skeleton

            4. 该skeleton分解参数

            5. 该skeleton调用EJB对象

            6. EJB对象执行容器服务

            7. EJB对象调用企业BEAN实例

            8. 企业BEA执行操作

            9. 执行l装/分解步骤然后q回

            与远E接口处理相比较Q本地接口的EJBҎ是:

                    1. 客户端调用本地对?/p>

                    2. 本地对象执行容器服务

                    3. 本地对象调用企业Bean实例

                    4. 企业Bean实例执行操作

                    5. 没有其他q回步骤Q!

            如果你不需要从q程的客L讉K一个特DEJBQ就应该使用本地Ҏ?/p>

    在实现Session Bean的服务中装对实体EJB的访?/h3>

            从Servlet讉K实体EJB不但效率低而且难于l护。用Session Fa?adeQ会话外观)模式可把对实体EJB的访问封装在会话EJB中,在该会话EJB中通过使用本地接口讉K实体EJB而避免过多的q程调用?/p>

            q项技术会有额外的性能和扩展方面的好处Q这是因Z话和实体EJB可以使用~存和资源池技术来q行改进。另外,׃负蝲的需要,会话和实体EJB可被扩展部v到其他硬件设备上Q这比将Servlet层复制扩展到其他g讑֤上要单的多?/p>

    量_粒度访问远EEJB

             当访问远EEJBӞ调用set/getҎ生过多的|络hQ同时也Dq程接口处理的过载。ؓ避免q种情况Q可考虑数据属性集中在一个对象中Q这样通过一ơ对q程EJB的调用就可以传递所有数据。这Ҏ术就是数据传输对象(Data Transfer ObjectQ模式?/p>

    优化SQL

            J2EE的架构设计工E师和开发h员通常不是SQL专家或经验丰富的数据库管理员。首先应该确保SQL使用了数据库提供的烦引支持。在某些情况下,数据库的烦引和数据分开存放会提高性能。但要知道,增加额外的烦引可以提高SELECT性能但也会降低INSERT的性能。对于某些数据库Q关联表之间的排序会严重影响性能。可以多向数据库理员咨询?/p>

    避免在实体EJB中过多执行SQL

            有时候,通过实体EJB讉K数据会执行多个SQL语句。根据J2EE 规范Q第一步,调用实体Bean的find(发现)ҎQ第二步Q在W一ơ调用实体EJB的业务方法时Q容器会调用ejbLoad()从数据库中获得信息?/p>

            很多CMP(容器理持久?在调用发现方法时q存了实体数据Q所以在调用ejbLoad()时就不再讉K数据库了。应该避免用BMP(Bean理的持久?或者自己实现缓存算法避免二ơ访问数据库?/p>

    使用Fast Lane Reader 模式讉K只读数据

            J2EE应用l常要以只读方式讉K大量长时间不变的数据Q而不是访问单个实体,例如览在线产品目录。在q种只读情况下,使用实体EJB讉K数据会导致严重过载ƈ且实现很ȝ。实体EJB 适合于对单个实体的粗_度讉KQ访问大量的列表只读数据时效率不高。不是使用CMPq是BMPQ一定需要编写代码操作多个实体EJB及其兌。这导致访问多个数据库q存在大量的也是不必要的事务开销?/p>

    利用Java Messaging Servce(消息服务)

            J2EE规范在JMS中提供了内置的异步处理服务。当涉及到系l需求时Q应该了解在什么情况下应该采用JMSq行异步处理的设计。一旦确定要执行一些异步处理,那么同步处理的Q务就应该少好Q将数据库密集的操作安排在稍后的异步处理中完成?/p>

    ~存JNDI Lookup查找

            很多操作在进行JNDI查找时要消耗大量资源。通常应该~存JNDI资源避免|络调用和某些处理的q蝲。可以缓存的JNDI查找包括Q?/p>

            EJB Home Interfaces

            Data Sources

            JMS Connection Factories

            JMS Destinations/Topics

            一些JNDI包实C~存功能。但是调用对EJBL口的narrowҎӞq种功能作用有限?/p>

            ~存查找的设计应该用共享的IntialContext实例Q尽构建它很麻烦。这是因为需要访问多U数据源Q包括应用资源文件JNDI.properties,pȝ属性的各项参数,传入到构造函数的各项参数?/p>

    zdygis 2006-09-02 14:31 发表评论
    ]]>
    Java性能优化技巧J2EE?转蝲)http://www.aygfsteel.com/zdygis/articles/67269.htmlzdygiszdygisSat, 02 Sep 2006 06:25:00 GMThttp://www.aygfsteel.com/zdygis/articles/67269.htmlhttp://www.aygfsteel.com/zdygis/comments/67269.htmlhttp://www.aygfsteel.com/zdygis/articles/67269.html#Feedback0http://www.aygfsteel.com/zdygis/comments/commentRss/67269.htmlhttp://www.aygfsteel.com/zdygis/services/trackbacks/67269.html J2EE?br />

        前面介绍的改善性能技巧适合于大多数Java应用Q接下来要讨论的问题适合于用JSP、EJB或JDBC的应用?br />

        2.1 使用~冲标记

        一些应用服务器加入了面向JSP的缓冲标记功能。例如,BEA的WebLogic Server?.0版本开始支持这个功能,Open Symphony工程也同h持这个功能。JSP~冲标记既能够缓冲页面片断,也能够缓冲整个页面。当JSP面执行Ӟ如果目标片断已经在缓冲之中,则生成该片断的代码就不用再执行。页面~冲捕获Ҏ定URL的请求,q缓冲整个结果页面。对于购物篮、目录以及门L站的主页来说Q这个功能极其有用。对于这cd用,面U缓冲能够保存页面执行的l果Q供后h使用?br />

        对于代码逻辑复杂的页面,利用~冲标记提高性能的效果比较明显;反之Q效果可能略逊一{V?br />

        2.2 始终通过会话Bean讉K实体Bean

        直接讉K实体Bean不利于性能。当客户E序q程讉K实体BeanӞ每一个getҎ都是一个远E调用。访问实体Bean的会话Bean是本地的Q能够把所有数据组l成一个结构,然后q回它的倹{?br />

        用会话Bean装对实体Bean的访问能够改q事务管理,因ؓ会话Bean只有在到达事务边界时才会提交。每一个对getҎ的直接调用生一个事务,容器在每一个实体Bean的事务之后执行一个“装?d”操作?br />

        一些时候,使用实体Bean会导致程序性能不佳。如果实体Bean的惟一用途就是提取和更新数据Q改成在会话Bean之内利用JDBC讉K数据库可以得到更好的性能?br />

        2.3 选择合适的引用机制

        在典型的JSP应用pȝ中,头、页脚部分往往被抽取出来,然后Ҏ需要引入页头、页脚。当前,在JSP面中引入外部资源的Ҏ主要有两U:include指oQ以及include动作?br />

    • include指oQ例?lt;%@ include file="copyright.html" %>。该指o在编译时引入指定的资源。在~译之前Q带有include指o的页面和指定的资源被合ƈ成一个文件。被引用的外部资源在~译时就定Q比q行时才定资源更高效?br />
    • include动作Q例?lt;jsp:include page="copyright.jsp" />。该动作引入指定面执行后生成的l果。由于它在运行时完成Q因此对输出l果的控制更加灵zR但Ӟ只有当被引用的内定wJ地改变Ӟ或者在对主面的请求没有出C前,被引用的面无法定Ӟ使用include动作才合?/li>

        2.4 在部|描q器中设|只d?/b>

        实体Bean的部|描q器允许把所有getҎ讄成“只诠Z。当某个事务单元的工作只包含执行d操作的方法时Q设|只d性有利于提高性能Q因为容器不必再执行存储操作?br />

        2.5 ~冲对EJB Home的访?/b>

        EJB Home接口通过JNDI名称查找获得。这个操作需要相当可观的开销。JNDI查找最好放入Servlet的init()Ҏ里面。如果应用中多处频繁地出现EJB讉KQ最好创Z个EJBHomeCachecREJBHomeCachecM般应该作为singleton实现?br />

        2.6 为EJB实现本地接口

        本地接口是EJB 2.0规范新增的内容,它得Bean能够避免q程调用的开销。请考虑下面的代码?br />

        

    																


    PayBeanHome home = (PayBeanHome)
    javax.rmi.PortableRemoteObject.narrow
    (ctx.lookup ("PayBeanHome"), PayBeanHome.class);
    PayBean bean = (PayBean)
    javax.rmi.PortableRemoteObject.narrow
    (home.create(), PayBean.class);



        W一个语句表C我们要LBean的Home接口。这个查N过JNDIq行Q它是一个RMI调用。然后,我们定位q程对象Q返回代理引用,q也是一个RMI调用。第二个语句C了如何创Z个实例,涉及了创建IIOPhq在|络上传输请求的stubE序Q它也是一个RMI调用?br />

        要实现本地接口,我们必须作如下修改:

    • Ҏ不能再抛出java.rmi.RemoteException异常Q包括从RemoteExceptionz的异常,比如TransactionRequiredException、TransactionRolledBackException和NoSuchObjectException。EJB提供了等L本地异常Q如TransactionRequiredLocalException、TransactionRolledBackLocalException和NoSuchObjectLocalException?br />
    • 所有数据和q回值都通过引用的方式传递,而不是传递倹{?br />
    • 本地接口必须在EJB部v的机器上使用。简而言之,客户E序和提供服务的lg必须在同一个JVM上运行?br />
    • 如果Bean实现了本地接口,则其引用不可串行化?/li>

        2.7 生成主键

        在EJB之内生成主键有许多途径Q下面分析了几种常见的办法以及它们的特点?br />

        利用数据库内建的标识机制QSQL Server的IDENTITY或Oracle的SEQUENCEQ。这U方法的~点是EJB可移植性差?br />

        由实体Bean自己计算主键|比如做增量操作)。它的缺Ҏ要求事务可串行化Q而且速度也较慢?br />

        利用NTP之类的时钟服务。这要求有面向特定^台的本地代码Q从而把Bean固定C特定的OS之上。另外,它还D了这样一U可能,卛_多CPU的服务器上,同一个毫U之内生成了两个主键?br />

        借鉴Microsoft的思\Q在Bean中创Z个GUID。然而,如果不求助于JNIQJava不能定|卡的MAC地址Q如果用JNIQ则E序p依赖于特定的OS?br />

        q有其他几种办法Q但q些办法同样都有各自的局限。似乎只有一个答案比较理惻Il合q用RMI和JNDI。先通过RMI注册把RMIq程对象l定到JNDI树。客L序通过JNDIq行查找。下面是一个例子:

        

    																


    public class keyGenerator extends UnicastRemoteObject implements Remote {
    private static long KeyValue = System.currentTimeMillis();
    public static synchronized long getKey() throws RemoteException { return KeyValue++; }



        2.8 及时清除不再需要的会话

        Z清除不再zd的会话,许多应用服务器都有默认的会话时旉Q一般ؓ30分钟。当应用服务器需要保存更多会话时Q如果内存容量不I操作pȝ会把部分内存数据转移到磁盘,应用服务器也可能Ҏ“最q最频繁使用”(Most Recently UsedQ算法把部分不活跃的会话转储到磁盘,甚至可能抛出“内存不”异常。在大规模系l中Q串行化会话的代h很昂늚。当会话不再需要时Q应当及时调用HttpSession.invalidate()Ҏ清除会话。HttpSession.invalidate()Ҏ通常可以在应用的退出页面调用?br />

        2.9 在JSP面中关闭无用的会话

        对于那些无需跟踪会话状态的面Q关闭自动创建的会话可以节省一些资源。用如下page指oQ?br />

        

    																


    <%@ page session="false"%>




        2.10 Servlet与内存?/b>

        许多开发者随意地把大量信息保存到用户会话之中。一些时候,保存在会话中的对象没有及时地被垃圑֛收机制回收。从性能上看Q典型的症状是用h到系l周期性地变慢Q却又不能把原因归于M一个具体的lg。如果监视JVM的堆I间Q它的表现是内存占用不正常地大v大落?br />

        解决q类内存问题主要有二U办法。第一U办法是Q在所有作用范围ؓ会话的Bean中实现HttpSessionBindingListener接口。这P只要实现valueUnbound()ҎQ就可以昑ּ地释放Bean使用的资源?br />

        另外一U办法就是尽快地把会话作废。大多数应用服务器都有设|会话作废间隔时间的选项。另外,也可以用~程的方式调用会话的setMaxInactiveInterval()ҎQ该Ҏ用来讑֮在作废会话之前,Servlet容器允许的客戯求的最大间隔时_以秒计?br />

        2.11 HTTP Keep-Alive

        Keep-Alive功能使客L到服务器端的q接持箋有效Q当出现Ҏ务器的后l请求时QKeep-Alive功能避免了徏立或者重新徏立连接。市Z的大部分Web服务器,包括iPlanet、IIS和ApacheQ都支持HTTP Keep-Alive。对于提供静态内容的|站来说Q这个功能通常很有用。但是,对于负担较重的网站来_q里存在另外一个问题:虽然为客户保留打开的连接有一定的好处Q但它同样媄响了性能Q因为在处理暂停期间Q本来可以释攄资源仍旧被占用。当Web服务器和应用服务器在同一台机器上q行ӞKeep-Alive功能对资源利用的影响其H出?br />

        2.12 JDBC与Unicode

        惛_你已l了解一些用JDBC时提高性能的措施,比如利用q接池、正地选择存储q程和直接执行的SQL、从l果集删除多余的列、预先编译SQL语句Q等{?br />

        除了q些显而易见的选择之外Q另一个提高性能的好选择可能是把所有的字符数据都保存ؓUnicodeQ代码页13488Q。Java以Unicode形式处理所有数据,因此Q数据库驱动E序不必再执行{换过E。但应该CQ如果采用这U方式,数据库会变得更大Q因为每个Unicode字符需?个字节存储空间。另外,如果有其他非Unicode的程序访问数据库Q性能问题仍旧会出玎ͼ因ؓq时数据库驱动程序仍旧必L行{换过E?br />

        2.13 JDBC与I/O

        如果应用E序需要访问一个规模很大的数据集,则应当考虑使用块提取方式。默认情况下QJDBC每次提取32行数据。D例来_假设我们要遍历一?000行的记录集,JDBC必须调用数据?57ơ才能提取到全部数据。如果把块大改?12Q则调用数据库的ơ数减到10ơ?br />

        在一些情形下q种技术无效。例如,如果使用可滚动的记录集,或者在查询中指定了FOR UPDATEQ则块操作方式不再有效?br />

        2.14 内存数据?/b>

        许多应用需要以用户为单位在会话对象中保存相当数量的数据Q典型的应用如购物篮和目录等。由于这cL据可以按照行/列的形式l织Q因此,许多应用创徏了庞大的Vector或HashMap。在会话中保存这cL据极大地限制了应用的可׾~性,因ؓ服务器拥有的内存臛_必须辑ֈ每个会话占用的内存数量乘以ƈ发用h大数量,它不仅服务器h格昂贵,而且垃圾攉的时间间隔也可能廉到难以忍受的E度?br />

        一些h把购物篮/目录功能转移到数据库层,在一定程度上提高了可伸羃性。然而,把这部分功能攑ֈ数据库层也存在问题,且问题的Ҏ与大多数关系数据库系l的体系l构有关。对于关pL据库来说Q运行时的重要原则之一是确保所有的写入操作E_、可靠,因而,所有的性能问题都与物理上把数据写入盘的能力有兟뀂关pL据库力图减少I/O操作Q特别是对于L作,但实现该目标的主要途径只是执行一套实现缓冲机制的复杂法Q而这正是数据库层W一h能瓉通常LCPU的主要原因?br />

        一U替代传l关pL据库的方案是Q用在内存中运行的数据库(In-memory DatabaseQ,例如TimesTen。内存数据库的出发点是允许数据时地写入Q但q些数据不必怹C存到盘上,所有的操作都在内存中进行。这P内存数据库不需要复杂的法来减I/O操作Q而且可以采用比较单的加锁机制Q因而速度很快?/p>

    zdygis 2006-09-02 14:25 发表评论
    ]]>
    վ֩ģ壺 | Ϫ| | | ˰| | ƽԶ| ƽ| | | Դ| ֦| | | Ϊ| ɽ| | | | | Һ| ȷ| | | ȫ| | | | Դ| | ½| γ| ֶ| ʩ| ֣| Դ| ˮ| | | ͩ| |