Itoo V3.0很快就要结束了,功能上基本上开发完成了,但是放到jboss中部署的时候,使用时感觉特别的慢,如果是数据量多的话,就把慢这个词发挥到了极致.这个慢的问题有大部分是因为基础系统中使用了JPA级联导致的,每次查询的时候,只要有关联的表,都会全部查询出来,一下发出一大版的HQL
语句,看着也是挺吓人的.出来优化JPA级联问题,还可以从代码中下手,从以下的几个方面考虑.
(1)减少对象生命周期
对象的生命周期有这么一个计算公式:对象生命周期=销毁时间-创建时间
实际上减少对象生命周期有2个途径:尽早地销毁对象和尽量晚地创建对象.大多数人都只注意尽早地销毁对象,但是却很少人注意尽量晚地创建对象。特别是耗费内存比较大的对象应该尽量晚地被创建。只有真正需要的时候才开始创建它.除了对象以外,比如连接数据库。只有所有准备就绪的时候,才再连接数据库,使用完成数据库连接就立刻关闭。最短时间使用连接,包括数据流也一样
(2)线程启动得越早越好
当准备线程的工作都已经好了以后,创建线程,就要马上启动线程,线程启动得越早越能提前获取数据
(3)用字符代替单字符串
StringBuilderstr=new StringBuilder();
那么str.append("m")不如str.append(‘m‘)快
(4)StringBuilder可以连续增加
StringBuilder的append方法返回自身可以继续增加,无需重新获取StringBuilder对象
StringBuilderstr=new StringBuilder(); str.append("abc"); str.append("ddd");
可以写成
StringBuilderstr=new StringBuilder(); str.append("abc").append("ddd");
(5)无顺序遍历数组
其实有的时候遍历数组无关顺序,只需要把数组对象都遍历一遍即可
通常写法是
int[] a=newint[10000]; for(inti=0,len=a.length;i<len;i++){ int b=a[i]; //然后处理 }
其实我在无关顺序遍历数组的时候我这么写:
int[] a=newint[10000]; for(inti=-1,len=a.length;++i<len;){ int b=a[i]; //然后处理 }
有的时候这么写
int[] a=newint[10000]; for(inti=a.length;i>0;){ int b=a[--i]; //然后处理 }
充分利用++i或者--i.最后一个不用计算len,直接--i可以取值,比较的时候与常数0比较
(6)不要有多余的操作
Stringa=getA(),b=getB(); if(a!=null&&b!=null){ }
最好为
String a=getA(); if(a!=null){ String b=getB();//这样a为null,就不需要获取b了。 if(b!=null){ } }
还有像
if(getValue()!=2&&getValue()!=0){ ... }
直接写为
intvalue=getValue(); if(value!=2&&value!=0){ ... }
要调用方法浪费性能,其次是访问对象属性,最快是局部变量,利用下标访问数组系统还要判断越界问题也浪费性能.
(7)还有一些数组复制用‘system.arraycopy (),还有使用局部变量要比使用全局变量快。大家可以看不变性的String类源代码就知道了
(8)关于锁java有读写锁还有尝试获取锁的功能,可以参看ReadWriteLock类
(9)出现内存泄露,分析发现全局GC(Gabage Collection)频繁时,可以考虑检查代码中大List、Map、数组等处,使用相应的clean方法,减轻GC压力,提高GC效率。
(10)io操作频繁时,在finally代码中一定把outputStream.flush掉,在Web应用中尤其如此
全心全意为人名服务的软件,就不能让客户等待太久.