1. 对象定义在错误的范围(Wrong Scope)
如果Foo实例对象的生命周期比较长,会导致临时性内存泄露—这里的names变量其实只有临时作用
Class Foo{
private Stirng[] names;
public void test(int length){
if(names == null || names.length < length){
names = new String[length];
}
populate(names);
print(names);
}
}
JVM喜欢生命周期短的对象,这样做已经足够高效
Class Foo{
public void test(int length){
Stirng[] names = new String[length];
populate(names);
print(names);
}
}
2. 异常(Exception)处理不当
- 错误做法
Connection conn = DriverManager.getConnection(url, name, pwd);
try{
String sql = "select * from table";
PreparedStatement stmt = conn.getPrepareStatement(sql);
ResultSet rs = stmt.executeQuery()'
while(rs.next()){
doProcess();
}
rs.close();
conn.close();
}catch(Exception e){
//如果doProcess()抛出异常
//rs.close()和conn.close()不会被调用
//会导致内存泄露和db链接泄露
}
- 正确的做法
Connection conn = DriverManager.getConnection(url, name, pwd);
try{
String sql = "select * from table";
PreparedStatement stmt = conn.getPrepareStatement(sql);
ResultSet rs = stmt.executeQuery()'
while(rs.next()){
doProcess();
}
}catch(Exception e){
//handle exception
}finally{
//永远用到finally去关闭资源,避免资源泄露
if(rs != null){
rs.close();
}
if(conn != null){
conn.close();
}
}
3. 集合数据处理不当
- 当使用Array-based的数据结构—ArrayList,HashMap等时,尽量减少扩容
- 比如new ArrayList时,尽量估算size,在创建的时候把size确定
- 减少扩容可以避免没必要的array copying, gc碎片等问题
- 如果一个List只需要顺序访问,不需要随机访问(Random Access),用LinkedList代替ArrayList
- LinkedList本质是链表,不需要扩容,但只适用于顺序访问