亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

PHP對象相互引用的內(nèi)存溢出實例分析

 更新時間:2014年08月28日 10:20:45   投稿:shichen2014  
這篇文章主要介紹了PHP對象相互引用的內(nèi)存溢出實例分析,是PHP5.3以下版本中常見的一個bug,文中給出了解決方法,需要的朋友可以參考下

通常來說使用腳本語言最大的好處之一就是可利用其擁有的自動垃圾回收機制來釋放內(nèi)存。你不需要在使用完變量后做任何釋放內(nèi)存的處理,因為這些PHP會幫你完成。
當然,我們可以按自己的意愿調(diào)用 unset() 函數(shù)來釋放內(nèi)存,但通常不需要這么做。
不過在PHP里,至少有一種情況內(nèi)存不會得到自動釋放,即便是手動調(diào)用 unset()。詳情可考PHP官網(wǎng)關于內(nèi)存泄露的分析:http://bugs.php.net/bug.php?id=33595。

問題癥狀如下:

如果兩個對象之間存在著相互引用的關系,如“父對象-子對象”,對父對象調(diào)用 unset()不會釋放在子對象中引用父對象的內(nèi)存(即便父對象被垃圾回收,也不行)。

是不是有些糊涂了?我們來看下面的這段代碼:

<?
phpclass Foo {
 function __construct(){
 $this->bar = new Bar($this);
 }
}
class Bar {
 function __construct($foo = null){
 $this->foo = $foo;
 }
}
while (true) {
 $foo = new Foo();
 unset($foo);
 echo number_format(memory_get_usage()) . " ";
}
?>

運行這段代碼,你會看到內(nèi)存使用率越來越高越來越高,直到用光光。

...33,551,61633,551,97633,552,33633,552,696PHP Fatal error: Allowed memory size of 33554432 bytes exhausted(tried to allocate 16 bytes) in memleak.php on line 17

對大部分PHP程序員來講這種情況不算是什么問題??扇绻阍谝粋€長期運行的代碼中使用到了一大堆相互引用的對象,尤其是在對象相對較大的情況下,內(nèi)存會迅速地消耗殆盡。

Userland解決方案

雖然有些乏味、不優(yōu)雅,但之前提到的 bugs.php.net 鏈接中提供了一個解決方案。
這個方案在釋放對象前使用一個 destructor 方法以達到目的。Destructor 方法可將所有內(nèi)部的父對象引用全部清除,也就是說可以將這部分本來會溢出的內(nèi)存釋放掉。

以下是“修復后”的代碼:

<?
phpclass Foo {
 function __construct(){
 $this->bar = new Bar($this);
 }
 function __destruct(){
 unset($this->bar);
 }
}
class Bar {
 function __construct($foo = null){
 $this->foo = $foo;
 }
}
while (true) {
 $foo = new Foo();
 $foo->__destruct();
 unset($foo);
 echo number_format(memory_get_usage()) . " ";
}
?>

注意那個新增的Foo::__destruct()方法,以及在釋放對象前對 $foo->__destruct() 的調(diào)用。現(xiàn)在這段代碼解決了內(nèi)存使用率一直增加的問題,這么一來,代碼就可以很好的工作了。

PHP內(nèi)核解決方案

為什么會有內(nèi)存溢出的發(fā)生?我對PHP內(nèi)核方面的研究并不精通,但可以確定的是此問題與引用計數(shù)有關系。
在 $bar 中引用 $foo 的引用計數(shù)不會因為父對象 $foo 被釋放而遞減,這時PHP認為你仍需要 $foo 對象,也就不會釋放這部分的內(nèi)存。原理大致如此。

通俗的來說,大體意思是:一個引用計數(shù)沒有遞減,所以一些內(nèi)存永遠得不到釋放。
此外在前面提到的 bugs.php.net 鏈接中指出了修改垃圾回收的過程將會犧牲極大的性能,需要讀者對此注意。

與其改變垃圾回收的過程,為什么不用 unset() 對內(nèi)部對象做釋放的工作呢?(或者在釋放對象的時候調(diào)用 __destruct()?)
也許PHP內(nèi)核開發(fā)者可以在此或其他地方,對這種垃圾回收處理機制做出修改。

相信本文所述對大家深入理解PHP運行原理有所幫助。

相關文章

  • php 采集書并合成txt格式的實現(xiàn)代碼

    php 采集書并合成txt格式的實現(xiàn)代碼

    記得上次有過一個叫采集后的處理這個就是它的升級版本 連采再處理,合成一本書txt的。
    2009-03-03
  • php中isset與empty函數(shù)的困惑與用法分析

    php中isset與empty函數(shù)的困惑與用法分析

    這篇文章主要介紹了php中isset與empty函數(shù)的困惑與用法,結合實例形式分析了php中isset與empty函數(shù)的功能、用法、區(qū)別及相關使用注意事項,需要的朋友可以參考下
    2019-07-07
  • PHP操作XML中XPath的應用示例

    PHP操作XML中XPath的應用示例

    這篇文章主要介紹了PHP操作XML中XPath的應用,結合實例形式分析了php使用XPath進行xml節(jié)點查詢的相關操作技巧,需要的朋友可以參考下
    2019-07-07
  • 詳解PHP數(shù)組賦值方法

    詳解PHP數(shù)組賦值方法

    這篇文章主要介紹了詳解PHP數(shù)組賦值方法,文章就怎樣創(chuàng)建數(shù)組、怎樣給PHP數(shù)組賦值,文章都做了詳細的介紹和講解,希望對大家有幫助。
    2015-11-11
  • PHPWind與Discuz截取字符函數(shù)substrs與cutstr性能比較

    PHPWind與Discuz截取字符函數(shù)substrs與cutstr性能比較

    PHP性能優(yōu)化系列第四期實戰(zhàn)篇,如何使用PEAR Benchmark類工具獲取函數(shù)執(zhí)行性能,這里以PHPWind與Discuz!兩個社區(qū)論壇的截取字符函數(shù)substrs與cutstr為例,分析兩個函數(shù)的執(zhí)行性能情況
    2011-12-12
  • PHP中使用正則表達式提取中文實現(xiàn)筆記

    PHP中使用正則表達式提取中文實現(xiàn)筆記

    這篇文章主要介紹了PHP中使用正則表達式提取中文實現(xiàn)筆記,本文還講解了韓文、日文的正則表達式,并同時給出實現(xiàn)代碼和使用示例,需要的朋友可以參考下
    2015-01-01
  • php 8小時時間差的解決方法小結

    php 8小時時間差的解決方法小結

    前幾天發(fā)現(xiàn)一個問題 date("Y-m-d G:i T",time()) 取出來的時間和本地時間老差8個小時,可我的系統(tǒng)明明是中國標準時(GMT+8),最后終于找到了問題所在。
    2009-12-12
  • php版微信返回用戶text輸入的方法

    php版微信返回用戶text輸入的方法

    這篇文章主要介紹了php版微信返回用戶text輸入的方法,結合實例形式分析了php實現(xiàn)的微信解析及返回用戶輸入數(shù)據(jù)的相關操作技巧,需要的朋友可以參考下
    2016-11-11
  • PHP正則匹配到2個字符串之間的內(nèi)容方法

    PHP正則匹配到2個字符串之間的內(nèi)容方法

    今天小編就為大家分享一篇PHP正則匹配到2個字符串之間的內(nèi)容方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • PHP實現(xiàn)基于圖的深度優(yōu)先遍歷輸出1,2,3...n的全排列功能

    PHP實現(xiàn)基于圖的深度優(yōu)先遍歷輸出1,2,3...n的全排列功能

    這篇文章主要介紹了PHP實現(xiàn)基于圖的深度優(yōu)先遍歷輸出1,2,3...n的全排列功能,涉及php數(shù)據(jù)結構中圖的遍歷及全排列相關數(shù)學運算技巧,需要的朋友可以參考下
    2017-11-11

最新評論