Linux上Python内存消耗:物理和虚拟内存增长而堆大小保持不变

21 投票
1 回答
12274 浏览
提问于 2025-04-18 04:47

我正在开发一个系统服务(其实就是一个日志解析器),用Python写的。这个程序应该能够持续运行很长时间(希望是几天甚至几周,不出故障也不需要重启)。所以我对内存的使用情况很关注。

我把不同网站上关于进程内存使用的信息整理成了一个简单的函数:

#!/usr/bin/env python
from pprint import pprint
from guppy import hpy
from datetime import datetime
import sys
import os
import resource
import re

def debug_memory_leak():
    #Getting virtual memory size 
    pid = os.getpid()
    with open(os.path.join("/proc", str(pid), "status")) as f:
        lines = f.readlines()
    _vmsize = [l for l in lines if l.startswith("VmSize")][0]
    vmsize = int(_vmsize.split()[1])

    #Getting physical memory size  
    pmsize = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss

    #Analyzing the dynamical memory segment - total number of objects in memory and heap size
    h = hpy().heap()
    if __debug__:
        print str(h)
    m = re.match(
        "Partition of a set of ([0-9]+) objects. Total size = ([0-9]+) bytes(.*)", str(h))
    objects = m.group(1)
    heap = int(m.group(2))/1024 #to Kb

    current_time = datetime.now().strftime("%H:%M:%S")
    data = (current_time, objects, heap, pmsize, vmsize)
    print("\t".join([str(d) for d in data]))

这个函数用来研究我这个长时间运行的程序的内存使用情况,但我还是无法解释它的表现。你可以看到,在这二十分钟内,堆的大小和对象的总数没有变化,而物理内存和虚拟内存分别增加了11%和1%。

更新:到目前为止,这个进程已经运行了将近15个小时。堆的大小还是没变,但物理内存增加了六倍,虚拟内存增加了50%。除了凌晨3点的几个奇怪的异常值外,其他的变化看起来是线性的:

时间 对象数 堆大小 物理内存 虚拟内存

19:04:19 31424 3928 5460 143732

19:04:29 30582 3704 10276 158240

19:04:39 30582 3704 10372 157772

19:04:50 30582 3709 10372 157772

19:05:00 30582 3704 10372 157772

(...)

19:25:00 30583 3704 11524 159900

09:53:23 30581 3704 62380 210756

我想知道我的进程的地址空间发生了什么。堆的大小保持不变,这说明所有动态对象都被正确释放了。但我毫不怀疑,内存使用量的增加会影响这个关键进程的稳定性。

在这里输入图片描述

有人能帮我解释一下这个问题吗?谢谢。

(我使用的是RHEL 6.4,内核版本2.6.32-358,Python版本2.6.6)

1 个回答

8

不知道你的程序具体在做什么,但这可能对你有帮助。

我在之前做项目的时候看到过一篇文章:http://chase-seibert.github.io/blog/2013/08/03/diagnosing-memory-leaks-python.html。文章提到,“长时间运行的Python程序如果消耗了很多内存,可能在程序结束之前不会把这些内存还给操作系统,即使所有的垃圾都已经被清理掉了。”

我最后使用了多进程模块,让我的项目分叉出一个单独的进程来处理需要做的工作,自那以后我就没注意到内存方面的问题了。

你也可以试试Python 3.3,详细信息可以查看这个链接:http://bugs.python.org/issue11849

撰写回答