Как избежать OOM (Из памяти) ошибка при получении всех записей от огромной таблицы?

Если Вы достаточно стараетесь, можно пойти о создании программного обеспечения, не используя Objective C, который имеет потенциал для великого за исключением того, что в конце дня это не будет очень хорошо. Вы проведете больше времени, пытаясь увещевать язык в выполнение чего-то, в чем это не является абсолют лучше всего. В WWDC я носил рубашку, которая сказала, "Изучают Objective C или Удаляются", который не перешел слишком хорошо с некоторыми людьми, которые все еще держали нежно на последние потоки жизни Паскаля, но точка в целом верна - Objective C - то, где это в на Mac, и притвориться иначе означает навредить себе.

Однако Вы не должны определенно исключать мосты на платформе для расширения Вашего приложения - Bill Bumgarner быстр для указания , сколько питания Скрученная сетевая платформа обеспечивает к приложениям Какао через мост PyObjC.

15
задан Kara 1 February 2014 в 20:26
поделиться

6 ответов

Я думаю, вы могли бы использовать то же решение, что и это . Прокручиваемый набор результатов.

4
ответ дан 1 December 2019 в 03:52
поделиться

At which stage is the OOM error occurring, is it on data retrieval or processing data to XML file?

If its data retrieval, get the data in batches. Get the total number of rows first, order the selects by the primary key and limit the rows selected to chewable sizes.

If its at creating the XML file, send the XML node of each customer to System.out.println, don't hold it in memory. Launch the program via commad line and redirect all output to a file;

java MyConverter > results.txt

As you loop through the record all is saved in the file.

0
ответ дан 1 December 2019 в 03:52
поделиться

Концепция экспорта всей таблицы. (Примечание для экспертов: я осведомлен о его недостатках.)

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class FullTableExport {
    public static String toXML(String s) {
        if (s != null) {
            StringBuilder b = new StringBuilder(s.length());
            for (int i = 0, count = s.length(); i < count; i++) {
                char c = s.charAt(i);
                switch (c) {
                case '<':
                    b.append("&lt;");
                    break;
                case '>':
                    b.append("&gt;");
                    break;
                case '\'':
                    b.append("&#39;");
                    break;
                case '"':
                    b.append("&quot;");
                    break;
                case '&':
                    b.append("&amp;");
                    break;
                default:
                    b.append(c);
                }
            }
            return b.toString();
        }
        return "";
    }
    public static void main(String[] args) throws Exception {
        String table = "CUSTOMER";
        int batch = 100;

        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection conn = DriverManager.getConnection(
            "jdbc:oracle:thin:@server:orcl", "user", "pass");
        PreparedStatement pstmt = conn.prepareStatement(
            "SELECT /*+FIRST_ROWS(" + batch + ") */ * FROM " + table);
        ResultSet rs = pstmt.executeQuery();
        rs.setFetchSize(batch);
        ResultSetMetaData rsm = rs.getMetaData();
        File output = new File("result.xml");
        PrintWriter out = new PrintWriter(new BufferedWriter(
            new OutputStreamWriter(
            new FileOutputStream(output), "UTF-8")), false);
        out.printf("<?xml version='1.0' encoding='UTF-8'?>%n");
        out.printf("<table name='%s'>%n", toXML(table));
        int j = 1;
        while (rs.next()) {
            out.printf("\t<row id='%d'>%n", j++);
            for (int i = 1; i <= rsm.getColumnCount(); i++) {
                out.printf("\t\t<col name='%s'>%s</col>%n", 
                    toXML(rsm.getColumnName(i)), 
                    toXML(rs.getString(i)));
            }
            out.printf("\t</row>%n");
        }
        out.printf("</table>%n", table);
        out.flush();
    }
}

Изменить Недостатки (спасибо @JS):

  • Никаких внешних библиотек, кроме ojdbc, не использовалось
  • Ничего не закрыто
  • Выдается общее исключение
  • Это основной метод
  • Использование печати для генерации XML
  • SQL, специфичный для Oracle
  • Обычный текстовый пароль
  • Некоторые столбцы выглядят неудобно в строковом представлении
  • UTF- 8 слишком интернационально
  • Размер структуры XML велик
1
ответ дан 1 December 2019 в 03:52
поделиться

Имея немного больше информации, я могу получить более полезный ответ.

Если вы используете MySQL:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
       java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

из http://www.oracle.com/technology /tech/java/sqlj_jdbc/htdocs/jdbc_faq.html:[12128 impression

6
ответ дан 1 December 2019 в 03:52
поделиться

Если вы используете JDBC, вы можете использовать ResultSet с курсором, который вы перебираете по одной записи за раз. Тогда вам нужно убедиться, что вы записываете свой XML в файл по одной записи за раз, а не используете DOM для построения XML.

4
ответ дан 1 December 2019 в 03:52
поделиться

Одно практическое правило, которое я усвоил на собственном опыте, заключается в том, что НИКОГДА не переносите ВСЕ данные из базы данных на сервер приложений. Единственное, что вы можете сделать, это реализовать процедуру для страничной страницы ваших данных.

Вы можете вывести одну страницу данных, содержащую около 1000-5000 записей, обработать их, а затем снова получить данные для следующей страницы.

4
ответ дан 1 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: