2013-02-08 4 views
0

Java OutOfMemoryError에 문제가 있습니다. 이 프로그램은 기본적으로 mysql workbench에서 실행되는 mysql 테이블을보고 쿼리하여 특정 정보를 가져온 다음 CSV 파일에 저장합니다.OutOfMemoryError : Java 힙 공간

이 프로그램은 더 작은 데이터 세트로도 잘 작동하지만 한 번 더 큰 데이터 세트 (약 40 분과 달리 로깅 정보 시간)를 사용하면이 오류가 발생합니다. 거대한 데이터 세트와 정보는 프로그램에 의해 너무 잘 처리되지 않습니다. 또는 내가 가지고있는 방식으로이 양의 데이터를 처리 할 수 ​​없습니다.

Java VM 인수를 -xmx1024m으로 설정하면 약간 큰 데이터 세트에서 작동하지만 더 큰 데이터 세트를 처리해야하지만 오류가 발생합니다.

// CSV is csvwriter (external lib), sment are Statements, rs is a ResultSet 
public void pidsforlog() throws IOException 
{ 
    String[] procs; 
    int count = 0; 
    String temp = ""; 

    System.out.println("Commence getting PID's out of Log"); 
    try { 
     sment = con.createStatement(); 
     sment2 = con.createStatement(); 
     String query1a = "SELECT * FROM log, cpuinfo, memoryinfo"; 
     rs = sment.executeQuery(query1a); 
     procs = new String[countThrough(rs)]; 

     // SIMPLY GETS UNIQUE PROCESSES OUT OF TABLES AND STORES IN ARRAY 
     while (rs.next()) { 
      temp = rs.getString("Process"); 

      if(Arrays.asList(procs).contains(temp)) { 
      } else { 
       procs[count] = temp; 
       count++; 
      } 
     } 

     // BELIEVE THE PROBLEM LIES BELOW HERE. SIZE OF THE RESULTSET TOO BIG? 
     for(int i = 0; i < procs.length; i++) { 
      if(procs[i] == null) { 
      } else { 
       String query = "SELECT DISTINCT * FROM log, cpuinfo, memoryinfo WHERE log.Process = " + "'" + procs[i] + "'" + " AND cpuinfo.Process = " + "'" + procs[i] + "'" + " AND memoryinfo.Process = " + "'" + procs[i] + "' AND log.Timestamp = cpuinfo.Timestamp = memoryinfo.Timestamp"; 
       System.out.println(query); 
       rs = sment.executeQuery(query); 

       writer = new CSVWriter(new FileWriter(procs[i] + ".csv"), ','); 
       writer.writeAll(rs, true); 
       writer.flush(); 
      } 
     } 
     writer.close(); 
    } catch (SQLException e) { 
     notify("Error pidslog", e); 
    } 
}; // end of method 

나는이 고정을 얻을 필사적 해요 당신이 소스 코드 나 자세한 정보를 원하는 경우 문의 주시기 바랍니다 : 여기에

내가 꽤 확신 방법이 어딘가에 프로그램의 원인이다 !

감사합니다.

+0

[프로파일 러] (http://profiler.netbeans.org/)를 사용해 보았습니까? – user000001

+0

메모리의 모든 것을 한번에 처리하지 않고 데이터베이스의 결과를 파일로 스트리밍 할 수 없습니까? – kutschkem

+0

'writer.close()'i.o. flush (루프 내부). 코드에서 개선 할 수있는 많은 기회; 프로그래머를 고용하십시오. –

답변

0

메모리에 너무 많은 데이터가로드되어 있다고 생각합니다. 이 문제를 피할 수 있도록 SQL 문에 offsetlimit을 사용하십시오.

2

SELECT * FROM log, cpuinfo, memoryinfo 큰 결과 집합을 제공합니다. 3 개의 테이블 모두에서 모든 행의 직교 곱을 얻을 수 있습니다.

테이블 구조를 보지 않고 (또는 원하는 결과를 알면) 솔루션을 찾아 내기가 어렵지만 결과 집합을 제한하기 위해 일종의 조인 조건을 원하거나 또는 UNION a'la를 사용해야합니다. 단지 3 개 테이블 Process 당신에게 모든 고유 값을 줄 것이다

SELECT Process FROM log 
UNION 
SELECT Process FROM cpuinfo 
UNION 
SELECT Process FROM memoryinfo 

....

두 번째 SQL 문도 약간 이상하게 보입니다.

SELECT DISTINCT * 
FROM log, cpuinfo, memoryinfo 
WHERE log.Process = @param1 
    AND cpuinfo.Process = @param1 
    AND memoryinfo.Process = @param1 
    AND log.Timestamp = cpuinfo.Timestamp = memoryinfo.Timestamp 

3 개의 로그를 동시에 선택하려고하지만 다른 데카르트 제품으로 끝나는 것처럼 보입니다. 기대하는 결과를 얻고 있습니까?

+0

인쇄 라인을 테스트 한 결과 내가 언급 한 첫 번째 선택을 시도한 후에 오류가 발생한다는 것은 틀림 없습니다. 어떻게 이런 식으로하지 않으면 세 테이블에서 모든 데이터를 가져올 수 있습니까? "memoryinfo .."가없고 "= memoryinfo.Timestamp"가없는 "log"및 cpuinfo "를 사용했을 때 두 번째 sql 문을 사용 했으므로 다음 테이블을 가져온다고 가정했습니다. (나는 그들을 모두 한 번에 같은 CSV 파일에 선택해야합니다.) 비슷하게 cpuinfo를 추가하고 작동했습니다. – fypfyp

+0

모든 테이블에서'Process'를 원하면'SELECT Process FROM log UNION SELECT Process ' FROM cpuinfo UNION SELECT FROM memoryinfo' 대신 위의 편집을 참조하십시오. –

1

SQL 질의에 의해 반환 된 결과를 LIMIT estatement로 제한 할 수 있습니다. 예를 들어

:

SELECT * FROM `your_table` LIMIT 100 

이 이것은 분명히 200

당신이 얻을 수 있도록 당신이 그 값을 반복 할 수는 100에서 결과를 반환합니다

SELECT * FROM `your_table` LIMIT 100, 200 

처음 100 개 개의 결과를 반환합니다 얼마나 많은 데이터베이스가 있더라도 데이터베이스의 모든 요소에 적용됩니다.

0

Java 코드는 데이터베이스가보다 효율적으로 수행 할 수있는 작업을 수행합니다. query1a에서, 당신이 정말로 원하는 것은 유일한 프로세스 인 것처럼 보입니다. select distinct Process from ...으로 충분해야합니다.

그런 다음 해당 쿼리에서 어떤 테이블이 필요한지 신중하게 생각하십시오. 정말로 log, cpuinfo 및 memoryinfo가 필요합니까? Joachim Isaksson이 언급했듯이이 세 테이블의 데카르트 곱을 반환하여 x * y * z 행 (x, y 및 z는 세 테이블 각각의 행 수)과 a + b + c 열 (여기서 a, b 및 c는 각 테이블의 열 수입니다). 나는 그것이 당신이 원하거나 필요로하는 것이 아닌지 의심 스럽다. 난 당신이 하나의 테이블 또는 유니온 (조인보다는) 세 테이블의 고유 한 프로세스를 얻을 수 있다고 가정합니다.

마지막으로, 두 번째 루프와 쿼리가 본질적으로 조인을하고 있습니다. 다시 한 번 더 효율적으로 데이터베이스에 남겨 둡니다.

0

다른 사람들처럼 작은 조각으로 데이터를 가져 오면 문제가 해결 될 수 있습니다. 이것은이 문제에 대해 이야기하는 stackoverflow의 다른 스레드 중 하나입니다. How to read all rows from huge table?

관련 문제