strArray1[i]=(newString("Array:
"+i));}
System.arraycopy(strArray1,0,strArray2,0,size);//
复制
同样的一个规则是,当有大量数据的复制时,应该使用
System.arraycopy()。
三、I/O性能
输入/输出(I/O)包括很多方面,我们知道,进行I/O操作是很费系统资源的。
程序
中应该尽量少用I/O操作。
使用时可以注意:
.合理控制输出函数System.out.println()
对于大多时候是有用的,特别是系统调试的时候,但也会产生大量的信息出现在控制台和日
志上,同时输出时,有序列化和同步的过程,造成了开销。
特别是在发行版中,要合理的控制输出,可以在项目开发时,设计好一个
Debug的工
具类,在该类中可以实现输出开关,输出的级别,根据不同的情况进行不同的输出的控制。
使用缓存
读写内存要比读写文件要快很多,应尽可能使用缓冲。
尽可能使用带有Buffer的类代替没有Buffer的类,如可以用BufferedReader代替
Reader,用BufferedWriter代替Writer来进行处理I/O操作。
同样可以用BufferedlnputStream
代替InputStream都可以获得性能的提高。
四、Servlet
Servlet采用请求响应模式提供Web服务,通过ServletResponse以及
ServletRequest这两个对象来输出和接收用户传递的参数,在服务器端处理用户的请求,
根据请求访问数据库、访问别的Servlet方法、调用EJB等等,然后将处理结果返回给客
户端。
尽量不使用同步
Servlet是多线程的,以处理不同的请求,基于前面同步的分析,如果有太多的同步就
失去了多线程的优势了。
不用保存太多的信息在HttpSession中
很多时候,存储一些对象在HttpSession中是有必要的,可以加快系统的开发,如网
上商店系统会把购物车信息保存在该用户的Session中,但当存储大量的信息或是大的对
象在会话中是有害的,特别是当系统中用户的访问量很大,对内存的需求就会很高。
具体开发时,在这两者之间应作好权衡。
清除Session
通常情况,当达到设定的超时时间时,同时有些Session没有了活动,服务器会释放
这些没有活动的Session,不过这种情况下,特别是多用户并访时,系统内存要维护多
个的无效Session。
当用户退出时,应该手动释放,回收资源,实现如下:
HttpSessiontheSession=request.getSession();〃获取当前Sessionif(theSession!
=null){theSession.invalidate();//
}
使该Session失效
五、EJB问题
EJB是Java服务器端服务框架的规范,软件厂商根据它来实现EJB服务器。
应用程序
开发者可以专注于支持应用所需的商业逻辑,
而不用担心周围框架的实现问题。
EJB规范详
细地解释了一些最小但是必须的服务,
如事务,安全和名字等。
缓存Home接口
EJB库使用EnterpriseBean
的客户端通过它的Home接口创建它的实例。
客户端
能通过JNDI访问它。
服务器通过
Lookup方法来获取。
JNDI是个远程对象,通过RMI方式调用,对它的访问往往是比较费时的。
所以,在
设计时可以设计一个类专门用来缓存Home接口,在系统初始化时就获得需要的Home接
口并缓存,以后的引用只要引用缓存即可。
封装EntityBean
直接访问EntityBean
改进事务管理,因为每一个对
是个不好的习惯,用会话Bean封装对实体Bean的访问能够
get方法的直接调用将产生一个事务,容器将在每一个实体
Bean的事务之后执行一个
“Load!
Store”.操作。
最好在SessionBean
中完成EntityBean的封装,减少容器的事务处理,并在
SessionBean中实现一些具体的业务方法。
释放有状态的SessionBean
相当于HttpSession,当把一个SessionBean设为Stateful,即有状态的Session
Bean后,应用容器(Container)就可能有钝化”(Passivate)和活化(Activate)过
程,即在主存和二级缓存之间对SessionBean进行存储位置的转移,在这个过程中,存在序列化过程。
通常有状态SessionBean的释放是在超时时发生,容器自动的清除该对象,但是如
维护一份该
果交给容器管理,一方面可能产生对象钝化,另一方面未超时期间,系统还要
对象,所以如果我们确认使用完该StatefulSessionBean后不再需要时,可以显式的将其释放掉,方法是调用:
theSesionBean.remove。
;
六、数据库访问
在J2EE开发的应用系统中,数据库访问一般是个必备的环节。
数据库用来存储业务数据,供应用程序访问。
在Java技术的应用体系中,应用程序是通过JDBC(JavaDatabaseConnectivity
实现的接口来访问数据库的,JDBC支持建立连接、SQL语句查询、处理结果”等基本功
能。
在应用JDBC接口访问数据库的过程中,只要根据规范来实现,就可以达到要求的功能。
明明根据规范编写的程
但是,有些时候进行数据查询的效率着实让开发人员不如所愿,
序,
运行效果却很差,造成整个系统的执行效率不高。
使用速度快的JDBC驱动
JDBCAPI包括两种实现接口形式,一种是纯
Java实现的驱动,一种利用ODBC驱
动和数据库客户端实现,具体有四种驱动模式并各有不同的应用范围,针对不同的应用开发
要选择合适的JDBC驱动,在同一个应用系统中,如果选择不同的JDBC驱动,在效率上
会有差别。
例如,有一个企业应用系统,不要求支持不同厂商的数据库,这时就可以选择模式的JDBC驱动,该驱动一般由数据库厂商实现的基于本地协议的驱动,直接调用数据库管
理系统使用的协议,减少了模式3中的中间层。
使用JDBC连接池
为了提高访问数据库的性能,我们还可以使用
JDBC2.0的一些规范和特性,JDBC是
占用资源的,在使用数据库连接时可以使用连接池
ConnectionPooling,避免频繁打开、
是比较消耗系统资源的。
关闭Connection。
而我们知道,获取Connection
Connection缓冲池是这样工作的:
当一个应用程序关闭一个数据库连接时,这个连接并不真正释放而是被循环利用,建立连接是消耗较大的操作,循环利用连接可以显著的提高性能,因为可以减少新连接的建立。
一个通过DataSource获取缓冲池获得连接,并连接到一个CustomerDB数据源的代码演示如下:
Contextctx=newInitialContext();
DataSourcedataSource=(DataSource)ctx.lookup("jdbc/CustomerDB");
Connectionconn=
dataSource.getConnection(”password","username");
缓存DataSource
一个DataSource对象代表一个实际的数据源。
这个数据源可以是从关系数据库到表
格形式的文件,完全依赖于它是怎样实现的,一个数据源对象注册到JNDI名字服务后,应
用程序就可以从JNDI服务器上取得该对象,并使用之和数据源建立连接。
通过上面的例子,我们知道DataSource是从连接池获得连接的一种方式,通过JNDI
方式获得,是占用资源的。
为了避免再次的JNDI
调用,可以系统中缓存要使用的DataSource。
关闭所有使用的资源
系统一般是并发的系统,
在每次申请和使用完资源后,应该释放供别人使用,数据库资
源每个模式的含义可以参考
SUNJDBC的文档,不同是比较宝贵的,使用完成后应该保证
彻底的释放。
请看下面的代码段:
Connectionconn=nuII;
Statementstmt=null;
ResuItSetrs=null;
try{
DataSourcedataSource=getDataSource();
//取的DataSource的方法,实现略。
conn=datasource.getConnection();
stmt=conn.createStatement();
rs=stmt.executeQuery("SELECT*FROM...");
...//其他处理
rs.close();
stmt.close();
conn.close();
}catch(SQLExceptionex){
...//错误处理
粗看似乎没有什么问题,也有关闭相关如Connection等系统资源的代码,但当出现
异常后,关闭资源的代码可能并不被执行,为保证资源的确实已被关闭,应该把资源关闭的
代码放到finally块:
Connectionconn=nuII;
Statementstmt=null;
ResultSetrs=null;
try{
DataSourcedataSource=getDataSource();
//取的DataSource的方法,实现略。
conn=datasource.getConnection();
stmt=conn.createStatement();
rs=stmt.executeQuery("SELECT*FROM...");
...//其他处理
}catch(SQLExceptionex){
...//错误处理
}finally{
if(rs!
=null){
try{
rs.closeO;//关闭ResultSet}
catch(SQLExceptionex){
...//错误处理
}
}
if(stmt!
=null){
try{
stmt.close();//关闭Statement}catch(SQLExceptionex){
...//错误处理
}
}
if(conn!
=null){
try{
conn.close();//关闭Connection}catch(SQLExceptionex){
...//错误处理
}
}
}
大型数据量处理
当我们在读取诸如数据列表、报表等大量数据时,可以发现使用
EJB的方法是非常慢
的,这时可以使用直接访问数据库的方法,用SQL直接存取数据,
从而消除EJB的经常开
支(例如远程方法调用、事务管理和数据序列化,对象的构造等)。
缓存经常使用的数据
对于构建的业务系统,如果有些数据要经常要从数据库中读取,
同时,这些数据又不经
常变化,这些数据就可以在系统中缓存起来,使用时直接读取缓存,
而不用频繁的访问数据
库读取数据。
缓存工作可以在系统初始化时一次性读取数据,
特别是一些只读的数据,当数据更新时
更新数据库内容,同时更新缓存的数据值。
一个例子是,在一套企业应用系统中,企业的信息数据(如企业的名称)在多个业务应用模块中使用,这时就可以把这些