【发布时间】:2010-09-23 17:25:30
【问题描述】:
我的网站允许用户上传包含书籍列表的 csv 文件。然后该脚本读取该文件并使用 PEAR Services_Amazon 类针对 Amazon 检查 isbn 编号,返回增强的图书数据。但是,每当我在书籍列表上运行脚本时,消耗的内存量都会稳步增加,直到出现致命错误。目前,分配了 32 MB,我只能在 CSV 文件崩溃之前读取 370 条记录。
我有一个要导入 4500 条记录文件的用户和一个具有 256 MB RAM 的虚拟服务器,因此增加内存限制不是解决方案。
这是 CSV 导入的简化版本:
$handle = fopen($filename, "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$isbn = $data[6];
checkIsbn($isbn);
}
这是该函数的精简版:
function checkIsbn($isbn) {
$amazon = &new Services_Amazon(ACCESS_KEY_ID, SECRET_KEY, ASSOC_ID);
// -- $options array filled with $isbn, other requested info --
$products = $amazon->ItemSearch('Books', $options);
// -- Then I create an array from the first result --
$product = $products['Item'][0];
$title = $product['ItemAttributes']['Title'];
// -- etc... various attributes are pulled from the $product array --
mysql_query($sql); // -- put attributes into our DB
unset($product);
unset($products);
usleep(1800000); // maximum of 2000 calls to Amazon per hour as per their API
return $book_id;
}
我尝试过:在函数和 CSV 导入代码中取消设置数组并将它们设置为 NULL。我增加了所有超时时间以确保这不是问题。我安装了 xdebug 并运行了一些测试,但我发现每次访问 Amazon 类时脚本在内存中不断增加(我不是 xdebug 专家)。我在想,也许 Services_Amazon 类中的变量在每次运行时都没有被清除,但不知道从这里去哪里。我希望取消设置两个数组可以做到这一点,但没有运气。
编辑:更新:我认为这可能是 PEAR 类中的一个问题(并且查看此处与 PEAR 相关的一些问题,这似乎是可能的)。无论如何,目前我的 OOP 技能很少,所以我找到了一种方法来通过多次重新加载页面来做到这一点 - 有关详细信息,请参阅下面的答案。
【问题讨论】:
-
我会检查是否可以在该类中找到任何缓存。同时:使用 `&new` 已经被弃用很长时间了,所以除非你还在使用 PHP4,否则我会放弃
&。 -
有缓存,但我相信它只是缓存了亚马逊的输出,所以你可以再次参考它。我只引用每条记录一次。
标签: php memory-leaks pear