You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu环境下PHP服务脚本真实内存占用持续增长问题求助

Ubuntu环境下PHP服务脚本真实内存占用持续增长问题求助

你好,针对你遇到的PHP无限循环脚本真实内存持续增长的问题,我来帮你分析下可能的原因和可行的排查解决方向:

先明确两个内存统计参数的差异

首先得搞清楚get_memory_usage()两个参数的核心区别,这能帮你快速定位问题根源:

  • get_memory_usage(false):仅统计PHP自身用户态分配的内存,这个值稳定说明你的业务代码里没有明显的PHP变量级内存泄漏(比如未释放的变量、循环引用未被GC处理)
  • get_memory_usage(true):统计PHP进程从操作系统实际申请的物理内存(包含PHP内核缓存、扩展占用的内存等),这个值持续增长,问题大概率出在底层资源未释放或操作系统内存分配机制上

可能的原因分析

  1. 外部资源未彻底释放:你脚本里涉及MySQL存储、外部检查(大概率是HTTP请求),这些操作依赖的底层资源如果没正确回收,会导致操作系统层面的内存占用累积。比如:
    • 每次循环新建MySQL连接但未用mysqli_close()/PDO::null销毁
    • curl请求后未调用curl_close()释放句柄
    • 文件操作后未用fclose()关闭文件描述符
  2. 操作系统内存缓存机制:Linux会把空闲内存用作缓存,PHP进程申请的内存如果没有主动归还,系统可能会暂时保留在进程地址空间,不过如果内存涨到1GB,肯定不是单纯的缓存问题
  3. 非PHP原生资源未被GC处理:PHP的垃圾回收只针对自身的对象和变量,像第三方扩展的资源、底层系统句柄这类不在GC范围内,需要手动释放;你调用了gc_collect_cycles()但没效果,大概率是这类资源的问题

具体排查与解决步骤

1. 强制清理循环内的所有资源

在循环迭代结束后,手动释放所有临时变量和外部资源,示例代码调整如下:

function execute(&$loop, $rep_server){
    foreach($rep_server->objetos as $server){
        $dates = ...; // 你的业务逻辑代码
        // 执行外部检查、MySQL存储等操作后
        // 手动释放当前循环内的临时变量
        unset($dates);
        unset($server);
        
        // 如果用到了curl/MySQL连接,在这里显式关闭
        // 比如 curl_close($ch); 或者 mysqli_close($conn);
    }
    // 清理循环引用并触发GC
    unset($rep_server);
    gc_collect_cycles();
}

2. 用系统工具定位内存增长区域

  • 用pmap查看进程的内存映射详情:
    pmap -x <你的PHP进程PID>
    
    观察输出里的内存区域大小变化,能快速定位是堆内存、共享库还是缓存区在持续增长
  • 用htop的F2设置里开启SHOW MEMORY PERCENTAGE和SHOW PROCESS TREE,更直观地跟踪进程内存变化

3. 排查PHP扩展与配置

  • 暂时禁用所有非必要的第三方扩展(比如监控、调试类扩展),重启脚本后看内存是否还增长,排查是否是扩展存在内存泄漏
  • 调整PHP内存相关配置:
    • 确认zend.enable_gc = On(php.ini中)
    • 减小realpath_cache_size(默认可能较大,长期运行会累积缓存)
    • 对于PHP 7+,可以尝试调整zend.memory_limit限制内核内存分配

4. 兜底方案:定时重启脚本

如果以上方法都无法彻底解决,可以用supervisor管理你的PHP服务,配置脚本运行一定时间后自动重启,避免内存持续涨到1GB影响系统稳定性。比如在supervisor配置里添加:

[program:php-monitor-script]
command=/usr/bin/php /path/to/your/script.php
autostart=true
autorestart=true
startretries=3
user=www-data
stdout_logfile=/var/log/php-monitor.log
stderr_logfile=/var/log/php-monitor.err.log
stopwaitsecs=10
; 每24小时重启一次
startsecs=86400

备注:内容来源于stack exchange,提问作者Vitor Lins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 14:28:11