一般的问题是:在PHP中取消设置String变量的值之后,是否可以从物理内存中删除该变量的值?
该问题是由安全标准的某些要求引起的(在处理某些重要数据时,应该没有办法将数据从内存转储到磁盘)。根据“ 内存是否已加密? ”主题,没有好的方法可以对内存中的数据进行加密。
因此,在PHP中取消设置String变量时,您不能肯定地说内存中的数据已被覆盖。关于为变量设置新值的相同故事。
因此,我是否有可能在不更改unset方法核心代码的情况下从内存中清除变量值?
前言:我确实知道'unset'在userland中是如何工作的,但我想知道它是如何在内部工作的.
当在zval结构上调用unset时,它会减少引用计数器(refcount__gc).当refcount__gc达到0时,该变量不再使用,可以删除.问题是它是否总是立即完成,或者在某些情况下它可以在以后由垃圾收集器完成?
我发现了两个相互矛盾的陈述:
unset()正如它的名字所说 - 取消设置一个变量.它不会强制立即释放内存.PHP的垃圾收集器会在看到拟合时执行它 - 尽快意图,因为无论如何都不需要那些CPU周期,或者在脚本耗尽内存之前,无论先发生什么.- Stackoverflow回答提到2009 php.net文档
相反的是:
当refcount达到零时,zval被销毁,它所持有的任何内存现在都是免费的 - 更好地理解PHP的垃圾收集,2012年文章
那么哪一个是正确的,比如PHP 5.3和PHP 5.5?如果可能,也许您可以提供PHP源代码中未设置定义的链接.谢谢!
在Code Igniter框架中有几个这种行为的例子 - 在方法的开头创建一个变量,使用它,在方法结束之前,取消设置这个变量.
他们为什么要取消他们?重点是什么?据我所知,局部变量无论如何都会在方法结束时死亡.
代码点火器,来自会话类(参见最后几行):
function sess_read()
{
// Fetch the cookie
$session = $this->CI->input->cookie($this->sess_cookie_name);
// No cookie? Goodbye cruel world!...
if ($session === FALSE)
{
log_message('debug', 'A session cookie was not found.');
return FALSE;
}
// Decrypt the cookie data
if ($this->sess_encrypt_cookie == TRUE)
{
$session = $this->CI->encrypt->decode($session);
}
else
{
// encryption was not used, so we need to check the md5 hash
$hash = substr($session, strlen($session)-32); // get last 32 chars
$session = substr($session, 0, strlen($session)-32); …Run Code Online (Sandbox Code Playgroud) 我正在使用实体存储库创建查询,它似乎存在内存泄漏。
在我的实体存储库类中:
echo 'mem 1 : ' . (memory_get_usage()/1024/1024) . "<br />\n";
$query = $this->createQueryBuilder('a')->select('a','b','c','...');
echo 'mem 2 : ' . (memory_get_usage()/1024/1024) . "<br />\n";
$r = $query->getQuery()->getResult();
echo 'mem 3 : ' . (memory_get_usage()/1024/1024) . "<br />\n";
$this->clear(true);
$query->getQuery()->free(true);
unset($r);
echo 'mem 4 : ' . (memory_get_usage()/1024/1024) . "<br />\n";
Run Code Online (Sandbox Code Playgroud)
输出:
内存 1:5.0805282592773
内存 2:5.0998611450195
内存 3:91.49528503418
内存 4:77.939567565918
为什么释放内存后内存没有恢复到初始大小(5 MB)?
而且只能从 91 传到 77。