6

PHP 文档有这样的说法pg_free_result()

仅当脚本执行期间的内存消耗存在问题时才需要调用此函数。否则,脚本结束时将自动释放所有结果内存。

http://www.php.net/manual/en/function.pg-free-result.php

我会(也许天真地)期望调用返回的资源pg_query()在超出范围时被垃圾收集。

在这样的假设函数中:

function selectSomething ()
{
    $res = pg_query("SELECT blah FROM sometable");
    // do something with $res
    pg_free_result($res);   // required or not?
}

最后真的有必要打电话pg_free_result()吗?

换句话说,如果我调用这个函数 1000 次,它会占用内存来存储所有 1000 个结果吗?

编辑:我说的是典型案例,即pg_connect()而不是pg_pconnect().

4

2 回答 2

1

正如 Elias Van Ootegem 正确指出的那样,您几乎可以肯定使用的是持久连接。在查询后使用持久连接,结果必须在内存中继续,因为您可能希望从中收集更多数据(例如最后一个错误)。

所以它归结为良好的做法。如果您在具有 2M 可用内存的环境中运行,并且您的脚本有时可以达到 0.1M 内存,那么上限是 20 个并发连接调用该脚本。之后,进一步的 Web 请求将排队或丢弃。不需要天才就能意识到这可能对 DDoS 攻击有多脆弱。

因此,最佳做法是在完成后立即清空内存。这几乎适用于任何编程或脚本。当系统受到压力并且需求很高时,在整个内存范围内可以服务的请求越多越好。如果您可以降低脚本的最大内存占用,则可以增加可以合理尝试调用它的并发连接数,从而增加脚本可以处理的负载。

做事的理想方式是尽快释放资源。仅仅因为我们没有,而且在测试期间一切似乎都正常工作,没有理由不这样做。

于 2013-05-16T10:26:59.897 回答
0

这是我的测试结果:

(之前/之后)

与:631288 / 631384

没有:631288 / 631640

随意使用以下代码自行运行测试:

<?php
class test {
    private static $tests = 5000;

    public function __construct() {
        $dbconn = pg_connect("host=### dbname=### user=### password=###")
            or die('Could not connect: ' . pg_last_error());

        self::test(self::$tests, true);
        self::test(self::$tests, false);
    }

    private function test($times, $with) {
        echo ($with ? "with:<br />\n" : "without:<br />\n") . memory_get_usage() ."<br />\n";

        for($i = 0; $i < $times; $i++) {
            $res = pg_query("SELECT * FROM chowder");

            if($with) {
                pg_free_result($res);
            }
        }

        echo memory_get_usage() ."<br /><br />\n\n";
    }

}

$test = new test();
于 2013-05-15T00:50:28.210 回答