gpt4 book ai didi

php - 为什么 PHP Doctine 的 free() 不工作?

转载 作者:可可西里 更新时间:2023-11-01 13:59:15 26 4
gpt4 key购买 nike

这是给所有 Doctrine 用户的。我有一个 PHP CLI 守护进程,它每 n 秒检查一次表以查找尚未处理的条目。它基本上是一个先进先出。无论如何,我总是超过分配给 PHP 的内存,因为 Doctrine 不会释放它的资源。为了解决这个问题,它提供了免费的查询对象。我似乎无法让它发挥作用。这是代码:

 22     print "You are using " . (memory_get_usage() / 1024). "\n";
23 $query = Doctrine_Query::create()
24 ->from('SubmissionQueue s')
25 ->where('s.time_acted_on IS NULL')
26 ->orderby('s.time_queued')
27 ->limit(1)
28 ->execute();
29 print $query[0]->time_queued . "\n";
30 $query->free();

知道我做错了什么吗?

编辑:我正在使用 1.0.3

编辑:我已经尝试了以下所有建议。我对 unset() 抱有很大的希望,因为在我找到 free() 之前我已经把它放在那里了。

这里有更多的代码可能会提供帮助。在您质疑连接的打开和关闭之前,生成子进程的将是守护进程,并且根据我的经验,连接必须是唯一的。

  1 <?php
2
3 require_once('/usr/local/lib/php/Doctrine/lib/Doctrine.php');
4
5 spl_autoload_register(array('Doctrine', 'autoload'));
6
7 $manager = Doctrine_Manager::getInstance();
8 $manager->setAttribute('model_loading','conservative');
9 Doctrine::loadModels('lib/model/master');
10
11 while(1){
12 print "You are using " . intval(memory_get_usage() / 1024) . "\n";
13 $manager->connection('********************************************','master');
14 $query = Doctrine_Query::create()
15 ->from('SubmissionQueue s')
16 ->where('s.time_acted_on IS NULL')
17 ->orderby('s.time_queued')
18 ->limit(1)
19 ->execute();
20 print "[" . $query[0]->time_queued . "]\n";
21 $query->free();
22 unset($query);
23 $query = null;
24 $manager->closeConnection(Doctrine_Manager::getInstance()->getConnection('master'));
25 sleep(5);
26 }
27

一些示例输出:

You are using 14949KB
[2008-11-17 13:59:00]
You are using 14978KB
[2008-11-17 13:59:00]
You are using 15007KB
[2008-11-17 13:59:00]
You are using 15035KB
[2008-11-17 13:59:00]
You are using 15064KB
[2008-11-17 13:59:00]
You are using 15093KB
[2008-11-17 13:59:00]
You are using 15121KB
[2008-11-17 13:59:00]
You are using 15150KB
[2008-11-17 13:59:00]
You are using 15179KB
[2008-11-17 13:59:00]
You are using 15207KB
[2008-11-17 13:59:00]
You are using 15236KB
[2008-11-17 13:59:00]
You are using 15265KB
[2008-11-17 13:59:00]
You are using 15293KB
[2008-11-17 13:59:00]
You are using 15322KB

最佳答案

问题是,free() 并没有从内存中删除 Doctrine 对象,只是消除了对这些对象的循环引用,使得垃圾收集器可以清理这些对象。请看23.6 Free ObjectsDoctrine manual :

As of version 5.2.5, PHP is not able to garbage collect object graphs that have circular references, e.g. Parent has a reference to Child which has a reference to Parent. Since many doctrine model objects have such relations, PHP will not free their memory even when the objects go out of scope.

For most PHP applications, this problem is of little consequence, since PHP scripts tend to be short-lived. Longer-lived scripts, e.g. bulk data importers and exporters, can run out of memory unless you manually break the circular reference chains. Doctrine provides a free() function on Doctrine_Record, Doctrine_Collection, and Doctrine_Query which eliminates the circular references on those objects, freeing them up for garbage collection.

解决方案应该是在使用free()之后unset()$query对象:

$query = Doctrine_Query::create()
->from('SubmissionQueue s')
->where('s.time_acted_on IS NULL')
->orderby('s.time_queued')
->limit(1);
$query->execute();
print $query[0]->time_queued . "\n";
$query->free();
unset($query); // perhaps $query = null; will also work

关于php - 为什么 PHP Doctine 的 free() 不工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/295662/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com