ZhipSoft.com
    冬去春来
        郑重声明:本Blog纯属个人学习、工作需要,记录相关资料。请不要发表任何有人身攻击的言论,谢谢!!www.ZhipSoft.com
posts - 94,comments - 149,trackbacks - 0

 J2EE中的优化方案

1.使用StringBuffer代替String

String是用来存储字符串常量的,如果要执行“+”的操作,系统会生成一些临时的对象,并对这些对象进行管理,造成不必要的开销。

如果字符串有连接的操作,替代的做法是用StringBuffer类的append方法。

当字符串的大小超过缺省16时,代码实现了容量的扩充,为了避免对象的重新扩展其容量,那么最好用StringBuffer sb=new StringBuffer(30)

2.优化循环体

Vector vect = new Vector(1000);
for( inti=0; i<vect.size(); i++){
 ...
}

  for循环部分改写成:

int size = vect.size();
for( int i=0; i>size; i++){
 ...
}

如果size=1000,就避免了1000次的size()调用开销,避免了重复调用.

3.对象的创建

尽量少用new来初始化一个类的实例,当一个对象是用new进行初始化时,其构造函数链的所有构造函数都被调用到,所以new操作符是很消耗系统资源的,new一个对象耗时往往是局部变量赋值耗时的上千倍。同时,当生成对象后,系统还要花时间进行垃圾回收和处理。

当new创建对象不可避免时,注意避免多次的使用new初始化一个对象。

尽量在使用时再创建该对象。

NewObject object = new NewObject();
int value;
if(i>0 )
{
 value =object.getValue();
}

  可以修改为:

int value;
if(i>0 )
{
 NewObject object = new NewObject();
 Value =object.getValue();
}

4.慎用异常处理

  异常是Java的一种错误处理机制,对程序来说是非常有用的,但是异常对性能不利。抛出异常首先要创建一个新的对象,并进行相关的处理,造成系统的开销,所以异常应该用在错误处理的情况,不应该用来控制程序流程,流程尽量用while,if等处理。

在不是很影响代码健壮性的前提下,可以把几个try/catch块合成一个。

讨论:需要处理的异常处理和不需要处理的异常处理在捕捉异常类型上应该采取什么策略。

5.变量的使用

   尽量使用局部变量,调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack) 中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。

尽量使用静态变量,即加修饰符static,如果类中的变量不会随他的实例而变化,就可以定义为静态变量,从而使他所有的实例都共享这个变量。

(但是静态变量不能滥用,如果这个变量用的比较少而声明成静态变量,不仅效率不会提高,还会影响性能)

 

6.I/O操作

    输入/输出(I/O)包括很多方面,我们知道,进行I/O操作是很费系统资源的。程序中应该尽量少用I/O操作。使用时可以注意: . 合理控制输出函数System.out.println()对于大多时候是有用的,特别是系统调试的时候,但也会产生大量的信息出现在控制台和日志上,同时输出时,有序列化和同步的过程,造成了开销。

    特别是在发行版中,要合理的控制输出,可以在项目开发时,设计好一个Debug的工具类,在该类中可以实现输出开关,输出的级别,根据不同的情况进行不同的输出的控制。

    我们在调试程序的时候,我们喜欢用System.out.println()这样的打印语句来跟踪我们的错误。但在程序发布的时候我们却没有把这样的语句都删除掉,在项目的运行中,也会影响效能。

7.使用缓存

  读写内存要比读写文件要快很多,应尽可能使用缓冲。

  尽可能使用带有Buffer的类代替没有Buffer的类,如可以用BufferedReader 代替Reader,用BufferedWriter代替Writer来进行处理I/O操作。

同样可以用BufferedInputStream代替InputStream都可以获得性能的提高。
 
8.Servlet的效率问题

  Servlet采用请求——响应模式提供Web服务,通过ServletResponse以及ServletRequest这两个对象来输出和接收用户传递的参数,在服务器端处理用户的请求,根据请求访问数据库、访问别的Servlet方法、调用EJB等等,然后将处理结果返回给客户端。

  ·尽量不使用同步

Servlet是多线程的,以处理不同的请求,基于前面同步的分析,如果有太多的同步就失去了多线程的优势了。

同步大多数使用在一个完整的事务中,避免事务中多方操作而引起的数据不同步现象。能用逻辑控制的尽量的用逻辑控制。

  ·不用保存太多的信息在HttpSession中

  很多时候,存储一些对象在HttpSession中是有必要的,可以加快系统的开发,如网上商店系统会把购物车信息保存在该用户的Session中,但当存储大量的信息或是大的对象在会话中是有害的,特别是当系统中用户的访问量很大,对内存的需求就会很高。

具体开发时,在这两者之间应作好权衡。

我们在写web应用时,经常只需要request的地方而使用了session,这样会是效率大大的降低的。但是我们用到了session,在项目的开发中又不能很好的利用session,这样对效率都是有影响的。比如说,我们把用户信息放在了session中,但是我们有时候在判断用户是否登录的时候,我们倾向去数据库里查这个是否有这个用户,又是用了request,但是这样是没有必要的,因为我们只需要判断session就行了。如果并发数量比较大的时候,服务器的负载就会过重。

  ·清除Session

  通常情况,当达到设定的超时时间时,同时有些Session没有了活动,服务器会释放这些没有活动的Session,.. 不过这种情况下,特别是多用户并访时,系统内存要维护多个的无效Session。

  当用户退出时,应该手动释放,回收资源,实现如下:..

HttpSession theSession = request.getSession();
// 获取当前Session
if(theSession != null){
 theSession.invalidate(); // 使该Session失效
}

9.数据库的操作

在J2EE开发的应用系统中,数据库访问一般是个必备的环节。数据库用来存储业务数据,供应用程序访问。

  在Java技术的应用体系中,应用程序是通过JDBC(Java Database Connectivity)实现的接口来访问数据库的,JDBC支持“建立连接、SQL语句查询、处理结果”等基本功能。在应用JDBC接口访问数据库的过程中,只要根据规范来实现,就可以达到要求的功能。

  但是,有些时候进行数据查询的效率着实让开发人员不如所愿,明明根据规范编写的程序,运行效果却很差,造成整个系统的执行效率不高。

  ·使用速度快的JDBC驱动

  JDBC API包括两种实现接口形式,一种是纯Java实现的驱动,一种利用ODBC驱动和数据库客户端实现,具体有四种驱动模式并各有不同的应用范围,针对不同的应用开发要选择合适的JDBC驱动,在同一个应用系统中,如果选择不同的JDBC驱动,在效率上会有差别。

例如,有一个企业应用系统,不要求支持不同厂商的数据库,这时就可以选择模式4的JDBC驱动,该驱动一般由数据库厂商实现的基于本地协议的驱动,直接调用数据库管理系统使用的协议,减少了模式3中的中间层。

  ·使用JDBC连接池

  为了提高访问数据库的性能,我们还可以使用JDBC 2.0的一些规范和特性,JDBC是占用资源的,在使用数据库连接时可以使用连接池Connection Pooling,避免频繁打开、关闭Connection。而我们知道,获取Connection是比较消耗系统资源的。

  Connection缓冲池是这样工作的:当一个应用程序关闭一个数据库连接时,这个连接并不真正释放而是被循环利用,建立连接是消耗较大的操作,循环利用连接可以显著的提高性能,因为可以减少新连接的建立。

  一个通过DataSource获取缓冲池获得连接,并连接到一个CustomerDB数据源的代码演示如下:

Context ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup("jdbc/CustomerDB");
Connection conn = dataSource.getConnection("password","username");

  ·缓存DataSource

  一个DataSource对象代表一个实际的数据源。这个数据源可以是从关系数据库到表格形式的文件,完全依赖于它是怎样实现的,一个数据源对象注册到JNDI名字服务后,应用程序就可以从JNDI服务器上取得该对象,并使用之和数据源建立连接。

  通过上面的例子,我们知道DataSource是从连接池获得连接的一种方式,通过JNDI方式获得,是占用资源的。

  为了避免再次的JNDI调用,可以系统中缓存要使用的DataSource。

  ·关闭所有使用的资源

  系统一般是并发的系统,在每次申请和使用完资源后,应该释放供别人使用,数据库资源每个模式的含义可以参考SUN JDBC的文档,不同是比较宝贵的,使用完成后应该保证彻底的释放。

  请看下面的代码段:

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
 DataSource dataSource = getDataSource();
 // 取的DataSource的方法,实现略。
 conn = datasource.getConnection();
 stmt = conn.createStatement();
 rs = stmt.executeQuery("SELECT * FROM ...");
 ... // 其他处理
 rs.close();
 stmt.close();
 conn.close();
}catch (SQLException ex) {
 ... // 错误处理
}

  粗看似乎没有什么问题,也有关闭相关如Connection等系统资源的代码,但当出现异常后,关闭资源的代码可能并不被执行,为保证资源的确实已被关闭,应该把资源关闭的代码放到finally块:

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
 DataSource dataSource = getDataSource();
 // 取的DataSource的方法,实现略。
 conn = datasource.getConnection();
 stmt = conn.createStatement();
 rs = stmt.executeQuery("SELECT * FROM ...");

 ... // 其他处理
}catch (SQLException ex) {
 ... // 错误处理

}finally{
 if (rs!=null) {
  try {
   rs.close(); // 关闭ResultSet}
  catch (SQLException ex) {
   ... // 错误处理
  }
 }

 if (stmt!=null){
  try {
   stmt.close(); // 关闭Statement}
  catch (SQLException ex) {
   ... // 错误处理
  }
 }
 if (conn!=null){
  try {
   conn.close(); // 关闭Connection}
  catch (SQLException ex) {
   ... // 错误处理
  }
 }
}

  ·大型数据量处理

  当我们在读取诸如数据列表、报表等大量数据时,可以发现使用EJB的方法是非常慢的,这时可以使用直接访问数据库的方法,用SQL直接存取数据,从而消除EJB的经常开支(例如远程方法调用、事务管理和数据序列化,对象的构造等)。

  ·缓存经常使用的数据

  对于构建的业务系统,如果有些数据要经常要从数据库中读取,同时,这些数据又不经常变化,这些数据就可以在系统中缓存起来,使用时直接读取缓存,而不用频繁的访问数据库读取数据。

  缓存工作可以在系统初始化时一次性读取数据,特别是一些只读的数据,当数据更新时更新数据库内容,同时更新缓存的数据值。

一个例子是,在一套企业应用系统中,企业的信息数据(如企业的名称)在多个业务应用模块中使用,这时就可以把这些数据缓存起来,需要时直接读取缓存的企业信息数据。

我们经常使用Hibernate这样的持久数据层的框架,就很好的利用了缓存的作用,所以在一定程度上弥补了封装而带来的效率丢失问题。但是在使用缓存的时候应该注意,因为访问的内存数据而不是真实的数据库数据,所以会出现脏读的情况。同时也并不是所有的东西都应该放在缓存中,不经常用到的我们就没有必要放在缓存中。有时候我们配合xml文件来使用,也不失一种好的方法。

 

一般意义上说,参与系统运行的代码都会对性能产生影响,实际应用中应该养成良好的编程规范、编写高质量的代码,当系统性能出现问题时,要找到主要影响性能的瓶颈所在,然后集中精力优化这些代码,能达到事半功倍的效果。

  J2EE性能的优化包括很多方面的,要达到一个性能优良的系统,除了关注代码之外,还应该根据系统实际的运行情况,从服务器软硬件环境、集群技术、系统构架设计、系统部署环境、数据结构、算法设计等方面综合考虑。

 



        本Blog纯属个人学习、工作需要,记录相关资料。请不要发表任何有人身攻击的言论,谢谢! www.zhipsoft.cn
posted on 2007-06-12 08:49 ZhipSoft 阅读(520) 评论(0)  编辑  收藏 所属分类: Java

只有注册用户登录后才能发表评论。


网站导航: