2012-02-29 2 views
3

내 애플리케이션에서 cache 데이터가 HashMap 또는 TreeMap이므로 매우 시간이 많이 걸리기 때문에 많은 시간을 절약 할 수 있습니다. DB server에서 매번 레코드를 가져와 처리하는 작업을 수행합니다.
는 또한 JProfiler를 사용하여이 응용 프로그램의 프로파일 링을하고있는 중이 야 그리고 내가 DataBase에서 레코드를 얻고 때이 classes 너무 많은 메모리를 가지고 저를 보여주고 있기 때문에 폐쇄되지 않은 ResultSetStatementMap 연결에 넣어 생각합니다.
이 문제는 내가 과도하게 반응하거나 실제로 문제가되는 것입니까?
그런데 connection을 닫고 있습니다. finally block입니다. 나는 그것의 코드를 게시하고있다.HashMap의 데이터 캐싱 (Connection, ResultSet 및 Statement가 데이터를 가져 와서 Map에 넣은 후 열림)

HMDBUtil.close() 메소드

public static void close(Connection con, Statement stmt, ResultSet rs) 
     throws SomeException { 
    if (log.isDebugEnabled()) 
     log.debug("Invoked"); 
    close(rs); 
    close(stmt); 
    close(con); 

    if (log.isDebugEnabled()) 
     log.debug("Leaving"); 
} 

모든 연결 닫습니다 사용되는 모든 가까운 방법

public Map someFunction() throws SomeException{ 
Connection con=null; 
    Statement stmt=null; 
    ResultSet rs=null; 
    String sql=null; 
    Map <String,String> testMap=new TreeMap<String, String>(); 

    try { 
     con=HMDBUtil.getConnection(); 
     if(cacheSize==0) { 
      sql = "SELECT SOMETHING FROM SOMEWHERE"; 
     }else { 
      sql = "SELECT SOMETHING FROM SOMEWHERE_ELSE where rownum<"+cacheSize; 
     } 
     stmt=con.createStatement(); 
     stmt.setFetchSize(100000); 
     rs=stmt.executeQuery(sql); 
     long count=0; 
     while(rs.next()) { 
      testMap.put(rs.getString(1).trim(), rs.getString(2)); 
      count++; 
     } 
    } catch (SQLException e) { 

     log.fatal("SQLException while fetching Data",e); 
     throw new SomeException("SQLException while fetching Data",e);   
    }finally { 
     HMDBUtil.close(con, stmt, rs); 
    } 

    return testMap; 
} 
--- - 설정

public static void close(Connection con) throws SomeException { 
    try { 

     if (log.isDebugEnabled()) 
      log.debug("Invoked"); 
     if (con != null) { 
      con.close(); 
      con = null; 
     } 

     if (log.isDebugEnabled()) 
      log.debug("Leaving"); 

    } catch (SQLException e) { 
     log.fatal("SQLException while Closing connection ", e); 
     throw new SomeException("SQLException while Closing connection ", 
       e, false, true); 
    } 
} 


public static void close(Statement stmt) throws SomeException { 
    try { 
     if (log.isDebugEnabled()) 
      log.debug("Invoked"); 

     if (stmt != null) { 
      stmt.close(); 
      stmt = null; 
     } 
     if (log.isDebugEnabled()) 
      log.debug("Leaving"); 

    } catch (SQLException e) { 
     // log.error("Exception while Closing statement ", e); 
     log.fatal("SQLException while Closing statement ", e); 
     throw new SomeException("SQLException while Closing statement ", e, false, true); 

    } 
} 


public static void close(ResultSet rs) throws SomeException { 

    try { 
     if (log.isDebugEnabled()) 
      log.debug("Invoked"); 
     if (rs != null) { 
      rs.close(); 
      rs = null; 
     } 
     if (log.isDebugEnabled()) 
      log.debug("Leaving"); 

    } catch (SQLException e) { 
     log.fatal("SQLException while Closing rs", e); 
     throw new SomeException("SQLException while Closing rs", e, false, true); 
    } 
} 
+3

더 유연하고 효율적인 방식으로 캐싱 API를 사용하면 어떨까요? –

+0

그러나 다시 질문은 내 프로파일 러가 이러한 DataBase 클래스를 보여주는 이유입니다. 심지어 내가 닫았습니다. –

+1

'HMDBUtil.close' 메소드를 보여줄 수 있습니까? –

답변

3

결과와 진술하지 않습니다 연결을 닫은 후에 힙에서 곧바로 제거하십시오. 이 일이 발생하려면 최소한 하나의 가비지 수집기가 있어야합니다.

또한 HMDBUtil.close() 메서드가 예상대로 작동하는지 확인하십시오. 연결이 누출 될 수도 있습니다.

+1 타사 캐싱 공급자를 사용하는 경우.

수정 : 혼동을 피하기 위해. 수업은 처리가 끝날 때까지 힙에 표시되며 Permanent Generation에 위치합니다.

클래스 (개체)의 인스턴스는 가비지 수집해야합니다. 그렇지 않다면 프로세스가 어딘가에서 참조를 유지하거나 가비지 수집기가 실행되지 않았 음을 의미합니다.

JProfiler에 대해 잘 모르겠지만 YourKit을 사용하면 개체 그래프를 쉽게 탐색하고 수집되지 않은 개체에 대한 참조가있는 개체를 찾을 수 있습니다. 과거에 메모리 누수를 발견하는 데 많은 도움이되었습니다.

+0

여러 번 모니터링했는데 GC 후에 이러한 클래스를 GCed하지 않았다고 확신합니다. 그리고 예 HMDBUtil.close() 메서드는 괜찮습니다. Statement, Resultset 및 Connection을 인수로 취해 메소드에서 하나씩 닫습니다. –

1

마지막으로 try blocl을 실행 한 후에 실행되므로 "testMap.put (rs.getString (1) .trim(), rs.getString (2));" ResultSet 및 Statement는 아직 닫지 않았기 때문에 열려 있습니다.

+0

내 시도 블록이 이미 완료되었습니다. 위의 주어진 방법으로지도를 반환하고 그것을 완벽하게 얻고 있습니다. Try 블록이 실행됨을 의미합니다. –

+0

그러나보고하는 문제는지도에 물건을 넣을 때의 문제입니다. 그렇습니까? "데이터베이스에서 레코드를 가져 와서 ResultSet에 대한 Map 연결을 닫고 Statement가 닫히지 않을 때"라고 생각합니다. 이것은 try 내부에서 닫히기 전에 실행됩니다. – Pau

+0

내가 잘못 설명했다고 생각하지만 DB 활동을 마치면이 객체도 힙에있는 것처럼 보입니다. –