- 尽量重用对象,不要循环创建对象,比如在 for 循环中进行字符串拼接,或者用原型模式提升性能;
- 容器类初始化的时候指定长度,比如 List<String> collection = new ArrayList<String>(5);,ArrayList 底层使用 Object 数组实现的,默认为空,添加元素时如果容量不够就涉及扩容操作,而扩容操作就涉及数组的复制操作;HashMap 底层也是数组,每个数组元素指向一个链表,当链表长度超过一定值时变成红黑树,故 HashMap 初始化的时候也要指定初始大小,避免 resize() 的时候的重哈希;
- ArrayList 随机访问快,LinkedList 添加删除快;LinkedList 是一个双向链表;
- 使用 Entry 遍历 Map;
for(Map.Entry<String, String> entry : map.entrySet()) {String key = entry.getKey();
String value = entry.getValue();}
- 大数组拷贝用 System.arraycopy,其底层是用 Native 代码做的,就是 C 代码做的;
- 尽量使用基本类型而不是包装类型;
- 不要手动调用 System.gc(),其作用是通知垃圾收集器做一个 FullGC,通过 GC 调优而不是这种方式;
- 及时消除掉过期对象的引用,防止内存泄漏;
- 尽量使用局部变量,减小变量作用域;
- 尽量使用非同步的容器,比如 ArrayList VS Vector;
- 尽量缩小同步作用范围,比如 synchronized 方法 VS synchronized 代码块;
- 使用 ThreadLocal 缓存一些线程不安全的对象,比如 SimpleDataFormat,其比较复杂,创建的时候比较耗资源,不用每次用的时候都 new 一个,可以缓存在 ThreadLocal 中,成为一个线程单例;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatUtil {private static ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() {protected SimpleDateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
public static void main(String[] args) {dateFormatHolder.get().format(new Date());
}
}
- 尽量使用延迟加载;
- 尽量减少使用反射,如果必须要用,加缓存,只在第一次需要反射的时候反射,之后将其加入一个缓存,以后再用从缓存中取;
- 尽量使用连接池,线程池,对象池,缓存;
- 及时释放资源,I/ O 流,Socket,数据库连接;
- 慎用异常,不要用抛异常的方式表示正常的业务逻辑,异常也是一个比较重的对象;
- String 操作的时候,尽量少用正则表达式,功能强大但是性能很低,能用 replace 就不用 replaceAll;
- 日志输出注意使用不同的级别;
- 日志中,参数拼接使用占位符;