2014-05-10 99 views
1

对于操作码缓存(php 5.5)失效,我写了一个小脚本。但是,状态确实告诉我失效失败。这是如何发生的?opcache失效不更新opcache状态

<?php 
$scripts = opcache_get_status(true)["scripts"];  
$failures = array(); 
foreach (array_keys($scripts) as $file) { 
    $result = opcache_invalidate($file, true); 
    if (!$result) $failures[] = $file; 
} 
if(count($failures) !== 0) { 
    exit("Failed to clear OPcache for files " . implode(", ", $failures)); 
} 

echo sprintf("%s OPcache files cleared\n", count($scripts)); 

$scripts = opcache_get_status(true)["scripts"]; 
echo sprintf("There are still %s files in the cache", count($scripts)); 

它现在是一个非常简单的脚本(这将是Soflomo\Cache的一部分)。我的问题是,第一个回声(“X清除网络的OPcache文件”)打印与最后一个回声相同的号码(“缓存中还有x个文件”)语句!

如何重现:

  1. 安装一个大FW应用程序(这里使用ZF2)
  2. 放置在上面的应用程序的根目录文件
  3. 运行应用程序(500+文件将得到缓存)
  4. 运行脚本,输出将类似于:

560 OPcache文件CLEA红

还有560个文件缓存

任何人都可以解释一下吗?这些文件是否被清除,或不是?

PS。我知道上述内容可以替换为opcache_reset(),但脚本会过滤一部分文件作为下一步。它旨在清除单个应用程序中文件的操作码,即使在单个服务器上运行多个应用程序。重置将清除所有这些文件,这不是一个选项。

回答

3

Opcache不会从内存中驱逐无效项 - 它们会一直保持到池已满为止,此时内存已被完全清除。存在无效的缓存条目不会阻止PHP再次加载/编译该文件。

+0

感谢您的快速回复。 “他们呆在那里,直到池满了,内存被完全清除了”意味着旧的东西留在内存中,将保持在那里无所事事,当这个过程最终达到内存限制时,它会刷新整个内存所有的“有效”物品都走了吗?换一种说法;也许这不是一个好主意来清除缓存子集的缓存(即服务器上的单个应用程序)? –

+1

是的,这正是它的意思。对于大多数网站来说,内存相对便宜,只要你不经常部署,或者拥有基础设施来切换服务器进/出/按高速缓存,那就不是问题。但是,这不适用于每个人 - 如果这适用于你,那么你可能会更好地恢复到apc – symcbean

+0

想知道现在,如果我无效文件foo.php,然后重新加载foo.php,所以它被再次缓存,它是否被放置在内存中foo.php以前的地方,还是它需要opcache中的另一个“插槽”?另外,还有更多关于这方面的背景信息,我可以找出工作人员(希望没有阅读源代码,我猜这会很困难)。 –