首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网页制作-> Dreamweaver教程
Java程序性能测试-JSP教程,Java技巧及代码
作者:网友供稿 点击:432
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
1 概述
在开发中,性能测试是设计初期容易忽略的问题,开发人员会为了解决一个问题而“不择手段”,作者所参与的项目中也遇到了类似问题,字符串拼接、大量的网络调用和数据库访问等等都对系统的性能产生了影响,可是大家不会关心这些问题,“cpu速度在变快”,“内存在变大”,并且,“好像也没有那么慢吧”。

有很多商业的性能测试软件可供使用,如jprofiler、jprobe profiler等,但在开发当中显得有些遥远而又昂贵。

2 目标
本文将讲述如何利用java语言本身提供的方法在开发中进行性能测试,找到系统瓶颈,进而改进设计;并且在尽量不修改测试对象的情况下进行测试。

3 预备知识
面向对象编程通过抽象继承采用模块化的思想来求解问题域,但是模块化不能很好的解决所有问题。有时,这些问题可能在多个模块中都出现,像日志功能,为了记录每个方法进入和离开时的信息,你不得不在每个方法里添加log("in some method")等信息。如何解决这类问题呢?将这些解决问题的功能点散落在多个模块中会使冗余增大,并且当很多个功能点出现在一个模块中时,代码变的很难维护。因此,aop(aspect oriented programming)应运而生。如果说oop(aobject oriented programming)关注的是一个类的垂直结构,那么aop是从水平角度来看待问题。

动态代理类可以在运行时实现若干接口,每一个动态代理类都有一个invocation handler对象与之对应,这个对象实现了invocationhandler接口,通过动态代理的接口对动态代理对象的方法调用会转而会调用invocation handler对象的invoke方法,通过动态代理实例、方法对象和参数对象可以执行调用并返回结果。

说到aop,大家首先会想到的是日志记录、权限检查和事务管理,是的,aop是解决这些问题的好办法。本文根据aop的思想,通过动态代理来解决一类新的问题——性能测试(performance testing)。

性能测试主要包括以下几个方面:

l 计算性能:可能是人们首先关心的,简单的说就是执行一段代码所用的时间

l 内存消耗:程序运行所占用的内存大小

l 启动时间:从你启动程序到程序正常运行的时间

l 可伸缩性(scalability)

l 用户察觉性能(perceived performance):不是程序实际运行有多快,而是用户感觉程序运行有多快.

本文主要给出了计算性能测试和内存消耗测试的可行办法。



4 计算性能测试
4.1 目标:
通过该测试可以得到一个方法执行需要的时间

4.2实现:
java为我们提供了system. currenttimemillis()方法,可以得到毫秒级的当前时间,我们在以前的程序当中一定也写过类似的代码来计算执行某一段代码所消耗的时间。

long start=system.currenttimemillis();

dosth();

long end=system.currenttimemillis();

system.out.println("time lasts "+(end-start)+"ms");


但是,在每个方法里面都写上这么一段代码是一件很枯燥的事情,我们通过java的java.lang.reflect.proxy和java.lang.reflect.invocationhandler利用动态代理来很好的解决上面的问题。

我们要测试的例子是java.util.linkedlist和java.util.arraylist的get(int index)方法,显然arraylist要比linkedlist高效,因为前者是随机访问,而后者需要顺序访问。

首先我们创建一个接口

public interface foo {

public void testarraylist();

public void testlinkedlist();

}


然后我们创建测试对象实现这个接口

public class fooimpl implements foo {



private list link=new linkedlist();

private list array=new arraylist();



public fooimpl()

{

for(int i=0;i<10000;i++)

{

array.add(new integer(i));

link.add(new integer(i));

}

}



public void testarraylist()

{

for(int i=0;i<10000;i++)

array.get(i);

}



public void testlinkedlist()

{

for(int i=0;i<10000;i++)

link.get(i);

}

}


接下来我们要做关键的一步,实现invocationhandler接口

import java.lang.reflect.invocationhandler;

import java.lang.reflect.method;

import java.lang.reflect.*;



public class handler implements invocationhandler {



private object obj;



public handler(object obj) {

this.obj = obj;

}



public static object newinstance(object obj) {

object result = proxy.newproxyinstance(obj.getclass().getclassloader(),

obj.getclass().getinterfaces(), new handler(obj));



return (result);

}



public object invoke(object proxy, method method, object[] args) throws throwable {

object result;

try {

system.out.print("begin method " + method.getname() + "(");

for (int i = 0; args != null && i < args.length; i++) {



if (i > 0) system.out.print(",");

system.out.print(" " +

args[i].tostring());

}

system.out.println(" )");

long start=system.currenttimemillis();

result = method.invoke(obj, args);

long end=system.currenttimemillis();

system.out.println("the method "+method.getname()+" lasts "+(end-start)+"ms");

} catch (invocationtargetexception e) {

throw e.gettargetexception();

} catch (exception e) {

throw new runtimeexception

("unexpected invocation exception: " +

e.getmessage());

} finally {

system.out.println("end method " + method.getname());

}

return result;

}

}


最后,我们创建测试客户端,

public class testproxy {

public static void main(string[] args) {

try {

foo foo = (foo) handler.newinstance(new fooimpl());

foo.testarraylist();

foo.testlinkedlist();

} catch (exception e) {

e.printstacktrace();

}

}

}


运行的结果如下:

begin method testarraylist( )

the method testarraylist lasts 0ms

end method testarraylist

begin method testlinkedlist( )

the method testlinkedlist lasts 219ms

end method testlinkedlist


使用动态代理的好处是你不必修改原有代码fooimpl,但是一个缺点是你不得不写一个接口,如果你的类原来没有实现接口的话。

4.3扩展
在上面的例子中演示了利用动态代理比较两个方法的执行时间,有时候通过一次简单的测试进行比较是片面的,因此可以进行多次执行测试对象,从而计算出最差、最好和平均性能。这样,我们才能“加快经常执行的程序的速度,尽量少调用速度慢的程序”。



5 内存消耗测试
5.1 目标
当一个java应用程序运行时,有很多需要消耗内存的因素存在,像对象、加载类、线程等。在这里只考虑程序中的对象所消耗的虚拟机堆空间,这样我们就可以利用runtime 类的freememory()和totalmemory()方法。

5.2 实现
为了方便期间,我们首先添加一个类计算当前内存消耗。

class memory

{

public static long used()

{

long total=runtime.getruntime().totalmemory();

long free=runtime.getruntime().freememory();

return (total-free);

}

}


然后修改handler类的invoke()方法。

public object invoke(object proxy, method method, object[] args) throws throwable {

object result;

try {

system.out.print("begin method " + method.getname() + "(");

for (int i = 0; args != null && i < args.length; i++) {



if (i > 0) system.out.print(",");

system.out.print(" " +

args[i].tostring());

}

system.out.println(" )");

long start=memory.used();

result = method.invoke(obj, args);

long end=memory.used();

system.out.println("memory increased by "+(end-start)+"bytes");

} catch (invocationtargetexception e) {

throw e.gettargetexception();

} catch (exception e) {

throw new runtimeexception

("unexpected invocation exception: " +

e.getmessage());

} finally {

system.out.println("end method " + method.getname());

}

return result;

}


同时我们的测试用例也做了一下改动,测试同样一个显而易见的问题,比较一个长度为1000的arraylist和hashmap所占空间的大小,接口、实现如下:

public interface memoconsumer {

public void creatarray();

public void creathashmap();

}

public class memoconsumerimpl implements memoconsumer {



arraylist arr=null;

hashmap hash=null;



public void creatarray() {



arr=new arraylist(1000);

}

public void creathashmap() {

hash=new hashmap(1000);

}

}


测试客户端代码如下:

memoconsumer arraymemo=(memoconsumer)handler.newinstance(new memoconsumerimpl ());

arraymemo.creatarray();

arraymemo.creathashmap();


测试结果如下:

begin method creatarray( )

memory increased by 4400bytes

end method creatarray

begin method creathashmap( )

memory increased by 4480bytes

end method creathashmap


结果一幕了然,可以看到,我们只需要修改invoke()方法,然后简单执行客户端调用就可以了。

6 结束语
aop通过分解关注点和oop相得益彰,使程序更加简洁易懂,通过java语言本身提供的动态代理帮助我们很容易分解关注点,取得了较好的效果。不过测试对象必须实现接口在一定程度上限制了动态代理的使用,可以借鉴spring中使用的cglib来为没有实现任何接口的类创建动态代理。


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·用正则表达式过滤脚本的一些研究(asp.net + C#)-.NET教程,C#语言
·射频电路设计的困境及对策
·ASP.NET2.0下为GridView添加鼠标滑过(onmouseover、onmouseout)的行颜色高亮效果!-.NET教程,Asp.Net开发
·Java程序性能测试-JSP教程,Java技巧及代码
·利用JSP 2.0开发Web应用程序-JSP教程,Jsp/Servlet
·PHP模板引擎SMARTY-PHP教程,PHP应用
·.NET中的设计模式五:观察者模式-.NET教程,.NET Framework
·ultradev实例教程:5 做一个相对简单的网站后台(3)
·ASP.net 2.0 自定义控件的开发之数据分页 第二章-.NET教程,Asp.Net开发
·我的DataGrid嵌套DataList(未解决)-ASP教程,ASP应用
最新文章
·桌面壁纸站的建设_站长心得
·dotmore的法宝: 文中关联广告的未来_网赚技巧
·如何用10几个页面的e文小站做到月入350刀_网赚技巧
·fackbook创始人:脸谱是社交工具,而非社区_站长访谈
·搜搜客ceo:分类信息是人与人的价值流动_站长访谈
·丫客网李松:把实业工作和资本市场分开看_站长访谈
·windows xp中巧妙去掉多余的安全删除硬件图标_windows xp
·个人如何建站与站建好后期的运作_站长心得
·google沙盒效应产生的原因及其避免方法_google推广
·提高google adsense广告单价的投放方法 _google推广
相关主题
  • java程序员认证模拟题及详细分析(4)_java认证
  • java程序员认证模拟题及详细分析(3)_java认证
  • java程序员认证模拟题及详细分析(2)_java认证
  • java程序员认证模拟题及详细分析(1)_java认证
  • JAVA程序的性能优化-JSP教程,Java技巧及代码
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭