【问题标题】:PHP MongoDB findOne Memory LeakPHP MongoDB findOne 内存泄漏
【发布时间】:2014-04-16 11:57:13
【问题描述】:

我发现了一些关于 php mongodb 驱动程序的内存泄漏问题的旧帖子。但没有人为旧版本的 php mongodb 驱动程序提供最终解决方案或解释。

我的驱动程序版本是 1.4.5(稳定) 使用 PHP 5.3.10

带有调试回显的代码:

     echo memory_get_usage()." in MB : "; 
        echo memory_get_usage()/1024/1024;
        echo "<br>";
        unset($cursor);
        $dt = new DateTime($day." 00:00:00", new DateTimeZone($this->timezone));
        $mongodate = new MongoDate($dt->getTimestamp());
       // print_r($mongodate);
        $cursor = $dc->findOne(array('keyword' => $keyword, 'date' => $mongodate));


        echo "Cursor loaded Doc (".$cursor['_id'].") : ";
        echo memory_get_usage()." in MB : "; 
        echo memory_get_usage()/1024/1024;
        echo "<br>";

** Echos 真实内存使用情况**

3932160 in MB : 3.75
Cursor geladen Doc (534cdee3c30fd1b8ee0bb641) : 218305980 in MB : 208.1928062439

带调试的代码回显真实内存使用情况:

        echo memory_get_usage(true)." in MB : "; 
        echo memory_get_peak_usage(true)/1024/1024;
        echo "<br>";
        unset($cursor);
        $dt = new DateTime($day." 00:00:00", new DateTimeZone($this->timezone));
        $mongodate = new MongoDate($dt->getTimestamp());
       // print_r($mongodate);
        $cursor = $dc->findOne(array('keyword' => $keyword, 'date' => $mongodate));
        /*
        echo "<pre>";
        print_r($cursor);
        echo "</pre>";
        */

        echo "Cursor loaded Doc (".$cursor['_id'].") : ";
        echo memory_get_usage(true)." in MB : "; 
        echo memory_get_peak_usage(true)/1024/1024;
        echo "<br>";

** Echos 真实内存使用情况**

3932160 in MB : 3.75
Cursor loaded Doc (534cdee3c30fd1b8ee0bb641) : 218628096 in MB : 224.5

因此,只有一个 Documents 会增加超过 200 MB 的内存。

bitrs3:PRIMARY> var doc = db.dailies.findOne({"_id" : ObjectId("534cdee3c30fd1b8ee0bb641")})
bitrs3:PRIMARY> Object.bsonsize(doc)
16754823

加载的文档确实不小,它有 16754823 Bytes 所以达到了最大 Bson Size 16 MB

我仍然想知道从结果中创建数组的 findOne + 游标操作需要这么多内存是否正常。

【问题讨论】:

  • 在使用 php 5.3 和 5.4 时,我肯定不会在 php 驱动程序 1.4 上得到这个,不确定这里到底发生了什么。您是否在形成 MongoDate 之后但在 findOne() 之前检查了内存使用情况?
  • @Sammaye 我会检查一下给我一个秒
  • 3932160 in MB : 3.75 MongoDate created : 3825472 in MB : 3.6482543945312 Cursor loaded Doc (534cdee3c30fd1b8ee0bb641) : 218307056 in MB : 208.19383239746
  • 我发现这篇有趣的文章可能会解释一些关于 php 内存使用的事情nikic.github.io/2011/12/12/…
  • 因为 Derick 或 Hanes 可能会问;你能更新到 1.5 再试一次吗?

标签: php mongodb memory-leaks


【解决方案1】:

您可以验证这是否是“与 PHP 做生意的成本”,或者您是否通过序列化数组(使用 serialize() 甚至 json_encode())发现驱动程序中的错误并将其保存到文件中。

然后你 unserialize() (或 json_decode()) 文件的内容并检查内存使用情况。 如果内存使用量相似,您会看到 PHP 输入的实际开销。

<?php
$mc = new MongoClient;
$collection = $mc->selectCollection("myDB", "myCollection");
$d = $collection->findOne(array("my" => "criteria"));
var_dump(memory_get_usage() / 1024 / 1024);
file_put_contents("serialized.bin", serialize($d));
?>

然后再次加载:

<?php
$val = unserialize(file_get_contents("serialized.bin"));
var_dump(memory_get_usage() / 1024 / 1024);
?>

编辑:先发制人地澄清任何误解。 一个 16Mb 的 MongoDB 文档通常不需要数百兆的内存。

但是,如果您在该对象中拥有数十万个元素,那么单个元素开销开始计算您拥有的每个元素的倍数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-10
    • 2023-03-17
    • 2012-04-17
    • 2012-01-12
    • 2017-01-28
    • 2016-03-30
    • 1970-01-01
    • 2014-04-29
    相关资源
    最近更新 更多