转载自:http://www.open-open.com/lib/view/open1399884636989.html#_label20
1.没有必要时不要使用静态变量
使用静态变量的目的是提高程序的运行性能;被static修饰的变量是不会被回收的。因此不经常使用的变量或者对象,需要仔细考量是否有必要设置为static。
2.充分利用单利
单利的好处是减少对资源的加载缩短运行时间,提高效率。
单利试用的场景有两种:
1.控制资源使用上,通过线程同步控制资源的并发访问。
2.控制实例的产生,以达到节省资源的目的。
3.减少对象的创建
为何要避免在经常调用的方法中循环使用new对象呢?
1.系统需要花费时间来创建对象
2.系统需要花费时间进行垃圾回收处理。
因此在可控范围时间内,最大限度重用对象。尽可能使用数据类型或者数据来代替对象。
4.使用final修饰符
java虚拟机会内联所有的final方法,使性能提高50%.(此处不理解!)
5.尽量使用局部变量
为什么呢要尽可能使用局部变量?调用方法传递的参数以及在调用创建临时变量都分配给方法的栈中,速度快。静态变量或者实力变量实在堆中创建,速度比较慢。
6.处理好包装类和基本类型的使用场所
虽然包装类型和基本类型在使用过程中可以相互转换,但是两者的内存区域完全不同。基本数据类型产生、处理和栈有关系。包装类型是实例,在堆中产生实例。在集合类对象中,对象需要进行包装处理。在其它方面,提倡建议使用基本类型。
7.学会使用StringBuilder和StringBuffer
单线程使用StringBuilder,线程不安全,性能特别高;多线程使用StringBuffer,线程安全,并且性能提升。
8.尽可能不要使用finalize方法
为什么将资源放在finalize方法中是不好的选择?gc处理Young代内存时,引起程序暂停。再使用finalize方法处理,gc负担更大。(具体参考《深入理解java虚拟机》,重写finalize方法会让被处理的对象可能会起死回生的!)
9.尽量使用基本数据类型代替对象
String str = “hello”;内存情况是在方法区运行时常量池产生字符串常量hello;
String str = new String(“hello”);内存情况,不仅在方法区常量池创建hello常量,还在堆中创建char[]来保存h,e,l,l,o.增加内存开销,还需要进行垃圾回收处理。
10.学会使用HashMap,ArrayList
HashTable,Vector线程安全,内部使用同步机制,会降低性能。
11.理解HashMap原理
需要创建比较大的HashMap时,充分利用public HashMap(int initialCapacity,float loadFactor)避免HashMap多次进行重构。扩容耗费性能,默认initialCapacity等于16,loadFactor等于0.75,你最好需要准确估计最佳性能大小。
12.减少对变量的重复计算
比如for(int i=0; i<list.size(); i++)
应该写成for(int i=0,len=list.size();i<len;i++)
并且在循环中英gia避免使用复杂的表达式,循环中,循环条件会被反复计算。如果不使用复杂的表达式,而循环条件值不变,程序运行速度会更快。
12.避免不必要的对象创建
A a = new A();
if(i == 1){ list.add(a);}
应该写成:
if(i == 1){ A a = new A(); list.add(a);}
本质上是减小创建对象的作用域。
13.尽量在finally块中释放资源
程序中使用的源尽可能在finally中释放,因为不管程序运行的结果如何,finally块总是会被执行的,保证资源正确关闭。
14.使用移位来代替乘法或者除法(a/b,仅适合和2相关的乘除)
/是代价很高的操作,使用移位操作更快更有效
int num = a / 4; //int num = a >>2;
int num = a / 8; //int num = a >>3;
int num = a * 4; //int num = a <<2;
int num = a * 8; //int num = a <<3;
位移应该加注释,移位操作不直观,可读性差,但是效率高。
15.确定StringBuffer的容量
StringBuffer的构造器会创建默认大小16的字符数组,如果超过这个数字,就会重新分配内存,创建更大的数字,将原来的数据复制过来,丢弃就的数组。因为为提高性能,在创建StringBuffer时指定大小,避免容量不够进行自增长,以提高性能。
eg:StringBuffer bufer = new StringBuffer(1000);
16.尽量避免使用sprit
为什么尽可能避免使用sprit呢?split支持正则表达式,效率比较低。如果频繁上百上万几十万的调用,会耗费大量资源。如果需要频繁调用sprit时,可以考虑使用apache的StringUtils.sprit(string,split),频繁split的可以缓存结果。
17.ArrayList和LinkList
前者基础是数组;后者基础是链表。查询数据频繁可以使用前者,需要频繁插入删除数据使用后者。
18.尽量使用System.arraycopy()代替通过循环复制数组
System.arraycopy()复制数据效率快。
19.尽量缓存经常使用的对象
经常使用的对象进行缓存,可以提高程序运行性能。
20.尽量避免非常大的内存分配
不要创建短命的需要大内存的对象,gc后可能得不到连续块内存空间,需要再次进行gc,会严重影响性能。
21.慎用异常
创建异常时,需要收集栈跟踪,用来描述异常何时创建的。建立栈耿宗,需要为运行时栈做快照,性能开销非常大。
创建异常开销比较大,好在捕获异常开销不大,可以进行try..catch处理;或者进行异常抛出。