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

Ubuntu环境下Python脚本意外内存耗尽问题排查与解决咨询

Python脚本被OOM Killer终止的问题排查与解决方案

问题背景

Python脚本运行时被标记为Killed,dmesg输出如下错误:

[Sat Dec  3 11:25:59 2022] Out of memory: Killed process 1126 (python) total-vm:17534768kB, anon-rss:14299092kB, file-rss:2752kB, shmem-rss:0kB, UID:1000 pgtables:28200kB oom_score_adj:0

脚本是长时间运行的任务(需数小时),同时运行两个实例,在虚拟环境中通过tmux执行。核心逻辑是读取最大约2GB的CSV文件到内存,用pandas拆分后输出小文件,代码模式如下:

for os.walk:
  df = read_csv()
  smaller_dfs = df.groupby
  for small_df in smaller_dfs:
    small_df.to_csv()

原本认为每次循环后上一个CSV的数据会被释放,但虚拟机有16GB内存,执行期间top显示总内存占用仅2-3GB,buff/cache占7-8GB,突然内存耗尽超出预期。

dmesg输出的进程表中两个Python进程:

[Sat Dec  3 11:25:59 2022] [  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name
[Sat Dec  3 11:25:59 2022] [    184]     0   184    17344      979   147456        0          -250 systemd-journal
[Sat Dec  3 11:25:59 2022] [    217]     0   217     5054      988    65536        0         -1000 systemd-udevd
[Sat Dec  3 11:25:59 2022] [    342]     0   342    70036     4488    90112        0         -1000 multipathd
[Sat Dec  3 11:25:59 2022] [    413]   102   413    22665      554    77824        0             0 systemd-timesyn
[Sat Dec  3 11:25:59 2022] [    484]   100   484     6850      921    77824        0             0 systemd-network
[Sat Dec  3 11:25:59 2022] [    487]   101   487     6136     1444    94208        0             0 systemd-resolve
[Sat Dec  3 11:25:59 2022] [    522]     0   522    60290      929   102400        0             0 accounts-daemon
[Sat Dec  3 11:25:59 2022] [    523]     0   523      637      183    49152        0             0 acpid
[Sat Dec  3 11:25:59 2022] [    527]     0   527     2137      567    53248        0             0 cron
[Sat Dec  3 11:25:59 2022] [    529]   103   529     1894      915    49152        0          -900 dbus-daemon
[Sat Dec  3 11:25:59 2022] [    538]     0   538    20475      740    61440        0             0 irqbalance
[Sat Dec  3 11:25:59 2022] [    540]     0   540     7407     2833    90112        0             0 networkd-dispat
[Sat Dec  3 11:25:59 2022] [    542]     0   542    59108      902    98304        0             0 polkitd
[Sat Dec  3 11:25:59 2022] [    545]   104   545    56125      958    81920        0             0 rsyslogd
[Sat Dec  3 11:25:59 2022] [    547]     0   547   363271     1292   204800        0             0 amazon-ssm-agen
[Sat Dec  3 11:25:59 2022] [    555]     0   555   274152     4234   290816        0          -900 snapd
[Sat Dec  3 11:25:59 2022] [    557]     0   557     4336      998    69632        0             0 systemd-logind
[Sat Dec  3 11:25:59 2022] [    565]     0   565    98885     1209   135168        0             0 udisksd
[Sat Dec  3 11:25:59 2022] [    566]     0   566      951      560    49152        0             0 atd
[Sat Dec  3 11:25:59 2022] [    599]     0   599    78585      931   106496        0             0 ModemManager
[Sat Dec  3 11:25:59 2022] [    606]     0   606     1840      436    53248        0             0 agetty
[Sat Dec  3 11:25:59 2022] [    611]     0   611    13313      362    94208        0             0 nginx
[Sat Dec  3 11:25:59 2022] [    613]    33   613    13454      821    94208        0             0 nginx
[Sat Dec  3 11:25:59 2022] [    614]    33   614    13454      821    94208        0             0 nginx
[Sat Dec  3 11:25:59 2022] [    628]     0   628     1459      362    53248        0             0 agetty
[Sat Dec  3 11:25:59 2022] [    657]     0   657    27034     2733   114688        0             0 unattended-upgr
[Sat Dec  3 11:25:59 2022] [    750]     0   750     3046      938    61440        0         -1000 sshd
[Sat Dec  3 11:25:59 2022] [    780]     0   780     3452     1050    73728        0             0 sshd
[Sat Dec  3 11:25:59 2022] [    789]  1000   789     4731     1118    73728        0             0 systemd
[Sat Dec  3 11:25:59 2022] [    793]  1000   793    25976      822    98304        0             0 (sd-pam)
[Sat Dec  3 11:25:59 2022] [    919]  1000   919     3486      809    73728        0             0 sshd
[Sat Dec  3 11:25:59 2022] [    920]  1000   920     2543      976    61440        0             0 bash
[Sat Dec  3 11:25:59 2022] [   1050]     0  1050   365631     1936   225280        0             0 ssm-agent-worke
[Sat Dec  3 11:25:59 2022] [   1074]  1000  1074     2534     1281    65536        0             0 tmux: server
[Sat Dec  3 11:25:59 2022] [   1075]  1000  1075     2565      914    57344        0             0 bash
[Sat Dec  3 11:25:59 2022] [   1105]  1000  1105     2564      967    53248        0             0 bash
[Sat Dec  3 11:25:59 2022] [   1126]  1000  1126  4383692  3575461 28876800        0             0 python
[Sat Dec  3 11:25:59 2022] [   1131]  1000  1131     2752      785    69632        0             0 top
[Sat Dec  3 11:25:59 2022] [   1174]  1000  1174     2757      754    57344        0             0 top
[Sat Dec  3 11:25:59 2022] [   1278]     0  1278     3452     1040    61440        0             0 sshd
[Sat Dec  3 11:25:59 2022] [   1372]  1000  1372     3486      811    61440        0             0 sshd
[Sat Dec  3 11:25:59 2022] [   1373]  1000  1373     1473      564    45056        0             0 sftp-server
[Sat Dec  3 11:25:59 2022] [   1382]  1000  1382     2760      793    61440        0             0 top
[Sat Dec  3 11:25:59 2022] [   1404]  1000  1404     2760      794    65536        0             0 top
[Sat Dec  3 11:25:59 2022] [   1569]  1000  1569   436810   384689  3260416        0             0 python
[Sat Dec  3 11:25:59 2022] [   1578]  1000  1578     2760      817    57344        0             0 top

执行期间free命令输出:

total        used        free      shared  buff/cache   available
Mem:       16240152     6257732     6280208         868     3702212     9695756
Swap:             0           0           0

问题解答

1. 排查步骤

  • 聚焦OOM时刻的真实内存占用:dmesg里的anon-rss:14299092kB显示被杀死的Python进程实际占用了约13.6GB物理内存,这是触发OOM的直接原因。top是采样式监控,脚本处理数据时可能出现瞬间内存峰值(比如groupby操作生成临时数据、大DataFrame的副本),这个峰值没被捕捉到。
  • 持续跟踪Python进程内存变化:用ps aux --sort=-%mem实时监控两个Python进程的内存,或者在脚本里加入内存监控逻辑,比如每次循环前后用psutil库的process.memory_info().rss打印当前内存使用,定位内存飙升的节点。
  • 检查pandas内存泄漏:即使循环逻辑看似释放了数据,pandas的某些操作可能隐式保留引用(比如groupby返回的对象持有原DataFrame引用,或全局变量、闭包意外留存旧数据)。可以在循环末尾手动删除变量并强制GC,观察内存是否下降。
  • 分析buff/cache的可回收性:Linux的buff/cache在内存紧张时会被回收,但如果存在大量不可回收的匿名页,或其他进程竞争内存,可能导致buff/cache无法及时释放触发OOM。用vmstat 1观察内存回收情况,查看si/so列(swap进出)是否异常,或用slabtop检查内核缓存占用。
  • 排查隐性内存占用:检查虚拟环境依赖、tmux会话中的后台进程、系统日志或临时文件导致的内核内存消耗,这些在top中可能不明显,但会占用内存。

2. 脚本中降低OOM概率的操作

  • 手动触发垃圾回收:在每次循环末尾加入import gc; gc.collect(),强制回收不再使用的内存。这会增加少量CPU开销,但能及时释放pandas可能遗留的内存。
  • 优化pandas内存使用:
    • 读取CSV时指定dtype参数,将字符串、整数等类型设为更节省内存的类型(比如用category类型存储重复值多的列,用int32代替int64),降低初始内存占用。
    • 使用pandas.read_csv的chunksize
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 23:55:19