Как управлять памятью PHP? - PullRequest
0 голосов
/ 15 октября 2018

Я написал одноразовый скрипт, который я использую для разбора PDF-файлов, сохраненных в базе данных.Пока все работает нормально, пока у меня не закончилась память после разбора 2700+ документов.

Основная последовательность действий скрипта следующая:

  1. Получить список всех документовИдентификаторы для анализа и сохранения их в виде массива в сеансе (~ 155 тыс. Документов).
  2. Отображение страницы с кнопкой для начала синтаксического анализа
  3. Создание запроса AJAX при нажатии этой кнопкикоторый будет анализировать первые 50 документов в массиве сеансов

$files = $_SESSION['files'];

$ids = array();

$slice = array_slice($files, 0, 50);
$files = array_slice($files, 50, null); // remove the 50 we are parsing on this request

if(session_status() == PHP_SESSION_NONE) {
  session_start();
}
$_SESSION['files'] = $files;
session_write_close();

for($i = 0; $i < count($slice); $i++) {
  $ids[] = ":id_{$i}";
}
$ids = implode(", ", $ids);

$sql = "SELECT d.id, d.filename, d.doc_content
  FROM proj_docs d
  WHERE d.id IN ({$ids})";

$stmt = oci_parse($objConn, $sql);
for($i = 0; $i < count($slice); $i++) {
  oci_bind_by_name($stmt, ":id_{$i}", $slice[$i]);
}
oci_execute($stmt, OCI_DEFAULT);
$cnt = oci_fetch_all($stmt, $data);
oci_free_statement($stmt);

# Do the parsing..
# Output a table row..

В ответ на запрос AJAX обычно указывается состояние завершения сценария синтаксического анализа ~ 155 тыс. Документов - если это не сделано, выполняется другой запрос AJAX для анализа следующих 50. Между каждым запросом имеется 5-секундная задержка.

Вопросы

  • Почему у меня заканчивается память, когда я ожидал, что пиковое использование памяти будет, когда я получу список всех идентификаторов документов на #1поскольку он содержит все возможные документы , а не несколько минут спустя, когда массив сеансов содержит на 2700 элементов меньше?
  • Я увидел несколько вопросов, похожих на мою проблему, и они предложили либо установитьпамять на unlimited, что я не хочу делать вообще.Другие предложили установить мои переменные на null, когда это было уместно, и я сделал это, но у меня все еще не хватило памяти после анализа ~ 2700 документов.Итак, какие еще подходы я должен попробовать?

# Freeing some memory space
$batch_size = null;
$with_xfa = null;
$non_xfa = null;
$total = null;
$files = null;
$ids = null;
$slice = null;
$sql = null;
$stmt = null;
$objConn = null;
$i = null;
$data = null;
$cnt = null;
$display_class = null;
$display = null;
$even = null;
$tr_class = null;

1 Ответ

0 голосов
/ 15 октября 2018

Так что я не совсем уверен, почему, но, похоже, решение проблемы связано с уменьшением количества анализируемых документов со 50 до 10 для каждого пакета.Я прошел более 5000 документов, и скрипт все еще работает.Единственное, что я могу предположить, это то, что когда я анализировал 50 документов, у меня должно было быть много больших файлов, которые занимали всю выделенную память.

Обновление # 1

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

Обновление # 2

Так что получается, что единственная причина, почему у меня заканчивается память, это то, что у нас, очевидно, естьнесколько файлов PDF, которые более 300 МБ загружены в базу данных.Я увеличил объем памяти, выделенной для PHP, до 512 МБ, и это, похоже, позволило мне завершить анализ всего.

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