2012-01-12 5 views
1

개행 문자로 분리 된 158000 개의 레코드 (12MB)를 포함하는 파일을 읽고 mysql 데이터베이스에 저장하려하지만 약 49000 개의 레코드를 삽입 한 후 Java 프로그램이 throw합니다. 데이터오류 발생 : java.lang.OutOfMemoryError : Java 힙 공간

FileInputStream file; 
     DataInputStream dataIn; 
     BufferedReader bReader; 
     Connection conn= openConnection(); 
     String strRecord=new String(); 
     String[]strSplittedRecord; 
     file= new FileInputStream("D:\\Java\\CountryWhois.txt"); 
     dataIn= new DataInputStream(file); 
     bReader= new BufferedReader(new InputStreamReader(dataIn)); 
     PreparedStatement insertStmt; 
     String strQuery="insert into countrywhois values(?,?,?,?,?,?)"; 
     while((strRecord=bReader.readLine())!=null) 
     { 

      strSplittedRecord=strRecord.split(","); 

     try { 

      insertStmt=conn.prepareStatement(strQuery); 
      insertStmt.setString(1,strSplittedRecord[0].substring(1, strSplittedRecord[0].length()-1)); 
      insertStmt.setString(2,strSplittedRecord[1].substring(1, strSplittedRecord[1].length()-1)); 
      insertStmt.setString(3,strSplittedRecord[2].substring(1, strSplittedRecord[2].length()-1)); 
      insertStmt.setString(4,strSplittedRecord[3].substring(1, strSplittedRecord[3].length()-1)); 
      insertStmt.setString(5,strSplittedRecord[4].substring(1, strSplittedRecord[4].length()-1)); 
      insertStmt.setString(6,strSplittedRecord[5].substring(1, strSplittedRecord[5].length()-1)); 
      int nResultInsert=insertStmt.executeUpdate(); 
      if(nResultInsert!=0) 
      { 
       System.out.println("Inserted 1"); 


      } 
      else 
      { 
       if(conn!=null) 
       { 
        conn.close(); 
        System.out.println("Disconnected from database"); 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      conn.close(); 
      e.printStackTrace(System.out);   
     } 

     } 

는 라인 insertStmt = conn.prepareStatement (strQuery)에서 예외를 throw 삽입 예외를

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at java.util.jar.Manifest$FastInputStream.<init>(Manifest.java:315) 
    at java.util.jar.Manifest$FastInputStream.<init>(Manifest.java:310) 
    at java.util.jar.Manifest.read(Manifest.java:178) 
    at java.util.jar.Manifest.<init>(Manifest.java:52) 
    at java.util.jar.JarFile.getManifestFromReference(JarFile.java:167) 
    at java.util.jar.JarFile.getManifest(JarFile.java:148) 
    at sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:696) at sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:696) 

    at java.net.URLClassLoader.defineClass(URLClassLoader.java:228) 
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:430) at com.mysql.jdbc.Util.handleNewInstance(Util.java:430) 

    at com.mysql.jdbc.PreparedStatement.getInstance(PreparedStatement.java:553) 
    at com.mysql.jdbc.ConnectionImpl.clientPrepareStatement(ConnectionImpl.java:1378) 
    at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4143) 
    at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4042) 
    at loadcsvdatabase.LoadCsvDatabase.fnLoadCsvIntoMemory(LoadCsvDatabase.java:52) 
    at loadcsvdatabase.LoadCsvDatabase.main(LoadCsvDatabase.java:29) 

자바 코드를 따르고;

내 프로그램 메모리 예외 부족 왜 저를 제안하십시오 ..

답변

7

당신은 새로운 PreparedStatement의 사용자가 레코드를 삽입 할 때마다 만들 수 있습니다. 그것은 PreparedStatements가 사용되는 방법이 아닙니다. 또한 OutOfMemoryException을 유발할 수있는 작성된 PreparedStatement를 절대로 닫지는 않지만 루트 문제점은 아 U니다.

PreparedStatement를 하나만 만들어서 재사용해야합니다. 그런 다음 모든 레코드를 삽입 한 후 PreparedStatement와 Connection을 닫으십시오.

+2

합니다. –

+0

나는 두 번째 ckuetbach. 그러나 우선 Nishit은 최적화하기 전에 먼저 OOM 문제를 수정해야합니다. 또한 레코드의 크기가 크기 때문에 1 회의 executeBatch() 호출마다 addBatch 호출을 100 (IMO)로 제한해야합니다. –

+0

감사합니다 !! 그 동안 준비된 문장을 루프 안에 넣으면서 실수를했습니다. –

0
insertStmt=conn.prepareStatement(strQuery); 

while 외부에 있어야합니다. 정확히 strQuery

+0

Thanks It Woks !! –

0

당신은이 방법을 따르도록 코드를 수정해야 초기화 후 넣어 : 포인트가 추가로 addBatch의 성능을 향상시킬 수있다

... 

try { 
    Connection conn = openConnection(); 
    try { 

    String strQuery="insert into countrywhois values(?,?,?,?,?,?)"; 
    PreparedStatement insertStmt=conn.prepareStatement(strQuery); 
    while (...) { 
     try { 
      .... 
      int nResultInsert=insertStmt.executeUpdate(); 

      // handle your result here (e.g. print/log) 
      // DO NOT close() here, continue with loop 

     } catch (Exception e) { 
      // handle your exception here (e.g. print/log) 
      // DO NOT close() here, continue with loop, OR break loop 
     } 
    } 

    } finally { 
     // closing SQL Connection no matter what happens to your while-loop 
     conn.close(); 
    } 
} catch (Exception e) { 
    // handle your exception here (e.g. print/log) 
} 
+0

감사합니다 !!! 그것은 작동합니다. –

관련 문제