Chr*_*anz 5 php memory orm doctrine
这是一个适用于你们任何一个Doctrine用户的人.我有一个PHP CLI守护进程,每隔n秒检查一次表,以查找尚未处理的条目.它基本上是一个FIFO.无论如何,我总是超过分配给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();
Run Code Online (Sandbox Code Playgroud)
我有什么想法我做错了吗?
编辑:我使用的是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
Run Code Online (Sandbox Code Playgroud)
一些示例输出:
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
Run Code Online (Sandbox Code Playgroud)
问题是,这free()不会从内存中删除Doctrine对象,只是消除了对这些对象的循环引用,使垃圾收集器可以清理这些对象.请参阅Doctrine手册中的23.6 Free Objects:
从版本5.2.5开始,PHP无法垃圾收集具有循环引用的对象图,例如,Parent具有对Child的引用,该引用具有对Parent的引用.由于许多学说模型对象具有这样的关系,即使对象超出范围,PHP也不会释放它们的内存.
对于大多数PHP应用程序来说,这个问题并不重要,因为PHP脚本往往是短暂的.除非您手动断开循环引用链,否则寿命较长的脚本(例如批量数据导入程序和导出程序)可能会耗尽内存.Doctrine在Doctrine_Record,Doctrine_Collection和Doctrine_Query上提供了一个free()函数,它消除了对这些对象的循环引用,将它们释放出来进行垃圾回收.
该解决方案应该是unset()在$query使用后的对象free():
$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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5010 次 |
| 最近记录: |