提升JSP页面响应速度的七大秘籍绝招


   步骤一:在servlet的init() 步骤中缓存数据
  当 利用服务器初始化servlet实例之后,为客户端 申请提供服务之前,它会调用这个servlet的init() 步骤 。在一个servlet的生命周期中,init() 步骤只会被调用一次 。通过在init() 步骤中缓存一些静态的数据或 实现一些 惟独求执行一次的、耗时的操作,就可大大地 普及系统性能 。

  例如,通过在init() 步骤中 构建一个JDBC衔接池是一个最佳例子, 假如我们是用jdbc2.0的DataSource接口来 获得数据库衔接,在通常的状况下,我们需求通过JNDI来 获得具体的数据源 。我们 可以 设想在一个具体的 利用中,假如每次SQL 申请都要执行一次JNDI 查问的话,那系统性能将会急剧 降落 。解决 步骤是如下代码,它通过缓存DataSource,使得下一次SQL调用时 依旧 可以 接续利用它:

  以下是 引用片段:
  public class ControllerServlet extends HttpServlet{
  private javax.sql.DataSource testDS = null;  
  public void init(ServletConfig config) throws ServletException {
  super.init(config);   
  Context ctx = null;  
  try{    
  ctx = new InitialContext();   
  testDS = (javax.sql.DataSource)ctx.lookup("jdbc/testDS");
  }catch(NamingException ne){ne.printStackTrace();}
  }catch(Exception e){e.printStackTrace();}
  } 
  public javax.sql.DataSource getTestDS(){ 
  return testDS; 
  } 
  ...
  ... 
  }

   步骤 2:禁止servlet和JSP 自动重载(auto-reloading)

  Servlet/JSP提供了一个有用的技术,即自动重载技术,它为开发人员提供了一个好的开发环境,当你转变servlet和JSP页面后而 毋庸重启 利用服务器 。但是,这种技术在产品运行阶段对系统的资源是一个极大的损耗,由于它会给JSP引擎的类装载器(classloader)带来极大的 累赘 。 因此关闭自动重载 性能对系统性能的 晋升是一个极大的协助 。

   步骤 3: 不要滥用HttpSession

  在众多 利用中,我们的程序需求 维持客户端的状态,以便页面中间 可以 彼此 联络 。但 可怜的是由于HTTP 存在天生无状态性,从而 无奈 保留客户端的状态 。 因此一般的 利用服务器都提供了session来 保留客户的状态 。在JSP 利用服务器中,是通过HttpSession对像来实现session的 性能的,但在容易的同时,它也给系统带来了不小的 累赘 。由于每当你 获得或更新session时,系统者要对它进行费时的序列化操作 。你 可以通过对HttpSession的以下几种 解决 模式来 晋升系统的性能 。

  假如没有必要,就应该关闭JSP页面中对HttpSession的缺省设置 。 假如你没有明确指定的话,每个JSP页面都会缺省地 缔造一个HttpSession 。假如你的JSP中不需求 使用session的话,那 可以通过如下的JSP页面 批示符来禁止它:

  以下是 引用片段:
  <%@ page session="false"%>

  不要在HttpSession中 存放大的数据对像:假如你在HttpSession中 存放大的数据对像的话,每当对它进行读写时, 利用服务器都将对其进行序列化,从而添加了系统的额外 累赘 。你在HttpSession中 存放的数据对像越大,那系统的性能就 降落得越快 。

  当你不需求HttpSession时,尽快地 开释它:当你不再需求session时,你 可以通过调用HttpSession.invalidate() 步骤来 开释它 。尽量将session的超时 工夫设得短丝毫:在JSP 利用服务器中,有一个缺省的session的超时 工夫 。当客户在这个 工夫之后没有进行任何操作的话,系统会将 有关的session自动从内存中 开释 。超时 工夫设得越大,系统的性能就会越低, 因此最好的 步骤便是尽量使得它的值 维持在一个较低的水平 。

   步骤 4: 将页面输出进行压缩

  压缩是解决数据冗余的一个好的 步骤,特殊是在网络带宽不够发达的今日 。有的阅读器 支撑gzip(GNU zip)进行来对HTML文件进行压缩,这种 步骤 可以戏剧性地削减HTML文件的下载 工夫 。 因此,假如你将servlet或JSP页面生成的HTML页面进行压缩的话,那消费者就会感觉页面阅读速度会十分快 。但 可怜的是,不是全部的阅读器都 支撑gzip压缩,但你 可以通过在你的程序中 审查客户的阅读器是不是 支撑它 。下面便是对于这种 步骤实现的一个代码片段:

  以下是 引用片段:
  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {
  OutputStream out = null;
  String encoding = request.getHeader("Accept-Encoding");  
  if (encoding != null && encoding.indexOf("gzip") != -1){
  request.setHeader("Content-Encoding" , "gzip");  
  out = new GZIPOutputStream(request.getOutputStream());
  } 
  else if (encoding != null && encoding.indexOf("comdivss") != -1){
  request.setHeader("Content-Encoding" , "comdivss");  
  out = new ZIPOutputStream(request.getOutputStream());
  }else{  
  out = request.getOutputStream();
  } 
  ... 
  ... 
  }

   步骤 5: 使用线程池

   利用服务器缺省地为每个不同的客户端 申请 缔造一个线程进行 解决,并为它们分派service() 步骤,当service() 步骤调用 实现后,与之相应的线程也随之 取缔 。由于 缔造和 取缔线程会 消费 定然的系统资源,这种缺省模式减低了系统的性能 。但所幸的是我们 可以通过 缔造一个线程池来转变这种状况 。

  另外,我们还要为这个线程池设置一个最小线程数和一个最大线程数 。在 利用服务器启动时,它会 缔造数量等于最小线程数的一个线程池,当客户有 申请时,相应地从池从 存入一个线程来进行 解决,当 解决 实现后,再将线程再一次放入到池中 。假如池中的线程不够地话,系统会自动地添加池中线程的数量,但总量不能超过最大线程数 。通过 使用线程池,当客户端 申请急剧添加时,系统的负载就会出现的平滑的 回升曲线,从而 普及的系统的可伸缩性 。

   步骤 6: 取舍正确的页面包括机制

  在JSP中有两种 步骤 可以用来包括另一个页面:

  1、 使用include 批示符

  以下是 引用片段:
  <%@ includee file=”test.jsp” %>

  2、 使用jsp 批示符

  以下是 引用片段:
  <jsp:includee page=”test.jsp” flush=”true”/>

  在实际中发现,假如 使用第一种 步骤的话, 可以使得系统性能更高 。

   步骤 7:正确地确定javabean的生命周期

  JSP的一个 壮大的地方便是对javabean的 支撑 。通过在JSP页面中 使用jsp:useBean标签, 可以将javabean直接插入到一个JSP页面中 。它的 使用 步骤如下:

  以下是 引用片段:
  <jsp:useBean id="name" scope="page|request|session|application" 
  class="package.className" type="typeName">
  </jsp:useBean>

  其中scope属性指出了这个bean的生命周期 。缺省的生命周期为page 。假如你没有正确地 取舍bean的生命周期的话,它将影响系统的性能 。

  举例来说,假如你只想在一次 申请中 使用某个bean,但你却将这个bean的生命周期设置成了session,那当这次 申请 完毕后,这个bean将 依旧保留在内存中,除非session超时或消费者关闭阅读器 。这样会 消费 定然的内存,并无谓的添加了JVM垃圾收集器的工作量 。 因此为bean设置正确的生命周期,并在bean的使命 完毕后尽快地清理它们,会 使用系统性能有一个 普及 。

  其它一些有用的 步骤

  1、在字符串衔接操作中尽量不 使用“+”操作符:在java编程中,我们 一般 使用“+”操作符来将几个字符串衔接起来,但你兴许 向来没有想到过它竟然会对系统性能造成影响吧?由于字符串是常量, 因此JVM会产生一些暂时的对像 。你 使用的“+”越多,生成的暂时对像就越多,这样也会给系统性能带来一些影响 。解决的 步骤是用StringBuffer对像来 接替“+”操作符 。

  2、幸免 使用System.out.println() 步骤:由于System.out.println()是一种同步调用,即在调用它时,磁盘I/O操作必须期待它的 实现, 因此我们要尽量幸免对它的调用 。但我们在调试程序时它又是一个必不可少的容易工具,为了解决这个矛盾,我 提议你最好 使用Log4j工具(http://Jakarta.apache.org ),它既 可以容易调试,而不会产生System.out.println()这样的 步骤 。

  3、ServletOutputStream 与 PrintWriter的 衡量: 使用PrintWriter可能会带来一些小的开销,由于它将全部的原始输出都转换为字符流来输出, 因此假如 使用它来作为页面输出的话,系统要 累赘一个转换过程 。而 使用ServletOutputStream作为页面输出的话就不存在一个问题,但它是以二进制进行输出的 。 因此在实际 利用中要 衡量两者的利弊 。

  总结

  本文的 目标是通过对servlet和JSP的一些调优技术来极大地 普及你的 利用程序的性能,并 因此 晋升整个J2EE 利用的性能 。通过这些调优技术,你 可以发现其实并不是某种技术平台( 比方J2EE和.NET之争)决定了你的 利用程序的性能,主要是你要对这种平台有一个较为 深刻的了解,这样你 威力从 根本上对自己的 利用程序做一个优化 。