2017-11-18 18 views
0

ArrayList에 DB 쿼리의 ResultSet을 입력으로 사용하여 파일에 쓸 수 있지만 메모리가 부족합니다. 내가 읽는 테이블에는 약 116k 행의 데이터가 있습니다. readDB() 메서드 내에서 파일에 직접 쓰기를 시도했으며 약 3.3MB의 CSV 파일을 만듭니다. 이것은 내 코드입니다.쓰기 파일에 대한 입력으로 사용할 결과 집합 저장

public class Main { 

    public static void main(String[] args) { 

     DBAccess dbAccess = new DBAccess(); 

    } 
} 

DB를 읽는 클래스와 메서드. 이것에 대한

import java.sql.*; 
import java.util.ArrayList; 
import java.util.List; 

public class DBAccess { 

    public List<String> readDB() { 

     String url = "jdbc:Cobol://Dev/Project Files/DatAndCpyFiles"; 


     try (Connection con = DriverManager.getConnection(url, "", ""); 
      Statement stmt = con.createStatement()) 

     { 

      stmt.setFetchSize(10); 

      Class.forName("com.hxtt.sql.cobol.CobolDriver").newInstance(); 


      String sql = "select * from PROFS"; 


      ResultSet rs = stmt.executeQuery(sql); 


      List<String> result = new ArrayList<>(); 

      ResultSetMetaData resultSetMetaData = rs.getMetaData(); 
      int iNumCols = resultSetMetaData.getColumnCount(); 
      for (int i = 1; i <= iNumCols; i++) { 
       result.add(resultSetMetaData.getColumnLabel(i) + ";"); 
      } 
      String row; 

      while (rs.next()) { 
       for (int i = 1; i <= iNumCols; i++) { 

        row = rs.getString(i); 

        row = row == null ? " " : row.replaceAll("\u0086", "å"); 
        row = row == null ? " " : row.replaceAll("\u008F", "Å"); 
        row = row == null ? " " : row.replaceAll("\u0084", "ä"); 
        row = row == null ? " " : row.replaceAll("\u008E", "Ä"); 
        row = row == null ? " " : row.replaceAll("\u0094", "ö"); 
        row = row == null ? " " : row.replaceAll("\u0099", "Ö"); 
        row = row == null ? " " : row.replaceAll("\u0081", "ü"); 
        row = row == null ? " " : row.replaceAll("\u009A", "Ü"); 
        row = row == null ? " " : row.replaceAll("\u0082", "é"); 
        row = row == null ? " " : row.replaceAll("\u0090", "É"); 

        result.add(result + row.trim() + ";"); 
       } 
      } 

      rs.close(); 
      System.out.println("Returning result"); 

      return result; 

     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

오류 메시지

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Arrays.java:3332) 
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124) 
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448) 
    at java.lang.StringBuilder.append(StringBuilder.java:136) 
    at java.lang.StringBuilder.append(StringBuilder.java:131) 
    at java.util.AbstractCollection.toString(AbstractCollection.java:462) 
    at java.lang.String.valueOf(String.java:2994) 
    at java.lang.StringBuilder.append(StringBuilder.java:131) 
    at se.spedweb.DBAccess.readDB(DBAccess.java:56) 
    at se.spedweb.Main.main(Main.java:15) 

어떤 다른 데이터 구조 할 수 있습니다 내가? 이것에 대해 잘못된 접근법을 사용하고 있습니까? 나는 add 대신에 파일에 append을 나열 할 수 있었지만 파일로 쓰고 별도의 클래스로 데이터베이스를 읽는 것이 더 낫다고 생각했다. 아마도 이것은 잘못된 것이다.

+0

콜백 사용을 고려하고 작성기를 db 판독기에 전달하고 (한 행으로 작성자에게 다시 전화하십시오. 시간). 그런 다음 읽기 로직과 분리 된 실제 쓰기 논리 (행 직렬화)가 있습니다. –

+0

여기서 전체 결과 세트를 메모리로로드하려고 시도하는 것이 잘못되었습니다. – EJP

+0

'String sql = "select * from PROFS"; 값이 기본 'PROFS' 테이블에 더 많으면 잘못 될 수 있습니다 –

답변

0

명령 줄 옵션으로 java를 실행하면 -Xmx를 사용하여 시도해보십시오. 수동으로 힙의 크기를 설정할 수 있습니다. -Xmx2048m으로 설정하십시오. 참고 : IDE를 사용하는 경우 빠른 방법을 사용하여 IDE를 변경하는 방법이 있습니다.