2013-05-13 4 views
1

저는 Timetable 스케줄러를 최종 프로젝트로 만들고 있습니다. 지난 2 일 동안 OutOfMemoryException이 발생했습니다. 예외에 대해 많이 읽었고 -Xms 및 -Xmx 옵션을 통해 할당 된 메모리를 늘려 고했습니다. 이 중 아무 것도 나를 위해 작동하지 않는 것 같습니다.OutOfMemoryError

프로젝트를 프로파일 링하여 hashmap 객체 및 MySQL 연결에서 최대 공간을 차지하는 것으로 나타났습니다.

public final class Connector 
{ 
private static Connector connector; 
Connection con; 
String driverName; 
String dbname; 
String username; 
String password; 
String connString; 

private Connector(){ 
    driverName = "com.mysql.jdbc.Driver"; 
    dbname = "timegen"; 
    username = "root"; 
    password = "root"; 
    connString = "jdbc:mysql://localhost:3306/" + dbname; 
    openConnection(); 
} 

public void openConnection(){ 
    try{ 
     Class.forName(driverName); 

     con = DriverManager.getConnection(connString, username, password); 
    } catch(Exception e){ 
     System.out.println(e); 

    } 
} 


public void terminateConnection(){ 
    try{ 
     con.close(); 
    } catch(Exception e){ 
     System.out.println(e); 
    } 

} 

public static Connector createConnection() { 

    if (connector == null){ 
     connector = new Connector(); 
    } 

    return connector; 
} 

public Connection getCon() { 
    return con; 
} 
public String getConnString() { 
    return connString; 
} 

public void setConnString(String connString) { 
    this.connString = connString; 
} 

} 

이 데이터베이스

public class MasterData{ 
    static Connector con; 
    static Statement st; 

    MasterData(){ 
    try { 
     con = Connector.createConnection(); 
     st = con.getCon().createStatement(); 
    } catch (SQLException ex) { 
     Logger.getLogger(MasterData.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    } 

    public Statement createStatement() throws SQLException{ 
     Statement st = con.getCon().createStatement(); 
     return st;  
    } 
    public void closeConnection(){ 
     con.terminateConnection(); 
    } 


} 

사용하는 클래스의 예에 액세스하는 모든 다른 클래스에 의해 확장 MasterData라는 이름의 클래스에 대한 코드는 다음과 같이 나는 정적 연결을 사용했다 이

public class Teacher extends MasterData{ 

int teacherid; 
String teachername; 
String subject; 
String post; 

@Override 
public String toString() { 
    return "Teacher{" + "teacherid=" + teacherid + ", teachername=" + teachername + ", 
post=" + post + ", subject=" + subject + '}'; 
} 



public Teacher(int teacherid, String teachername,String subject, String post) { 
    this.teacherid = teacherid; 
    this.teachername = teachername; 
    this.subject = subject; 
    this.post = post; 
} 

public Teacher(String teachername) { 
    this.teachername = teachername; 
} 

public Teacher(){} 

public String display(){ 

    String s ="\nTeacher name = " + teachername 
      + "\nSubject = " + subject 
      + "\nPost = "+post; 
    return s; 
} 


public ArrayList<String> getSubjectTeachers(String s){ 
    ArrayList<String> teachers = new ArrayList<String>(); 
    try{ 
     ResultSet rs = st.executeQuery("select teachername from teacher where 
subject='"+s+"';"); 
     while(rs.next()){ 
      teachers.add(rs.getString(1)); 
     } 
    }catch(Exception e){e.printStackTrace();} 

    return teachers; 
} 

public List<Teacher> getFree() 
{ 
    List<Teacher> lst = new ArrayList<Teacher>(); 
    try{ 
     ResultSet rs = st.executeQuery("select * from teacher where teacherid not 
in(select classteacher from division where classteacher!=null)"); 
     while(rs.next()) 
     { 
      lst.add(new 
Teacher(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4))); 
     } 

    }catch(Exception e){e.printStackTrace();} 
    return lst; 
} 




public int getTeacherid() { 
    return teacherid; 
} 

public void setTeacherid(int teacherid) { 
    this.teacherid = teacherid; 
} 

public String getTeachername() { 
    return teachername; 
} 

public void setTeachername(String teachername) { 
    this.teachername = teachername; 
} 


public String getSubject() { 
    return subject; 
} 

public void setSubject(String subject) { 
    this.subject = subject; 
} 

public String getPost() { 
    return post; 
} 

public void setPost(String post) { 
    this.post = post; 
} 

public boolean checkDuplicate(){ 
    try{ 
     ResultSet rs = st.executeQuery("select * from teacher where 
teachername='"+teachername+"';"); 
     if(rs.next()) 
      return true; 

    }catch(Exception e){e.printStackTrace();} 

     return false; 

} 

public boolean insert(){ 
    int t; 
    try{ 
     t = st.executeUpdate("insert into teacher(teachername,subject,post)  
values('"+teachername+"','"+subject+"','"+post+"');"); 
     if(t!=0) return true; 
    } 
    catch(Exception e){ 
     e.printStackTrace(); 
     return false; 

    } 
    return false; 
} 


public boolean delete(){ 
    int t; 
    try{ 
     new AssignedTeacher().deleteTeacher(teacherid); 
     t = st.executeUpdate("delete from teacher where teacherid="+teacherid+";"); 
     if(t!=0) return true; 
    } 
    catch(Exception e){ 
     e.printStackTrace(); 
     return false; 

    } 
    return false; 
} 

public boolean update(){ 
    int t; 
    try{ 
     t = st.executeUpdate("update teacher set teachername = '"+teachername+"',     
subject='"+subject+"', post='"+post+"' where teacherid="+teacherid+";"); 

     if(t!=0) return true; 
    } 
    catch(Exception e){ 
     e.printStackTrace(); 
     return false; 

    } 
    return false; 
} 

} 

내 의도는 전체 프로그램에 대해 단일 정적 연결을 만드는 것이 었습니다. 잘 작동하는 것 같습니다. 그러나 이것이 문제의 가능한 원인입니까?

+0

@SotiriosDelimanolis : 나는 몇 가지 더 많은 기능을 추가까지 나는 널 포인터 제외하고 ... 전체 프로그램이 잘 작동받지 못했습니다. 그런 다음 OutOfMemory Exception을 시작했습니다. – AartiRajan

+0

getter가 단순히'Connector'의'Connection con' 필드를 반환합니까? –

+0

그래, 그게 .. .. – AartiRajan

답변

0

Connection이 너무 많습니다.

openConnection 방법으로 연결 is valid을 확인할 수 있습니다. Connection Pool도 사용할 수 있습니다.

편집 : insert, delete, updategetSubjectTeachers 방법이 있기 때문에

당신이 Active record pattern을 구현하기 위해 노력했습니다 나에게 보인다. 어쨌든, 그게 항상 좋은 생각이 아닙니다. extend Teacher from MasterData. 부작용으로 각 인스턴스에 대해 MasterData의 새 연결이 생성됩니다. static Connection con은 새 개체로 재 할당되지만 이전 Connection은 종료되지 않습니다. MasterData#createStatement와 동일하게 유지됩니다.

또한 greedybuddha가 지적했듯이 HashMap이 동일한 방식으로 재 할당되지 않았는지 확인하십시오.

+0

데이터베이스를 쿼리 할 때마다 연결을 열고 닫으면 도움이됩니까? 그리고이 두 클래스를 사용하지 않습니까? – AartiRajan

+0

정말 필요하지 않습니다. 외부 항아리를 재사용 할 수 있습니까? 그렇다면 여러 가지 유용한 구현이 가능합니다. [C3PO] (http://www.mchange.com/projects/c3p0/index.html) – lifus

+0

나는 그것을 시도 할 것이다.고마워요 – AartiRajan

0

뿐만 아니라 이러한 매개 변수를 설정하십시오 :

-XX:PermSize 
-XX:MaxPermSize 
+0

그녀는 이미 시도해 봤는데 -Xms 및 -Xmx 옵션 _을 통해 할당 된 메모리를 늘려 보았습니다. 후속 'OutOfMemoryError'는 코드에 몇 가지 문제가 있기 때문에 시간 문제 일뿐입니다. – lifus

+0

또한 정적 객체가 여전히 힙에 저장되어 있기 때문에 PermGen 공간 오류라고 확신하지 못합니다. – lifus