使用StringBuilder来连接字符串
出现字符串连接时应该使用StringBuilder/StringBuffer代替。
由于Java虚拟机不仅要花时间生成对象,以后可能还需要花时间对这些对象进行垃圾回收和处理,
因此,生成过多的对象将会给程序的性能带来很大的影响。
避免递归(无法避免时,使用尾递归代替头递归)
谨慎使用正则表达式
如果你不得不在计算密集的代码段中使用正则表达式,那么需要缓存Pattern的引用而避免重复编译:
static final Pattern HEAVY_REGEX = Pattern.compile("(((X)*Y)*Z)*");
使用一些流行的库,比如Apache Commons Lang也是一个很好的选择,特别是在字符串的操作方面。
循环内不要不断创建对象引用
例如:
for (int i = 1; i <= count; i++)
{
Object obj = new Object();
}
这种会导致内存中有count份Object对象引用存在,count很大的话,就耗费内存了
建议为改为:
Object obj = null;
for (int i = 0; i <= count; i++)
{
obj = new Object();
}
这样的话,内存中只有一份Object对象引用,
每次new Object()的时候,Object对象引用指向不同的Object罢了,
但是内存中只有一份,这样就大大节省了内存空间了。
基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组大小时才使用ArrayList
尽量在合适的场合使用单例
单例主要适用于以下三个方面:
(1)控制资源的使用,通过线程同步来控制资源的并发访问
(2)控制实例的产生,以达到节约资源的目的
(3)控制数据的共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信
将常量声明为static final,并以大写命名
编译期间会把这些放入常量池中,避免运行期间计算生成常量的值。
程序运行过程中避免使用反射
反射是Java提供给用户一个很强大的功能,功能强大往往意味着效率不高。
不建议在程序运行过程中使用尤其是频繁使用反射机制,特别是 Method的invoke方法,
确实有必要时,建议的做法是将需要反射加载的类在项目启动时通过反射实例化出一个对象并放入内存
用户只关心和对端交互的时候获取最快的响应速度,并不关心对端的项目启动花多久时间。
尽可能的使用栈变量
如果一个变量需要经常访问,那么你就需要考虑这个变量的作用域了。
static? local?还是实例变量?访问静态变量和实例变量将会比访问局部变量多耗费2-3个时钟周期
尽量减少对变量的重复计算
比如
for(int i=0;i<list.size();i++)
应修改为
for(int i=0,len=list.size();i<len;i++)
使用数据库连接池和线程池
多资源的close()建议分开操作
try {
XXX.close();
YYY.close();
} catch (Exception e) {
...
}
建议修改为:
try {
XXX.close();
} catch (Exception e) {
...
}
try {
YYY.close();
} catch (Exception e) {
...
}
集合初始化时指定大小
HashMap(初始大小为16)等集合有默认的大小以及扩容策略,一般为当容量达到初始大小的75%时便会触发扩容策略,而进行扩容时会消耗较多性能
总结:
1、能复用就复用:线程池、连接池、单例、final static
2、减少内存开销:StringBuffer、循环内new对象、多资源close分开try catch、避免使用反射
网友评论