`
tolys
  • 浏览: 118227 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

J2EE应用程序中的性能提升

阅读更多
Java很热门,尽管只诞生了9年,但它已经成为世界上领先的开发环境之一。数百万的程序员和数千家公司都在使用它,而且半数IT管理者都希望在今年部署J2EE应用程序。


  但是Java的流行并不一定使之对于日益增长的Java代码开发人员变得容易。为了在生产上达到一个新的高度,程序员们逐渐在更大的团队中工作,而在他们当中,持续缩短开发周期始终很热门。每天,那些团队都要面对一个软件开发中的不变定律:您编写的代码越多,您就会碰到越多的bug——而且是浪费时间和降低应用程序质量和性能的bug。
  本文主要介绍了一个J2EE应用程序的性能调优和内存使用优化。我们设置使用 BEA WebLogic Application Server。我们将讨论以下几个方面:
  • 问题域
  • 调优Java虚拟机
  • HTTP session管理
  • 调优应用服务器
  • 编码标准:为未来放弃规则

问题域
  我们有一个如下设置的J2EE应用程序:

  • BEA WebLogic 6.1 Service Pack 5 作为应用/Web服务器。
  • 某个流行的RDBMS。对我们的讨论没有影响。
  • Model I Web Architecture。
  • 8个无状态EJB以及6个有状态EJB。
  • HTTP session拥有对有状态EJB的引用。
  • Database Connection Pool初始化为2,最大值为10。
  • 在Web层有大约120个servlet。
  • 基于XML/XSLT的体系结构。

问题
  应用程序有一个内存问题。当服务器启动时,内存使用率大约占全部可用物理内存的7~8%。随着时间的推移和更多地使用应用程序,内存使用率会增加到接近49~53%(7~10天一个周期)。
  如果用户通过点击左边菜单中的“Log off”按钮从他们的会话中注销,那么应用程序就会从服务器中删去所有的有状态bean。但是,如果一个用户仅仅只是关闭浏览器窗口,那它就不会删去那些bean,而会在容器中保留它们直到应用服务器重新启动为止。这样继续下去,内存中的EJB实例数量会增加到400个甚至更多。
  当BEA WebLogic Server装载了多于400个EJB时,Hotspot虚拟机会抛出一个OutOfMemory 异常。尽管看似还有更多内存可用,但这种情况还是会发生。

调优Java虚拟机
  当试图分配PermGeneration空间时,Hotspot虚拟机会抛出OutOfMemory异常。Hotspot虚拟机使用不同部分的内存。持久生成部分被用来储存类、方法以及运行的Java对象所使用的符号。持久生成部分的初始大小为1MB,最大值为64MB,1.3.1之前是32MB。
  要避免这种情况,我们可以通过一个Java虚拟机开关,使用下面的命令行来设置permGeneration空间。
java -server -XX:MaxPermSize=128M.
  注意,增加perm 最大值只是推迟了故障的发生。最终还是要靠您的应用程序去适当地清除无用的对象。另外,并非所有的Java虚拟机都支持XX选项。

HTTP Session 管理
  当用户没有从会话中注销就关闭浏览器时,用户会话中的EJB不会被垃圾收集。这就是内存中有太多EJB的主要原因。要避免这种情况,HTTP session 管理必须注意所有可能的结合。我们可以在web.xml (Web应用程序部署描述符)中设置一个默认的会话超时周期,如下所示:

<session-config>
<session-timeout>x</session-timeout>
<session-config>

  通过这个设置,用户的会话会在不活动x分钟后自动释放。
  另一种方法是在创建HTTP session时用下面的代码编写会话管理

HttpSession session=new HttpSession ();
session.setmaxinactiveinternal(int timeoutSeconds);

  这段代码会使不活动了timeoutSeconds时间的用户会话失效。
  注意:如果您把两个步骤都做了,那么在servlet代码中的值将覆盖在web.xml中设置的值。
  这两种方法惟一的不同点是第二种方法以秒作为参数,而 <session-timeout> 标记则是以分钟作为参数。通常,当会话失效后,logoff servlet/JSP 会用代码删去被特殊会话所引用的所有对象/对象图形的引用。但是当用户只是关闭浏览器时,就没有办法调用注销servlet/JSP。在这种情况下,即使会话已经失效,被封装的对象和对象图形会继续存在。当垃圾收集器试图对该会话进行垃圾收集时,它也会对所有这些封装对象进行收集。当我们有大对象时(拥有大的引用/数据的对象),我们也可以用HTTPSessionListener接口来进行同样的清除工作。

javax.servlet.http.HTTPSessionListener 接口
  该接口声明了下面两种回调方法:

Public void sessionCreated(HttpSessionEvent event);
Public void sessionDestroyed(HttpSessionEven event);

  这些方法在一个会话被创建/销毁前被调用。
  我们可以使用一个实现了这个接口的监听器类,并用这些回调方法来控制会话的创建和销毁。我们需要像下面这样在web.xml中注册我们的监听器类:

<listener>
<listener-class>MySessionListener</listener-class>
</listener>

  使用监听器类以及在web.xml文件中添加会话超时参数的好处是我们能对会话管理进行更多的控制。如果会话拥有大对象,那么在垃圾收集器清除这些对象之前,它的时间片可能会消失。在这种情况下,就需要等到下一个时间片才能清除这些对象。
  注意:我们所设计的应用程序只有一个进入点是很重要的。我们需要在这个类中启动一个新的 HTTP session。所有余下的页面应该检查 HTTP session 是否存在,并且当会话为null时(Session 到期)调入一个错误页面。这样就可以实现对 HTTP session 的集中控制。

调优应用服务器
  BEA WebLogic 提供了一些参数,我们能用它们优化bean池的大小,这包括设置无状态bean 池的初始大小。以下是一些使用方法:

  • 用 <initial-bean-pool-size> 标记为无状态会话 bean设置 bean 池的最小值:默认情况下,这个值是1000。因为无状态会话bean可以在并发用户之间共享,所以最好把这个值设置得特别小。该标记的合适值取决于并发用户以及应用程序的峰值载入情况。
  • 用 <max-beans-in-free-pool> 标记为有状态会话bean设置bean 池的最大值: 它的默认值没有被规定。该标记所设置的值会极大地影响到BEA WebLogic Server的激活与钝化机制。它的合适值取决于应用程序的流量。当池中bean的数量已经达到了阈值而又有一个对新bean实例的请求到达时,WebLogic Server会挑选池中一个或更多的bean来钝化。为钝化而挑选bean实例的算法是LRU(最近最少使用)或者NRU (最近没有使用)。
      如果达到了max-beans-in-cache且高速缓存中的EJB并没有正在使用,WebLogic Server会把其中某些bean钝化。尽管没用的bean还没有达到它们的 idle-timeout-seconds极限,但这也会发生。如果达到了max-beans-in-cache且高速缓存中的EJB正在被客户端使用,那么WebLogic Server就会抛出一个CacheFullException异常。
  • 用 <idle-timeout-seconds> 标记设置WebLogic Server在钝化一个空闲的有状态 会话 bean实例前所等待的时间:WebLogic Server会在从交换(swap)空间中删出bean之前等待同样长的时间。应该小心设置这个值,因为一旦从交换空间中删去钝化的实例,就没有办法重新获得该bean的状态了。

例如,考虑下面的设置

<idle-timeout-seconds>1200</idle-timeout-seconds>

  这个空闲bean实例将会在静止20分钟后被钝化。再过20分钟,这个bean实例会从硬盘上删去。现在,让我们假设在第41分钟用户调用了这个bean实例的一个方法。BEA WebLogic Server将会抛出错误,如程序清单1所示。

程序清单 1
: Bean has been deleted.
at weblogic.ejb20.swap.DiskSwap.read(DiskSwap.java:156) at
weblogic.ejb20.manager.StatefulSessionManager.getBean(StatefulSession Manager.java:242) at
weblogic.ejb20.manager.StatefulSessionManager.preInvoke(StatefulSessionManager.java:313)
at weblogic.ejb20.internal.BaseEJBLocalObject.preInvoke(BaseEJBLocalObject.java:113)
at
weblogic.ejb20.internal.StatefulEJBLocalObject.preInvoke(StatefulEJBLocalObject.java:126)
WebLogic 6.1 Service Pack 5提供了一个有用的标记来避免发生这种情况。这个标记如下所示:
<!-- The stateful session beans that are passivated to the disk will stay alive for this many seconds. After this interval, the passivated beans will be removed from the disk.
Used in: stateful-session-cache
Since: WebLogic Server 6.1 sp5
Default value: 600
-->
<! ELEMENT session-timeout-seconds (#PCDATA)>

  如果我们为这个<session-timeout-seconds>设置值,我们就能控制钝化的bean何时从硬盘中被删去。我们可以使用这个标记并把它设置到一个适当的值,这样我们就能总是拥有有状态EJB(或者在内存中或者在硬盘中)。这将完全消除bean被删除的错误。

使用WebLogic被管理服务器
  BEA WebLogic 允许您在单独一个域中创建一个或多个服务器。一个服务器是管理服务器,所有其它服务器是被管理服务器,也就是被管理服务器管理。一个应用程序投入使用后,不应该被部署在管理服务器上。使用被管理服务器的好处是我们能从管理控制台上启动和停止它们。因此,即使服务器使应用程序停止响应(任何的原因),我们还是可以有机会从管理控制台重新启动服务器。
编码标准:为未来放弃规则
  当系统的运行环境并没有在设计阶段考虑到时,管理一个开发系统会更加困难。当在设计阶段认真考虑了环境、边界、应用程序的运行环境后,系统再开发将是一项简单的任务。设计是执行路径的抽象定义。当考虑了设计中的每一个细节后再开发,解决方案会更具可伸缩性。对于系统开发并没有硬性的规定,因为这取决于您正面对的特定问题域。但是,还是有一些总会有帮助的定律。

  • 对于补充类比如String 和 StringBuffer要有清晰的认识: 在合适的情况下用合适的类。例如,用String类构建一个长SQL查询是效率很低的,并加重JVM string池的负荷。
  • 在您使用完继承对象后立即清除它们,比如 Hashtable。
  • 在EJB引用中显式地调用 remove() 方法:这会把bean实例释放到bean池中,并减少由容器创建的bean实例数量。
  • 小心地管理数据库连接:在您使用完后立即调用close()方法。不要在类的第一行就打开连接。而只在需要的时候才打开连接。
  • 理解业务需求,并在您编写第一行代码之前就了解代码的执行环境。

  总之一句话,”尽可能晚的创建对象而尽可能早的删除它们”。

原文出处 http://www.sys-con.com/story/?storyid=43039&DE=1

 
分享到:
评论

相关推荐

    构建J2ee应用程序

    **构建J2EE应用程序** Java 2 Enterprise Edition (J2EE) 是一个强大的平台,用于开发和部署企业级应用程序。它提供了多种服务、APIs和工具,以支持分布式多层架构,尤其适合处理高并发、大数据量和复杂业务逻辑的...

    JBuilder2006开发J2EE应用程序

    在J2EE应用程序开发中,EJB(Enterprise JavaBeans)是核心部分。本教程将详细讲解如何在JBuilder2006中创建、部署和测试EJB组件,包括session beans、entity beans和message-driven beans。同时,还会探讨如何利用...

    J2EE 应用系统调优

    在J2EE应用架构中,调优的第一步通常是针对应用程序本身进行优化。这包括通用代码调优、异常处理、类型选择和利用池、缓冲区及缓存。对于代码级优化,应避免不必要的对象创建,尽量减少对象生命周期,如使用克隆或...

    精通J2EE应用程序开发

    Ted Neward在《精通J2EE应用程序开发》中提出了五种类型的企业Java应用程序: 1. **烟囱应用**(Chimney Applications):这类应用通常为单个部门或特定功能定制,与其他系统隔离。 2. **宝石应用**(Gem ...

    构建高性能J2EE应用的5种策略

    构建高性能的J2EE应用程序是IT领域中的一个重要挑战,尤其在当前大数据和高并发的背景下。J2EE(Java 2 Platform, Enterprise Edition)作为企业级应用开发的标准平台,提供了丰富的中间件服务和组件模型,使得...

    J2EE程序的性能优化技巧

    本文将深入探讨J2EE程序性能优化的一些关键技术和策略。 一、概要 J2EE平台的核心在于其分层架构,它支持分布式计算,简化了应用开发。通过使用应用程序服务器,开发者可以专注于业务逻辑,而由服务器负责事务管理...

    J2EE应用服务器标准

    标题和描述均提到了“J2EE应用服务器标准...总之,J2EE应用服务器标准是现代企业级应用开发的基石,它通过提供标准化的框架、工具和技术,极大地提升了应用的开发效率、安全性和可扩展性,是IT行业中不可或缺的一部分。

    开发高性能j2ee应用, 最佳实践

    在开发高性能的J2EE应用程序时,首先需要理解“可扩展性”(Scalability)这一概念。可扩展性指的是系统能够随着资源的增加而提高吞吐量的能力。例如,在多核架构中添加更多核心后,应用服务器可以处理更多的事务...

    一个用于J2EE应用程序的Backbase Ajax前端

    它的Ajax前端,即Backbase Presentation Client(BPC),是针对J2EE应用程序设计的,能为这些应用程序添加动态和交互性的用户体验。 **Ajax技术的核心特点** Ajax的核心在于其异步特性,它通过JavaScript和...

    Spring 简介 轻量级的J2EE 应用程序框架

    1. **轻量级容器**:Spring框架的核心是一个轻量级容器,它实现了IoC(Inversion of Control,控制反转)模式,使得应用程序中的依赖关系由框架本身负责管理。 2. **IoC与DI**:IoC是一种设计理念,核心思想是将...

    J2EE_应用程序部署每台应用程序服务器上部署一个应用程序还是多个应用程序?[参照].pdf

    【J2EE应用程序部署策略】在软件开发领域,特别是针对J2EE平台的应用,部署策略是一个重要的考虑因素。J2EE规范定义了如何打包应用程序为EAR文件,但并未明确指出最佳部署方式。开发者面临的选择是在每台应用程序...

    J2EE应用开发实践 .rar

    在IT行业中,J2EE(Java 2 Platform, Enterprise Edition)是Java平台企业版的简称,是一个用于构建可扩展、分布式、多层的企业级应用程序的标准框架。本实践指南将深入探讨J2EE的核心概念和技术,以及如何将其应用...

    J2EE 应用与 BEA WebLogic Server

    J2EE(Java 2 Platform, Enterprise Edition)是一种由Oracle公司(原Sun Microsystems)推出的用于构建企业级分布式应用程序的平台。它提供了一套规范和服务,包括Servlet、JSP(JavaServer Pages)、EJB...

    J2EE_应用程序部署每台应用程序服务器上部署一个应用程序还是多个应用程序?定义.pdf

    在J2EE(Java 2 Platform, Enterprise Edition)架构中,应用程序部署策略的选择是一项关键的任务,直接关系到系统的性能、资源利用率以及...只有这样,才能确保J2EE应用程序在生产环境中的高可用性和良好的用户体验。

    应用OSCache提升J2EE系统运行性能

    这种技术被称为缓存,是提升Web应用程序性能的关键策略之一。 描述中提到的“性能测试结果”,暗示了在应用OSCache前后进行了对比测试。通常,这种测试会包括响应时间、并发用户数、TPS(每秒事务处理量)等关键...

    Oracle_9i_JDeveloper开发手册——构建J2EE应用程序

    Oracle 9i JDeveloper是一款专为Java编程设计的集成开发环境(IDE),它在构建J2EE应用程序方面具有显著优势。这款工具集成了多种功能,包括设计、开发、调试和部署,涵盖了Java语言及其在企业级应用中的各种组件。...

    Hibernate+Struts的J2EE应用开发2

    综上所述,结合Hibernate和Struts框架的J2EE应用开发策略不仅能够提高开发效率,还能显著降低代码耦合性,为构建高性能、易维护的企业级应用提供了有力的支持。在未来的发展过程中,随着更多新技术的出现,这种组合...

    构建高性能J2EE应用的十个技巧

    构建高性能的J2EE应用程序是IT领域中的一个重要挑战,它涉及到多个层面的技术优化。以下是根据标题和描述中提及的关键知识点进行的详细说明: 1. **内存管理**:J2EE应用性能的基础在于如何有效地管理内存。减少...

    精通BEA WebLogic Server——构建与部署J2EE应用的最佳策略

    《精通BEA WebLogic Server——构建与部署J2EE应用的最佳策略》这本书是针对企业级Java开发者和系统管理员的一份重要指南,它深入探讨了如何有效地利用BEA WebLogic Server来构建、部署以及管理J2EE(Java 2 ...

Global site tag (gtag.js) - Google Analytics