如何管理 PHP 内存?

How to manage PHP memory?

我编写了一个一次性脚本,用于解析保存在数据库中的 PDF。到目前为止它工作正常,直到我在解析 2,700 多个文档后 运行 内存不足。

脚本的基本流程如下:

  1. 获取要解析的所有文档 ID 的列表并将其保存为会话中的数组(~155k 文档)。
  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..

  1. 对 AJAX 请求的响应通常包括脚本是否已完成解析全部 ~155k 文档的状态 - 如果未完成,则会发出另一个 AJAX 请求来解析接下来的 50 . 每次请求之间有5秒的延迟。

问题


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

所以我不太确定为什么,但是将我正在解析的文档数量从每个批次的 50 减少到 10 似乎解决了这个问题。我现在已经超过 5,000 个文档,脚本仍然是 运行。我唯一的猜测是,当我解析 50 个文档时,我一定遇到了很多大文件,这些文件用完了所有分配的内存。

更新#1

我在 8,500 多个文档中遇到另一个关于内存 运行 的错误。我已经将批次进一步减少到每个 5 个文档,明天会看到它是否一直解析所有内容。如果还是不行,我就临时增加分配的内存。

更新 #2

事实证明,我 运行 内存不足的唯一原因是我们显然有多个超过 300MB 的 PDF 文件上传到数据库中。我将分配给 PHP 的内存增加到 512MB,这似乎让我能够完成对所有内容的解析。