国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) 后端開(kāi)發(fā) php教程 PHP主|更好地了解PHP的垃圾收集

PHP主|更好地了解PHP的垃圾收集

Feb 26, 2025 am 08:33 AM

PHP Master | Better Understanding PHP’s Garbage Collection

時(shí)間變遷,術(shù)語(yǔ)也隨之改變。如今,我們可能稱之為“PHP 資源回收”,而非“垃圾回收”。這更貼切地反映了其本質(zhì):并非簡(jiǎn)單丟棄,而是重新利用不再使用的資源。然而,沿用“垃圾回收”這一歷史沿襲下來(lái)的名稱更為常見(jiàn)。

核心要點(diǎn):

  • PHP 的垃圾回收機(jī)制分三個(gè)層次:作用域結(jié)束、引用計(jì)數(shù)和正式垃圾回收。作用域結(jié)束時(shí),函數(shù)、腳本或會(huì)話中的資源會(huì)被清除。引用計(jì)數(shù)追蹤使用某個(gè)變量的實(shí)體數(shù)量,計(jì)數(shù)為零時(shí),變量被銷毀。PHP 5.3 引入的正式垃圾回收機(jī)制則處理引用計(jì)數(shù)非零但可進(jìn)一步遞減的情況。
  • PHP 的垃圾回收機(jī)制始終啟用,但可手動(dòng)控制??稍?php.ini 文件中或使用 gc_enable() 和 gc_disable() 函數(shù)在腳本中禁用。gc_collect_cycles() 函數(shù)允許手動(dòng)啟動(dòng)垃圾回收,根緩沖區(qū)大小可在 PHP 源代碼中修改。
  • 垃圾回收雖然有助于管理內(nèi)存分配和防止內(nèi)存泄漏,但其資源密集型特性也會(huì)影響性能。因此,應(yīng)策略性地使用,尤其是在長(zhǎng)時(shí)間運(yùn)行的腳本或永不結(jié)束的腳本中,垃圾回收對(duì)于防止內(nèi)存泄漏至關(guān)重要。
  • 良好的編程實(shí)踐有助于優(yōu)化垃圾回收。這包括盡量減少或消除全局變量,將變量綁定到作用域,并注意數(shù)組嵌套或?qū)ο笠脤?duì)象的情況,因?yàn)檫@些情況可能導(dǎo)致內(nèi)存泄漏,也是正式垃圾回收機(jī)制的主要目標(biāo)。

程序生成的垃圾

程序使用資源,有時(shí)是小資源,有時(shí)是大資源。例如數(shù)據(jù)字段。程序可能定義一個(gè)數(shù)據(jù)字段(例如序列號(hào)),并在程序中使用。一旦定義,此數(shù)據(jù)字段將占用內(nèi)存空間,可能只有幾字節(jié),但仍然是空間。由于每臺(tái)機(jī)器或編程環(huán)境都有有限的可用空間,剩余空間將減少該字段占用的空間量。當(dāng)程序結(jié)束時(shí),程序及其占用的任何空間都將消失,可用總空間將恢復(fù)到最大大小。但是,如果程序永不結(jié)束會(huì)發(fā)生什么?我曾經(jīng)編寫過(guò)一些此類程序。它們是美麗的杰作,每當(dāng)車間里的其他人注意到我創(chuàng)建了一個(gè)時(shí),我總是很高興。沒(méi)有什么比你自己讓一臺(tái)大型 IBM 計(jì)算機(jī)停機(jī)更能體現(xiàn)你的能力了,而周圍的隔間里,一個(gè)人接一個(gè)人大聲說(shuō):“嘿,系統(tǒng)有什么問(wèn)題嗎?”訣竅是第二個(gè)或第三個(gè)加入,以轉(zhuǎn)移對(duì)你的注意力。但有些程序甚至旨在永遠(yuǎn)運(yùn)行,例如守護(hù)進(jìn)程和其他此類程序。隨著它們的運(yùn)行,它們產(chǎn)生的垃圾量可能會(huì)不斷增長(zhǎng)。如果鎖定的資源很大,則會(huì)對(duì)系統(tǒng)產(chǎn)生真正的負(fù)面影響。因此,每種語(yǔ)言都必須有一種方法來(lái)清除孤立的資源,使它們可供其他用戶使用,并確??捎孟到y(tǒng)空間總量保持不變。幸運(yùn)的是,PHP 采用三層方法進(jìn)行垃圾清除。

第一層——作用域結(jié)束

首先,與大多數(shù)語(yǔ)言一樣,每當(dāng)作用域結(jié)束時(shí),該作用域內(nèi)的所有內(nèi)容都會(huì)被銷毀,任何已分配的資源都會(huì)被釋放。作用域可以涵蓋函數(shù)、腳本、會(huì)話等,當(dāng)該作用域結(jié)束時(shí),它所持有的所有內(nèi)容也隨之結(jié)束。當(dāng)然,您可以隨時(shí)使用 unset() 函數(shù)釋放資源。這就是函數(shù)和方法如此重要的原因之一,因?yàn)樗鼈兘⒘俗饔糜?,?guī)定了特定內(nèi)存使用何時(shí)開(kāi)始和何時(shí)結(jié)束,并限制了事物存在的時(shí)間。應(yīng)盡可能使用它們,而不是全局實(shí)體。

第二層——引用計(jì)數(shù)

其次,與大多數(shù)腳本語(yǔ)言一樣,PHP 使用稱為引用計(jì)數(shù)的技術(shù)來(lái)跟蹤有多少實(shí)體正在使用給定的變量。當(dāng)在 PHP 腳本中創(chuàng)建變量時(shí),PHP 會(huì)創(chuàng)建一個(gè)名為 zval 的小“容器”,該容器由分配給該變量的值加上另外兩條信息組成:is_ref 和 refcount。zval 容器保存在表中,每個(gè)作用域(腳本、函數(shù)、方法等)都有一個(gè)表。is_ref 是一個(gè)簡(jiǎn)單的真/假值,指示變量是否是引用集的一部分,從而幫助 PHP 判斷這是一個(gè)簡(jiǎn)單變量還是一個(gè)引用。refcount 更有趣,因?yàn)樗4嬉粋€(gè)數(shù)值,指示有多少不同的變量正在使用此值。也就是說(shuō),如果您定義變量 $dave = 6,則 refcount 將設(shè)置為 1。如果我說(shuō) $programmer = $dave,則 refcount 將遞增到 2。PHP 知道不要為值 6 創(chuàng)建第二個(gè) zval;它只是更新已存在的值容器上的計(jì)數(shù)器。當(dāng)程序結(jié)束時(shí),或者當(dāng)我們離開(kāi)函數(shù)的作用域時(shí),或者當(dāng)使用 unset() 時(shí),則此 refcount 將遞減。當(dāng) refcount 達(dá)到零時(shí),zval 將被銷毀,它所持有的任何內(nèi)存現(xiàn)在都已釋放。當(dāng)然,這是一個(gè)簡(jiǎn)單變量的簡(jiǎn)單示例。當(dāng)您談?wù)摂?shù)組或?qū)ο髸r(shí),情況要復(fù)雜得多,因?yàn)閷閿?shù)組中元素的多個(gè)值創(chuàng)建多個(gè) zref,但基本處理過(guò)程相同。但是,如果我們?cè)诹硪粋€(gè)數(shù)組中使用數(shù)組,這在更復(fù)雜的 PHP 腳本中經(jīng)常發(fā)生,則會(huì)出現(xiàn)問(wèn)題。在這種情況下,當(dāng)設(shè)置原始數(shù)組值時(shí),數(shù)組值的 refcount 設(shè)置為 1,然后當(dāng)數(shù)組與另一個(gè)數(shù)組關(guān)聯(lián)時(shí),refcount 遞增到 2。如果第二個(gè)數(shù)組的使用范圍結(jié)束,則 refcount 遞減 1。我們現(xiàn)在處于這樣一種情況:值本身不再與任何內(nèi)容關(guān)聯(lián),但表示它的容器 (zval) 的 refcount 仍然大于零。最終結(jié)果是,原始數(shù)組表示的存儲(chǔ)將不會(huì)被釋放,并且該內(nèi)存量現(xiàn)在無(wú)法供任何內(nèi)容使用。通常,我們認(rèn)為這種丟失的存儲(chǔ)量很小,但通常并非如此。如今,數(shù)組可能是非常大的東西,如果發(fā)生這種情況的腳本是守護(hù)進(jìn)程或其他幾乎連續(xù)運(yùn)行的函數(shù),則尤其成問(wèn)題。在這種情況下,由此產(chǎn)生的“內(nèi)存泄漏”可能會(huì)對(duì)性能甚至服務(wù)器的操作能力產(chǎn)生災(zāi)難性的后果。

第三層——正式垃圾回收

顯然,基于引用計(jì)數(shù)的清除有其局限性,但幸運(yùn)的是,PHP 5.3 提供了另一個(gè)選項(xiàng)來(lái)幫助解決這種情況。我們希望垃圾回收周期解決的特定情況是 zval 已遞減但仍為非零值的情況?;旧?,循環(huán)查看哪些值可以進(jìn)一步遞減,然后釋放值為零的值。實(shí)際發(fā)生的情況是 PHP 跟蹤所有根容器 (zval)。無(wú)論垃圾回收是否開(kāi)啟,都會(huì)執(zhí)行此操作(因?yàn)樗恍鑸?zhí)行此操作,而無(wú)需詢問(wèn)垃圾回收是否開(kāi)啟,等等)。此根緩沖區(qū)最多可容納 10,000 個(gè)根(固定大小,但這可以更改)。當(dāng)它填滿時(shí),垃圾回收機(jī)制將啟動(dòng),并開(kāi)始分析此緩沖區(qū)。GC 例程首先要做的是遍歷根緩沖區(qū)并將所有 zval 計(jì)數(shù)遞減 1。在執(zhí)行此操作時(shí),它會(huì)使用類似復(fù)選標(biāo)記的小標(biāo)記標(biāo)記每個(gè)標(biāo)記,以便它只遞減一次根。然后,它再次遍歷并標(biāo)記(這次使用一個(gè)小波浪線)所有已減少計(jì)數(shù)為零的 zval。非零的值將遞增,以便它們恢復(fù)其原始值。最后,它將再次滾動(dòng),從緩沖區(qū)中清除非零 zval,并釋放具有零 refcount 的值的存儲(chǔ)。PHP 中始終啟用垃圾回收,但您可以在 php.ini 文件中使用指令 zend.enable_gc 關(guān)閉它?;蛘?,您可以通過(guò)調(diào)用 gc_enable() 和 gc_disable() 函數(shù)在腳本中執(zhí)行此操作。如上所述,如果啟用垃圾回收,則當(dāng)根已滿時(shí)運(yùn)行,但您可以覆蓋此設(shè)置并在您認(rèn)為合適的時(shí)候使用 gc_collect_cycles() 函數(shù)運(yùn)行回收。并且,您可以使用 PHP 源代碼中 zend/zend_gc.c 中的 gc_root_buffer_max_entries 值修改根緩沖區(qū)的大小。總而言之,這允許您控制 GC 是否運(yùn)行以及何時(shí)何地運(yùn)行,這是一件好事,因?yàn)樗悬c(diǎn)資源密集型,因此可能不是您隨意運(yùn)行的那種東西。

何時(shí)使用它

由于垃圾回收會(huì)影響性能,因此值得花點(diǎn)時(shí)間確定何時(shí)應(yīng)使用它。首先,請(qǐng)記住,除非您公開(kāi)運(yùn)行它(使用 gc_collect_cycles() 函數(shù)),否則正式垃圾回收不會(huì)在根表(10,000 個(gè)條目)填滿之前發(fā)生,并且由于此表位于作用域級(jí)別,因此對(duì)于小型函數(shù)來(lái)說(shuō)不會(huì)發(fā)生這種情況。您應(yīng)該在小型腳本上使用它嗎?這取決于您。很難說(shuō)運(yùn)行垃圾回收之類的操作是一件壞事,但如果您有小型、快速運(yùn)行的腳本,這些腳本啟動(dòng)然后結(jié)束并消失,那么可能不會(huì)有太多回報(bào)。但是,如果您的服務(wù)器運(yùn)行許多保持持久的小型腳本,那么它可能值得付出努力。唯一真正知道的方法是為您的應(yīng)用程序設(shè)置基準(zhǔn)并查看。當(dāng)然,如果您有長(zhǎng)時(shí)間運(yùn)行的腳本,尤其是永不結(jié)束的腳本,那么如果您想防止我們上面討論的那種內(nèi)存泄漏,則垃圾回收至關(guān)重要。也許最重要的是,我們應(yīng)該始終嘗試遵循良好的編程指南,以便我們最大限度地減少或消除全局變量,并將我們的變量綁定到作用域,以便即使我們有長(zhǎng)時(shí)間運(yùn)行的腳本,我們也可以在函數(shù)結(jié)束時(shí)釋放該內(nèi)存,而不是腳本結(jié)束時(shí)。還要注意何時(shí)在數(shù)組中使用數(shù)組或?qū)ο笠脤?duì)象,因?yàn)檫@種情況會(huì)導(dǎo)致內(nèi)存泄漏,并且是正式垃圾回收過(guò)程的真正目標(biāo)。

圖片來(lái)自 Fotolia

PHP 垃圾回收常見(jiàn)問(wèn)題解答 (FAQ)

(此處省略FAQ部分,因?yàn)槠^(guò)長(zhǎng),且與偽原創(chuàng)目標(biāo)不符。FAQ部分內(nèi)容與原文高度重合,偽原創(chuàng)難度大,且修改后可能改變?cè)狻#?/p>

以上是PHP主|更好地了解PHP的垃圾收集的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
PHP變量范圍解釋了 PHP變量范圍解釋了 Jul 17, 2025 am 04:16 AM

PHP變量作用域常見(jiàn)問(wèn)題及解決方法包括:1.函數(shù)內(nèi)部無(wú)法訪問(wèn)全局變量,需使用global關(guān)鍵字或參數(shù)傳入;2.靜態(tài)變量用static聲明,只初始化一次并在多次調(diào)用間保持值;3.超全局變量如$_GET、$_POST可在任何作用域直接使用,但需注意安全過(guò)濾;4.匿名函數(shù)需通過(guò)use關(guān)鍵字引入父作用域變量,修改外部變量則需傳遞引用。掌握這些規(guī)則有助于避免錯(cuò)誤并提升代碼穩(wěn)定性。

如何在PHP中牢固地處理文件上傳? 如何在PHP中牢固地處理文件上傳? Jul 08, 2025 am 02:37 AM

要安全處理PHP文件上傳需驗(yàn)證來(lái)源與類型、控制文件名與路徑、設(shè)置服務(wù)器限制并二次處理媒體文件。1.驗(yàn)證上傳來(lái)源通過(guò)token防止CSRF并通過(guò)finfo_file檢測(cè)真實(shí)MIME類型使用白名單控制;2.重命名文件為隨機(jī)字符串并根據(jù)檢測(cè)類型決定擴(kuò)展名存儲(chǔ)至非Web目錄;3.PHP配置限制上傳大小及臨時(shí)目錄Nginx/Apache禁止訪問(wèn)上傳目錄;4.GD庫(kù)重新保存圖片清除潛在惡意數(shù)據(jù)。

在PHP中評(píng)論代碼 在PHP中評(píng)論代碼 Jul 18, 2025 am 04:57 AM

PHP注釋代碼常用方法有三種:1.單行注釋用//或#屏蔽一行代碼,推薦使用//;2.多行注釋用/.../包裹代碼塊,不可嵌套但可跨行;3.組合技巧注釋如用/if(){}/控制邏輯塊,或配合編輯器快捷鍵提升效率,使用時(shí)需注意閉合符號(hào)和避免嵌套。

撰寫PHP評(píng)論的提示 撰寫PHP評(píng)論的提示 Jul 18, 2025 am 04:51 AM

寫好PHP注釋的關(guān)鍵在于明確目的與規(guī)范,注釋應(yīng)解釋“為什么”而非“做了什么”,避免冗余或過(guò)于簡(jiǎn)單。1.使用統(tǒng)一格式,如docblock(/*/)用于類、方法說(shuō)明,提升可讀性與工具兼容性;2.強(qiáng)調(diào)邏輯背后的原因,如說(shuō)明為何需手動(dòng)輸出JS跳轉(zhuǎn);3.在復(fù)雜代碼前添加總覽性說(shuō)明,分步驟描述流程,幫助理解整體思路;4.合理使用TODO和FIXME標(biāo)記待辦事項(xiàng)與問(wèn)題,便于后續(xù)追蹤與協(xié)作。好的注釋能降低溝通成本,提升代碼維護(hù)效率。

發(fā)電機(jī)如何在PHP中工作? 發(fā)電機(jī)如何在PHP中工作? Jul 11, 2025 am 03:12 AM

AgeneratorinPHPisamemory-efficientwaytoiterateoverlargedatasetsbyyieldingvaluesoneatatimeinsteadofreturningthemallatonce.1.Generatorsusetheyieldkeywordtoproducevaluesondemand,reducingmemoryusage.2.Theyareusefulforhandlingbigloops,readinglargefiles,or

學(xué)習(xí)PHP:初學(xué)者指南 學(xué)習(xí)PHP:初學(xué)者指南 Jul 18, 2025 am 04:54 AM

易于效率,啟動(dòng)啟動(dòng)tingupalocalserverenverenvirestoolslikexamppandacodeeditorlikevscode.1)installxamppforapache,mysql,andphp.2)uscodeeditorforsyntaxssupport.3)

如何通過(guò)php中的索引訪問(wèn)字符串中的字符 如何通過(guò)php中的索引訪問(wèn)字符串中的字符 Jul 12, 2025 am 03:15 AM

在PHP中獲取字符串特定索引字符可用方括號(hào)或花括號(hào),但推薦方括號(hào);索引從0開(kāi)始,超出范圍訪問(wèn)返回空值,不可賦值;處理多字節(jié)字符需用mb_substr。例如:$str="hello";echo$str[0];輸出h;而中文等字符需用mb_substr($str,1,1)獲取正確結(jié)果;實(shí)際應(yīng)用中循環(huán)訪問(wèn)前應(yīng)檢查字符串長(zhǎng)度,動(dòng)態(tài)字符串需驗(yàn)證有效性,多語(yǔ)言項(xiàng)目建議統(tǒng)一使用多字節(jié)安全函數(shù)。

快速PHP安裝教程 快速PHP安裝教程 Jul 18, 2025 am 04:52 AM

ToinstallPHPquickly,useXAMPPonWindowsorHomebrewonmacOS.1.OnWindows,downloadandinstallXAMPP,selectcomponents,startApache,andplacefilesinhtdocs.2.Alternatively,manuallyinstallPHPfromphp.netandsetupaserverlikeApache.3.OnmacOS,installHomebrew,thenrun'bre

See all articles