【问题标题】:Python memory consumption on Linux: physical and virtual memory are growing while the heap size remains the sameLinux 上的 Python 内存消耗:物理内存和虚拟内存都在增长,而堆大小保持不变
【发布时间】:2014-06-15 16:51:27
【问题描述】:

我正在开发一种用 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%。

UPD:到目前为止,该过程已经运行了将近 15 个小时。堆还是一样,但是物理内存增加了六倍,虚拟内存增加了 50%。除了凌晨 3:00 的奇怪异常值外,曲线似乎是线性的:

时间对象堆 PhM 虚拟机

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)

【问题讨论】:

  • 当您运行几个小时而不是 20 分钟时,图表的外观如何?
  • 哦,可能相关:stackoverflow.com/q/1194416/691859
  • @2rs2ts,进程工作了一夜,内存还在增长。
  • 好的,这讲述了一个与几分钟不同的故事,所以感谢您衡量和分享。无论如何,我不确定这是否适用,但我在程序员身上看到了this question(它现在已迁移到 SO)关于一个简单的“Hello World”java 程序中的虚拟内存使用情况。保持一致的堆大小告诉我您不必担心,但物理内存增加的担忧却不然。希望其他人能给出明确的答案。
  • 也许堆栈正在稳步增加而您不知道? (我不确定这个问题是否适用于这种情况,但是......)您可以使用this example 查看堆栈,所以也许您可以记录格式化堆栈中的行数并查看它是否增长。

标签: python linux memory-consumption


【解决方案1】:

在不知道您的程序在做什么的情况下,这可能会有所帮助。

不久前我在做一个项目时偶然发现了这篇文章: http://chase-seibert.github.io/blog/2013/08/03/diagnosing-memory-leaks-python.html 其中说,“在运行时消耗大量内存的长时间运行的 Python 作业在进程实际终止之前可能不会将该内存返回给操作系统,即使所有内容都已正确收集垃圾。”

我最终使用多处理模块让我的项目派生出一个单独的进程并在需要工作时返回,此后我没有注意到任何内存问题。

或者在 Python 3.3 中尝试一下 http://bugs.python.org/issue11849

【讨论】:

  • 不幸的是,我正在使用的库(auparse - 在 Linux 中与 auditd 一起使用)仍未移植到第三个分支。
猜你喜欢
  • 2018-07-27
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
相关资源
最近更新 更多