跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 一个 Python GC 问题,虽然被解决了,但是还是不懂为什么
未分類
14 4 月 2020

一个 Python GC 问题,虽然被解决了,但是还是不懂为什么

一个 Python GC 问题,虽然被解决了,但是还是不懂为什么

資深大佬 : aladdindingding 22

就是我们有一个 redis 的公共文件自定义了一个方法使用了 pipline,举个例子: 比如这个是一次从一个 list 一次 pop 出多个元素

def lpopn(self, name, n):  """一次 pop 多个元素"""     pipe = self.pipeline()     pipe.lrange(name, 0, n - 1)     pipe.ltrim(name, n, -1)     raw_list, is_succ = pipe.execute()     return raw_list 

之前写了一个脚本用来收集 redis 中的数据入库用了这个方法,导致脚本运行时发现了内存泄漏,然后使用内存监控工具定位到了是这个 redis.client.Pipeline 这个对象占用了大量内存,之前记得有 python 的坑说的是 如果在循环引用中的对象定义了 del,那么 python gc 不能进行回收,然后我就点进 pipeline 里面看确实是定义了 del

class Pipeline(BasePipeline, Redis):     "Pipeline for the Redis class"     pass      class BasePipeline(object):   # 省略了其他方法     def __del__(self):         try:             self.reset()         except Exception:             pass 

然后我就改成 脚本里面全局创建一个 pipline 对象传进这个方法,然后问题就解决了,但是不明白这个 pipeline 怎么就循环引用了呢,不知道是不是这个原因,希望有 v 友能解答一下疑惑,给点思路

大佬有話說 (4)

  • 資深大佬 : linw1995

    应该是执行 self.reset() 给 pipeline 带来新的引用?导致回收不了

  • 主 資深大佬 : aladdindingding

    @linw1995 reset()应该是重置 redis 事务一些参数的 应该没有带来新的引用吧

  • 資深大佬 : xiaolinjia

    我看他定义了 enter 和 exit 魔法方法。不如试试
    with self.pipeline() as pipe: ?
    不过我看他代码是一样的,大概是 del 的时候出异常了?导致 reset 没执行?

  • 資深大佬 : linw1995

    @aladdindingding 你发的代码又不全。建议用 tracemalloc 看看是不是 redis.client.Pipeline, 再用 objgraph 看看又没有被生存周期长的对象引用到。没有就应该是被 `__del__` 给复活了。https://www.python.org/dev/peps/pep-0442/

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具