1. 調整PHP配置文件(php.ini)
修改php.ini是優化PHP內存使用的基礎。關鍵參數包括:
memory_limit:設置單個PHP腳本的最大內存使用量(如memory_limit = 128M),根據應用需求調整(避免設置過高導致內存浪費)。opcache.enable=1(啟用)、opcache.memory_consumption=128(緩存內存大小,單位MB)、opcache.interned_strings_buffer=8(interned字符串緩沖區大?。?、opcache.max_accelerated_files=4000(最大加速文件數,根據項目文件數量調整)。memory_limit設為64M,大型應用設為256M。2. 優化PHP代碼邏輯
代碼層面的優化能直接減少內存占用:
unset()函數銷毀不再需要的變量(如大數組、數據庫連接對象),釋放內存。例如:$largeArray = range(1, 1000000); unset($largeArray);。yield)以迭代方式處理數據,避免一次性加載全部數據到內存(如處理大型CSV文件時,用yield逐行讀?。?。for ($i = 0; $i < count($array); $i++)改為$count = count($array); for ($i = 0; $i < $count; $i++)),減少內存分配次數。3. 啟用并配置OPcache
OPcache是PHP官方推薦的字節碼緩存擴展,能顯著減少內存使用:
sudo apt install php-opcache安裝,然后在php.ini中添加zend_extension=opcache.so并啟用(opcache.enable=1)。opcache.memory_consumption(如128M),設置opcache.max_accelerated_files為項目中PHP文件的總數(可通過find /path/to/project -name "*.php" | wc -l統計),避免緩存過多無用文件。4. 使用外部緩存系統
對于頻繁訪問但不常變化的數據(如數據庫查詢結果、會話數據),使用Redis或Memcached等外部緩存系統,減少PHP腳本的內存占用:
sudo apt install redis-server)和PHP Redis擴展(sudo apt install php-redis),在代碼中連接Redis并存儲數據:$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$data = $redis->get('cached_data'); // 嘗試從緩存獲取
if (!$data) {
$data = fetchDataFromDatabase(); // 若緩存無數據,從數據庫獲取
$redis->set('cached_data', $data, 3600); // 存入緩存,有效期1小時
}
這樣可避免每次請求都從數據庫加載大量數據,降低PHP內存壓力。5. 調整PHP-FPM配置(若使用FPM)
PHP-FPM(FastCGI進程管理器)的配置直接影響內存使用:
/etc/php/{version}/fpm/pool.d/www.conf({version}為PHP版本,如8.1),優化以下參數:
pm.max_children:設置最大子進程數(如pm.max_children = 20),根據服務器內存計算(每個子進程約占用memory_limit的1/4至1/2,如memory_limit=128M,則pm.max_children不宜超過50)。pm.start_servers:啟動時的子進程數(如pm.start_servers = 5)。pm.min_spare_servers/pm.max_spare_servers:空閑子進程的最小/最大數量(如pm.min_spare_servers = 5,pm.max_spare_servers = 10)。6. 監控與分析內存使用
通過工具監控內存使用,定位瓶頸:
memory_get_usage()(當前內存使用量)和memory_get_peak_usage()(峰值內存使用量)輸出到日志,分析腳本內存消耗情況。sudo apt install php-xdebug),在php.ini中啟用內存分析(xdebug.profiler_enable=1,xdebug.profiler_output_dir=/tmp),生成內存使用報告,識別高內存消耗的代碼段。7. 修復內存泄漏
內存泄漏會導致內存持續增長,需通過以下方式修復:
WeakReference)打破循環引用(如對象A引用對象B,對象B引用對象A),避免垃圾回收器無法回收。$db = null、fclose($file))。gc_collect_cycles()強制進行垃圾回收,釋放未使用的內存(如循環結束后調用)。__destruct())中釋放資源(如關閉數據庫連接),確保資源被正確回收。8. 系統級優化
sudo fallocate -l 2G /swapfile,sudo chmod 600 /swapfile,sudo mkswap /swapfile,sudo swapon /swapfile),緩解物理內存壓力,但需注意Swap會降低性能,僅作為臨時解決方案。sudo systemctl restart php{version}-fpm)或Apache(sudo systemctl restart apache2),釋放累積的內存碎片。