PHP垃圾收集澄清

时间:2011-10-19 22:26:39

标签: php session garbage-collection

根据PHP手册,session.gc_probability和session.gc_divisor声明gc将基于此概率发生。我知道了。

我不清楚的是这个概率是基于会话还是整体。

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

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

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

3 个答案:

答案 0 :(得分:11)

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

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

您的长期会话策略应该可以正常运行,但您可能希望将1%减少到0.1%

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

答案 1 :(得分:7)

上次我查看源代码,每次调用session_start()“掷骰子”可以说,使用除数和概率。如果您点击,则会删除session.save_path目录中早于session.gc_maxlifetime的所有文件。我忘记了它是否使用了文件的修改或访问时间,虽然它在正常情况下无关紧要,因为php默认会在脚本执行结束时覆盖会话文件,因此mod和访问时间几乎总是非常紧密地匹配。 / p>

// 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 ....
}

我不知道如果你希望它们至少活6个月,你最终会有多少个会话文件。考虑到php可能需要一段时间来统计数千个文件来确定它们的年龄。也许考虑其他选项来持久存储这些数据。或者您可以禁用php gc并只运行一个cron作业来删除陈旧的会话文件。否则,1%的请求将触发gc并且必须等待php;换句话说,它可能会滞后。

答案 2 :(得分:2)

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

  

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

因此,如果您将此设置设置为合适的值(60 * 60 * 24 * 365 / 2半年,那么15768000),那么无论其他什么,相应的数据都不符合垃圾回收的条件设置是。

相关问题