【问题标题】:Python Queue will not release the memory after get()Python Queue 在 get() 之后不会释放内存
【发布时间】:2017-12-28 23:24:19
【问题描述】:

关于队列内存,我需要您的帮助。 1)我选择队列作为我的数据结构,因为我有一个线程将数据提供给队列,而另一个线程将获取数据 2)设计为运行数天的两个线程 3)我不想限制队列大小,队列的大小可能真的很长,比如说~10k占用10GB。这可以 4) 问题是当我通过 get() 将 q 大小缩小到只有 20 个项目时,这些项目仅占用约 100MB 的内存。我打印尺寸,我确定只有 20 件。 5)但在系统层面,整个进程仍然占用~10GB

我试着打电话

gc.collect()

就我自己而言,记忆不会改变。所以我的疯狂猜测是 get() 中的那些项目被破坏了。 并且线程一直在运行,python不会减少队列的容量。

我的问题是:有没有办法释放队列暂时不使用的那些内存?我找不到任何 api 来做到这一点。

更新 1

Ubuntu 16.04、python 2.7.12 我今天做了一些实验。我的观察是q大小是空的,但是系统内存占用了大约84M。这是一些重现我的结果的代码。

第一次拍摄:del

import Queue

q = Queue.Queue()
length = 10000000
buffer_size = 1000
index = 0
while index < length:
  q.put_nowait(1)
  index += 1
key = raw_input('finish insert, press key to pop')
while q.qsize() > buffer_size:
  a = q.get()
  del a
print 'after pop, q size = ', q.qsize()
raw_input('let me del the q')
del q
key = raw_input('finish delete')

第二次拍摄:clear()

import Queue

q = Queue.Queue()
length = 10000000
buffer_size = 1000
index = 0
while index < length:
  q.put_nowait(1)
  index += 1
key = raw_input('finish insert, press key to pop')
while q.qsize() > buffer_size:
  a = q.get()
  del a
print 'after pop, q size = ', q.qsize()
raw_input('let me del the q')
with q.mutex:
  q.queue.clear()
print 'q size = ', q.qsize()
key = raw_input('finish delete')

第三次拍摄:Queue()

import Queue

q = Queue.Queue()
length = 10000000
buffer_size = 1000
index = 0
while index < length:
  q.put_nowait(1)
  index += 1
key = raw_input('finish insert, press key to pop')
while q.qsize() > buffer_size:
  a = q.get()
  del a
print 'after pop, q size = ', q.qsize()
raw_input('let me del the q')
q = Queue.Queue()
print 'q size = ', q.qsize()
key = raw_input('finish delete')

第四次拍摄:gc.collect()

import Queue
import gc

q = Queue.Queue()
length = 10000000
buffer_size = 1000
index = 0
while index < length:
  q.put_nowait(1)
  index += 1
key = raw_input('finish insert, press key to pop')
while q.qsize() > buffer_size:
  a = q.get()
  del a
print 'after pop, q size = ', q.qsize()
raw_input('let me del the q')
#del q
#with q.mutex:
#  q.queue.clear()
q = Queue.Queue()
print 'q size = ', q.qsize()
raw_input('let me gc.collect')
gc.collect()
raw_input('how about now?')

这四种方式不会释放队列中的内存。谁能告诉我我做错了什么?非常感谢!

一些想法

似乎python Queue 会保留其生命周期中最大的内存容量,并尝试在没有 malloc 内存的情况下重用内存。以 C++ stl vector 中的数据结构为例。当 (size == capacity) 时将内存加倍,如果 (size / capacity == 0.25) 则将容量减少一半。我预计动态数据结构将具有此功能。 有什么办法可以做到吗?还是python队列就是这样设计的?

【问题讨论】:

  • Python 有一个引用计数垃圾收集器。如果队列中的元素仍在程序中的某处使用,则它们不会被垃圾收集。
  • 你有代码要显示吗?
  • 您好,感谢您的回复!我只是添加一些测试代码。我使用 python 2.7.12 在我的 Ubuntu 16.04 上对其进行了测试。你能看出我在这里做错了吗?
  • 遇到同样的问题。你想好怎么清理内存了吗?
  • 这可能是一种 Numpy 版本问题。 stackoverflow.com/questions/54419043/…

标签: python multithreading memory queue


【解决方案1】:

q.get()之后调用q.task_done()

参考: https://docs.python.org/3/library/queue.html#queue.Queue.task_done

此外,请参阅: https://bugs.python.org/issue43911

【讨论】:

  • 内存问题与task_done无关。我尝试了调用 task_done 和不调用它。内存没有区别。内存在最后被释放。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 2014-11-17
相关资源
最近更新 更多