PHP中的OPCode和OPCache
PHP中的OPCode和OPCache
概述
PHP作為一門動態指令碼語言,其在zend虛擬機器執行過程為:讀入指令碼程式字串,經由詞法分析器將其轉換為單詞符號,接著語法分析器從中發現語法結構後生成抽象語法樹,再經靜態編譯器生成opcode,最後經直譯器模擬機器指令來執行每一條opcode。
確切地說,分成以下四個步驟:
1. Scanning(Lexing) ,將PHP程式碼轉換為語言片段(Tokens)
2. Parsing, 將Tokens轉換成簡單而有意義的表示式
3. Compilation, 將表示式編譯成Opocdes(位元組碼)
4. Execution, 順次執行Opcodes,每次一條,從而實現PHP指令碼的功能。
一、OPCode
1、什麼是opcode?
當一個 PHP 檔案被解釋執行的時候,首先是被編譯成名為 opcode (CPU 專用的機器語言指令)的中間程式碼,然後才被底層的虛擬機器執行。 如果PHP檔案沒有被修改過,opcode 始終是一樣的。這就意味著編譯步驟白白浪費了 CPU 的資源。
2、什麼是opcode快取?
此時 opcode 快取就派上用場了。通過將 opcode 快取在記憶體中,它能防止冗餘的編譯步驟,並且在下次呼叫執行時得到重用。一般執行過程是先檢查檔案的簽名(signature)或者修改時間,以防檔案有改動。
二、OPCache
1、什麼是OpCache?
OPCache 是Zend官方出品的,開放自由的 opcode 快取擴充套件。PHP 5.5.0 及後續版本中已經綁定了 OPcache 擴充套件。
1)opCache的作用
主要是為了減少重複編譯,從而減少CPU和記憶體的開銷。
2)opcache快取的內容
- OPCode
-
Interned String(可以理解為php請求生命週期中不需要釋放的String,包括:變數名、類名、方法名、字串、註釋等)
2、OPCache的工作原理
Opcache工作原理其實是使用了共享記憶體機制,將需要快取的內容放入到共享記憶體中,供其他程序使用。
因為Opcache在建立快取的過程中不會阻止其他程序讀取,所以在使用Opcache時要注意兩點,不然會大量消耗資源:
1)不要給Opcache設定過期時間
2)不要在流量高峰期釋出程式碼
3、OPCache的配置
1 //新增Opcache擴充套件 2 zend_extension=opcache.so 3 //開啟Opcache 4 opcache.enable=1 5 //cli環境下啟用Opcache 6 opcache.enable_cli=1 7 //浪費記憶體的上限,以百分比計,如果達到該上限,Opcache則會清空並重新生成快取。預設5% 8 opcache.max_wasted_percentage=5 9 //配置共享記憶體儲存大小,單位MB 10 opcache.memory_consumption=128 11 //用來儲存臨時字串的記憶體大小,單位MB。這個配置就是上面說到的Opcache快取的interned_string,它會在第一次使用到interned_string時快取到共享記憶體中,供其他程序後續使用 12 opcache.interned_strings_buffer=8 13 //用於控制共享記憶體最多可以快取多少個檔案,該值最小範圍是200,在php5.5.6版本之後,最大值是1000000 14 opcache.max_accelerated_files=4000 15 //設定快取的過期時間,為0的話則每次都要檢查 16 opcache.revalidate_freq=60 17 //如果啟用,OPcache會在opcache.revalidate_freq設定的秒數去檢測檔案的時間戳(timestamp)檢查指令碼是否更新。如果這個選項被禁用(設定為0),opcache.revalidate_freq會被忽略,PHP檔案永遠不會被檢查。這意味著如果你修改了你的程式碼,然後你把它更新到伺服器上,再在瀏覽器上請求更新的程式碼對應的功能,你會看不到更新的效果 18 opcache.validate_timestamps=0 //所以像我上面說的,在大流量高併發場景下,該項不要啟用,切記 19 //啟用後,可以將依賴Zend引擎的記憶體管理模組一次釋放全部請求變數的記憶體,而不是依次釋放每一個已分配的記憶體塊。 20 opcache.fast_shutdown=1 21 //啟用檔案快取(設定快取路徑),這樣Opcache就可以將Opcode快取到檔案中,實現跨php生命週期快取 22 opcache.file_cache=/tmp
三、總結
合理的使用OPcahce將會減少Web伺服器的CPU使用率,但是會增加一定的記憶體使用率。如果使用得到,這將會大大提高或服務端和PHP的吞吐量。
參考連結:
https://segmentfault.com/a/1190000021718693