神秘的GC缓存条目是什么意思?

23

有时候,我会收到这个奇怪的警告消息。通常在重新加载页面后就消失了。这是什么意思?我尝试了谷歌搜索但没有结果。

Warning: include(): GC cache entry '/.../...class.php' (dev=2049 ino=37120489) was on gc-list for 3840 seconds in /.../...class.php on line 111

1
我猜这与 APC 有关,你是否已安装了 APC? - tawfekov
2
APC 可能已经耗尽了内存。http://pecl.php.net/bugs/bug.php?id=16966 - teemitzitrone
这个问题已经被修复(从警告级别降为调试级别):https://github.com/krakjoe/apcu/pull/45/files - aimfeld
1个回答

34

这个问题明显来自于APC,源代码来自apc-3.1.6-r1包。当项目被插入用户缓存或文件缓存时,会调用该函数。

static void process_pending_removals(apc_cache_t* cache TSRMLS_DC)
{
slot_t** slot;
time_t now;

/* This function scans the list of removed cache entries and deletes any
 * entry whose reference count is zero (indicating that it is no longer
 * being executed) or that has been on the pending list for more than
 * cache->gc_ttl seconds (we issue a warning in the latter case).
 */

if (!cache->header->deleted_list)
    return;

slot = &cache->header->deleted_list;
now = time(0);

while (*slot != NULL) {
    int gc_sec = cache->gc_ttl ? (now - (*slot)->deletion_time) : 0;

    if ((*slot)->value->ref_count <= 0 || gc_sec > cache->gc_ttl) {
        slot_t* dead = *slot;

        if (dead->value->ref_count > 0) {
            switch(dead->value->type) {
                case APC_CACHE_ENTRY_FILE:
                    apc_warning("GC cache entry '%s' (dev=%d ino=%d) was on gc-list for %d seconds" TSRMLS_CC,
                        dead->value->data.file.filename, dead->key.data.file.device, dead->key.data.file.inode, gc_sec);
                    break;
                case APC_CACHE_ENTRY_USER:
                    apc_warning("GC cache entry '%s'was on gc-list for %d seconds" TSRMLS_CC, dead->value->data.user.info, gc_sec);
                    break;
            }
        }
        *slot = dead->next;
        free_slot(dead TSRMLS_CC);
    }
    else {
        slot = &(*slot)->next;
    }
} 
}

从 APC 配置 ( http://cz.php.net/manual/en/apc.configuration.php#ini.apc.gc-ttl )

apc.gc_ttl integer

缓存条目在垃圾回收列表中可以保留的秒数。如果服务器进程在执行缓存的源文件时死机,此值提供了故障安全机制;如果修改了该源文件,则为旧版本分配的内存将在 TTL 达到之前不会被回收。将其设置为零以禁用此功能。

我们在以下情况下收到消息“在 gc-list 上 %d 秒内的 GC 缓存条目 '%s' (dev=%d ino=%d)”或 “在 gc-list 上 %d 秒内的 GC 缓存条目 '%s'”:

(gc_sec > cache->gc_ttl) && (dead->value->ref_count > 0)

第一个条件意味着,缓存项在 apc.gc_ttl 秒之后被删除,并且仍在垃圾回收器列表中。第二个条件意味着,该项仍在被引用。

例如,当进程意外死亡时,引用计数没有减少。首先,在 APC 缓存中启动 apc.ttl 秒,然后删除该项(不会再有下一个对该项的调用)。现在,该项在垃圾回收器列表(GC)中,并且 apc.gc_ttl 超时正在运行。如果 apc.gc_ttl 小于(现在 - 项删除时间),则会发出警告并完全清除该项。

请尝试检查您的日志(Web 服务器、PHP、系统/内核)以了解关键错误,例如 PHP、Web 服务器段错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接