Произошла ошибка :: java.lang.OutOfMemoryError: пространство кучи Java - PullRequest
1 голос
/ 12 января 2012

Я пытаюсь прочитать файл, содержащий 158000 записей (12 МБ), разделенных символом новой строки, и поместить эту запись в базу данных mysql, но после вставки около 49000 записей моя Java-программа выдает следующее исключение

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)

Java Codeвставка данных

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);

Пожалуйста, подскажите, почему моей программе не хватает памятиисключение ..

Ответы [ 3 ]

7 голосов
/ 12 января 2012

Вы создаете новый PreparedStatement каждый раз, когда вставляете запись.Это не то, как PreparedStatements предполагается использовать.Кроме того, вы никогда не закрываете созданные PreparedStatements, что, вероятно, вызывает исключение OutOfMemoryException, но это не является корневой проблемой.

Вы должны создать только один PreparedStatement и использовать его повторно.Затем, после вставки всех записей, закройте PreparedStatement и Connection.

0 голосов
/ 12 января 2012

Вам следует пересмотреть свой код, чтобы выполнить следующие действия:

...

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 голосов
/ 12 января 2012
insertStmt=conn.prepareStatement(strQuery);

Должен быть вне цикла while. Поставь точно после инициализации strQuery

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...