77-Java内存泄漏经典原因分析

Java内存泄漏经典原因分析

  • Java内存泄漏经典原因分析:
    • 对象定义在错误的范围(Wrong scope);
    • 异常(Exception)处理不当;
    • 集合数据管理不当。
  • 对象定义在错误的范围(Wrong scope)
    • 如果Foo实例对象的生命较长,会导致临时性内存泄漏。(这里names变量其实只有临时作用)
    class Foo{
       private String[] names;
       public void odIt(int length){
          if(names == null || names.length < length){
             names = new String[length];
          }
          populate(names);
          print(names);
       }
    }
    
    • JVM喜欢生命周期短的对象,这样做已经足够高效:
    class Foo{
       public void odIt(int length){
          String[] names = new String[length];
          populate(names);
          print(names);
       }
    }
    
  • 异常处理不当:
    • 错误的做法:

      Connection conn = DriverManager.getConnection(url,name,passward);
      try{
         String sql = "do a query sql";
         PreparedStatement stmt = conn.prepareStatement(sql);
         ResultSet rs = stmt.executeQuery();
         while(rs.next()){
            doSomeStuff();
         }
         rs.close();
         conn.close();
      }catch(Exception e){
         //如果doSomeStuff()抛出异常
         //rs.close 和 conn.close 不会被调用,
         //会导致内存泄漏和db连接泄漏
      }
      
    • 正确的做法:

    PreparedStatement stmt = null;
    ResultSet rs = null;
    try{
       String sql = "do a query sql";
       stmt = conn.prepareStatement(sql);
       rs = stmt.executeQuery();
       while(rs.next()){
          doSomeStuff();
       }
    }catch(Exception e){
    	//handle exception
    }finally{
       //永远用finally去关闭资源,避免资源泄漏
       if(rs != null){
          rs.close();
       }
       if(stmt != null){
          stet.close();
       }
       conn.close();
    }
    
  • 集合数据管理不当:
    • 当时用Array-based的数据结构(ArrayList,HashMap等)时,尽量减少resize
      • 比如:new ArrayList时,尽量估算size,在创建的是把size确定;
      • 减少resize可以避免没有必要的array copying , gc碎片等问题;
    • 如果一个List只需要顺序访问,不需要随机访问(Random Access),用LinkedList代替ArrayList
      • LinkedList本质是链表,不需要resize,但只适用于顺序访问。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值