【问题标题】:Python: CTypes memory leak with StructurePython:具有结构的 CTypes 内存泄漏
【发布时间】:2011-11-19 03:19:55
【问题描述】:

Python ctypes 是否存在已知的内存泄漏?我正在使用ctypes 编写具有以下sn-p 代码的Python 脚本,由于某种原因导致内存泄漏。本例中的“while True”是为了测试调用函数引起的泄漏。它正在使用 Python 2.5.4 在 Windows 上运行:

import ctypes
def hi():
    class c1(ctypes.Structure):
            _fields_=[('f1',ctypes.c_uint8)]
    class c2(ctypes.Structure):
            _fields_=[('g1',c1*2)]

while True:
    test=hi()

可以使用 ProcessExplorer 测试泄漏——因为它不断循环,Python 不断占用越来越多的内存。似乎需要有两个 Structure 子类,其中一个类具有另一个类的“倍数”(使用* 运算符),但我不确定条件是否比这更基本。即使在循环中添加了del test,它仍然会泄漏内存。

有什么可能导致这种情况的想法吗?

编辑:因为有人建议它可能还没有进行垃圾收集,所以这里有一个编辑后的版本,它会进行垃圾收集但似乎仍然会泄漏内存:

import gc
import ctypes
def hi():
    class c1(ctypes.Structure):
            _fields_=[('f1',ctypes.c_uint8)]
    class c2(ctypes.Structure):
            _fields_=[('g1',c1*2)]

while True:
    test=hi()
    test2=gc.collect()

【问题讨论】:

  • 泄漏了多少?它为每个 c1 创建一个字节吗?有一个计数器,每 50,000 次调用 hi() 就会打印一次,这样你就知道了。
  • 在 ProcessExplorer 中,“工作集”内存以每秒大约 20-30 KB 的速度稳步增长,并且每隔一段时间,“私有字节”就会赶上这一速度。大约 12 分钟后,我的内存已经超过 59 MB,并且正在计算在解释器中运行的第二个 sn-p。如何在代码中放置一个计数器,告诉您正在占用多少内存?其他人可以证实我的这一点吗?
  • 最简单的方法是在顶部添加from itertools import count,然后将while True: 更改为for c in count():,然后在循环中添加if not c % 50000: print c。然后,如果 prints 太频繁或太少而无用,则增加或减少 50000
  • 我添加了一个错误跟踪器案例;这是交叉引用:bugs.python.org/issue12998
  • 从对该案例的回复中可以看出,这不是泄漏。您真的不应该尝试将进程资源管理器用作泄漏检测工具。

标签: python memory-leaks ctypes


【解决方案1】:

这不是内存泄漏,这只是意味着垃圾收集器尚未运行。即使垃圾收集器确实运行了,也很有可能会发生某种内存池。

ProcessExplorer 不是一个好的调试工具,尤其是内存方面。

【讨论】:

  • 即使我在开头添加“import gc”并在循环内添加“test2=gc.collect()”,它占用的内存仍然在不断增长。 “内存池”是什么意思?内存不应该在某个时候被释放吗?
  • 内存池意味着留出一个区域(在 python 中),其中包含可用内存。这是一种优化技术。它只是看起来正在使用内存。
【解决方案2】:

脚本本身不会泄漏。使用gc.set_debug(gc.DEBUG_LEAK) 运行表明创建的结构类型是可回收的,而gc.garbage 在每次循环迭代中都保持为空,因此没有不可回收的对象。在 Linux 系统上使用 time 运行脚本也不会显示内存消耗的稳定增加。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-10
    • 2016-03-28
    • 2015-03-24
    • 2011-10-04
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多