PHP的垃圾收集澄清

从PHP手册中,session.gc_probability和session.gc_divisor声明gc将基于这个概率发生。 我明白了。

我不清楚的是,这个概率是按照会话还是总体来说的。

所以如果我的概率是GC的1%(1/100),那么这是否意味着如果一个会话不断扩展,每次有1%的改变,特定的会话将被清除? 或者这是否意味着所有现有会议(以及新会议)的1%将触发所有其他会议的GC?

我很确定这是后者,我只是想确定一下。

这个问题的目的是在我们的网站上,我希望用户有长期的会议(6个月)。 如果所有会话中有1%触发了GC,那么这将有效地消除长期会话的目的,因为GC最终会每隔一两个小时发生一次。

每次执行PHP脚本并启动会话时,都有可能会扫描会话文件夹,从而导致旧会话中断。

清理只会删除在一定时间内未被访问的会话。 但是,PHP不能保证会话将在这段时间内被销毁。

您的长期会议策略应该可以正常工作,但是您可能希望将1%减less到0.1%

另一件需要注意的事情是操作系统可能会在重启时清理你的/ tmp文件夹,所以即使PHP不会这样做。

我上次每次查看源文件session_start()时,都会用“除数”和概率来“掷骰子”。 如果您点击,则会删除session.save_path目录中比session.gc_maxlifetime更早的所有文件。 我忘了它是否使用了文件的修改或访问时间,虽然它在正常情况下应该没有问题,因为PHP在脚本执行结束时默认覆盖会话文件,所以mod和访问时间几乎总是非常接近。

 // Rough psuedo code of how php's session_start() function works regarding garbage collection. function session_start() { $percentChanceToGC = 100 * ini_get('session.gc_probability') / ini_get('session.session.gc_divisor'); $shouldDoGarbageCollection = rand(1, 100) < $percentChanceToGC; if ($shouldDoGarbageCollection) { $expiredCutoffTime = time() - ini_get('session.gc_maxlifetime'); foreach (scandir(ini_get('session.save_path')) as $sessionFile) { if (filemtime($sessionFile) < $expiredCutoffTime) { unlink($sessionFile); } } } // ... rest of code .... } 

我不知道有多less会话文件,如果你想让它们至less生存6个月,那么你最终会遇到什么问题。 考虑一下PHP可能需要一些时间来统计成千上万的文件来确定他们的年龄。 也许考虑其他选项来持久存储这些数据。 或者你可以禁用php gc,只需运行一个cron作业来删除陈旧的会话文件。 否则,1%的请求会触发gc,必须等待php; 换句话说,它可能会滞后。

我不是这方面的专家,但是通过阅读手册,我会提请你注意另一个设置, session.gc_maxlifetime 。 从文档:

session.gc_maxlifetime指定数据将被视为“垃圾”并可能清理的秒数。 垃圾收集可能会在会话开始时发生(取决于session.gc_probabilitysession.gc_divisor )。

因此,如果您将此设置设置为适当的值( 60 * 60 * 24 * 365 / 2 15768000半年,那么15768000 ),则无论其他设置如何,相应的数据都将无法进行垃圾回收。