欧冠

“快”在细节 J2EE程序的性能优化技巧3

2019-09-13 19:23:21来源:励志吧0次阅读

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

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

HttpSession theSession = request.getSession();

// 获取当前Session

if(theSession != null){

theSession.invalidate(); // 使该Session失效

}

五、EJB 问题

EJB是Java服务器端服务框架的规范,软件厂商根据它来实现EJB服务器。应用程序开发者可以专注于支持应用所需的商业逻辑,而不用担心周围框架的实现问题。EJB规范详细地解释了一些最小但是必须的服务,如事务,安全和名字等。

·缓存Home接口

EJB库使用Enterprise Bean 的客户端通过它的Home接口创建它的实例。客户端能通过JNDI访问它。服务器通过Lookup方法来获取。

JNDI是个远程对象,通过RMI方式调用,对它的访问往往是比较费时的。所以,在设计时可以设计一个类专门用来缓存Home接口,在系统初始化时就获得需要的Home接口并缓存,以后的引用只要引用缓存即可。

·封装Entity Bean

直接访问Entity Bean是个不好的习惯,用会话Bean封装对实体Bean的访问能够改进事务管理,因为每一个对get方法的直接调用将产生一个事务,容器将在每一个实体Bean的事务之后执行一个“Load-Store”.. 操作。

最好在Session Bean中完成Entity Bean的封装,减少容器的事务处理,并在Session Bean中实现一些具体的业务方法。

·释放有状态的Session Bean

相当于HttpSession,当把一个Session Bean设为Stateful,即有状态的Session Bean 后,应用容器(Container)就可能有“钝化”(Passivate)和活化(Activate)过程,即在主存和二级缓存之间对SessionBean进行存储位置的转移,在这个过程中,存在序列化过程。

通常有状态Session Bean的释放是在超时时发生,容器自动的清除该对象,但是如果交给容器管理,一方面可能产生对象钝化,另一方面未超时期间,系统还要 维护一份该对象,所以如果我们确认使用完该StatefulSession Bean后不再需要时,可以显式的将其释放掉,方法是调用:

theSesionBean.remove();

六、数据库访问

在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) {

... // 错误处理

}

}

}

糖尿病胃轻瘫便秘多久好
宝宝不消化食疗法
孩子感冒发烧怎么办
小孩发烧了怎么办如何退烧
分享到: