草庐IT

python - 莫名其妙的非对象python内存泄漏

coder 2023-08-18 原文

我有一个在 uwsgi 下运行的 django 网络服务器,它似乎会泄漏内存。

具体来说,进程的 RSS 缓慢增长,直到最终我不得不重新启动它。

我知道其他与此类似的问题,但是到目前为止找到的所有解决方案/结论似乎都不适用于(我能找到的)这种情况。

到目前为止,我已经使用了meliae , Heapy , pymplerobjgraph检查 python 堆,它们都报告相同的事情:一个看起来正常的堆使用大约 40MB 的内存(预期),随着时间的推移变化很小(根据需要)。

不幸的是,这与进程 RSS 完全不一致,RSS 将愉快地增长到 400MB+,没有反射(reflect)在 python 堆大小中。

一些示例输出来说明我的观点 -

Pympler 输出比较 python 堆/对象内存与进程 RSS:

Memory snapshot:
                                        types |   # objects |   total size
============================================= | =========== | ============
                                         dict |       20868 |     19852512
                                          str |      118598 |     11735239
                                      unicode |       19038 |     10200248
                                        tuple |       58718 |      5032528
                                         type |        1903 |      1720312
                                         code |       13225 |      1587000
                                         list |       11393 |      1289704
                            datetime.datetime |        6953 |       333744
                                          int |       12615 |       302760
  <class 'django.utils.safestring.SafeUnicode |          18 |       258844
                                      weakref |        2908 |       255904
     <class 'django.db.models.base.ModelState |        3172 |       203008
                   builtin_function_or_method |        2612 |       188064
                       function (__wrapper__) |        1469 |       176280
                                         cell |        2997 |       167832
                            getset_descriptor |        2106 |       151632
                           wrapper_descriptor |        1831 |       146480
                                          set |         226 |       143056
                                      StgDict |         217 |       138328
---------------------------
Total object memory: 56189 kB
Total process usage:
 - Peak virtual memory size: 549016 kB
 - Virtual memory size: 549012 kB
 - Locked memory size: 0 kB
 - Peak resident set size: 258876 kB
 - Resident set size: 258868 kB
 - Size of data segment: 243124 kB
 - Size of stack segment: 324 kB
 - Size of code segment: 396 kB
 - Shared library code size: 57576 kB
 - Page table entries size: 1028 kB
---------------------------

Heapy 输出显示类似的东西

Memory snapshot:
Partition of a set of 289509 objects. Total size = 44189136 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0 128384  44 12557528  28  12557528  28 str
     1  61545  21  5238528  12  17796056  40 tuple
     2   5947   2  3455896   8  21251952  48 unicode
     3   3618   1  3033264   7  24285216  55 dict (no owner)
     4    990   0  2570448   6  26855664  61 dict of module
     5   2165   1  1951496   4  28807160  65 type
     6  16067   6  1928040   4  30735200  70 function
     7   2163   1  1764168   4  32499368  74 dict of type
     8  14290   5  1714800   4  34214168  77 types.CodeType
     9  10294   4  1542960   3  35757128  81 list
<1046 more rows. Type e.g. '_.more' to view.>
---------------------------
Total process usage:
 - Peak virtual memory size: 503132 kB
 - Virtual memory size: 503128 kB
 - Locked memory size: 0 kB
 - Peak resident set size: 208580 kB
 - Resident set size: 208576 kB
 - Size of data segment: 192668 kB
 - Size of stack segment: 324 kB
 - Size of code segment: 396 kB
 - Shared library code size: 57740 kB
 - Page table entries size: 940 kB
---------------------------

请注意,在这两种情况下,报告的堆大小为 40-50MB,而进程 RSS 为 200MB+。

我还使用了 objgraph 的 get_leaking_objects() 来尝试查看 C 扩展是否正在执行错误的引用计数,但是不可 gc'able 对象的数量并没有随着时间的推移显着增加.

有没有人知道如何调试它?在这一点上,我假设是以下两种情况之一:

  • 我有一个 C 扩展在内部泄漏内存
  • uwsgi 本身正在泄漏内存(尽管我在网上找不到其他证据)

可能值得一提的是,我在任何类型的开发环境中都没有成功复制它(尽管我可能只是没有给他们带来足够的流量)。

我们确实使用了一堆具有 C 扩展的模块(simplejson、hiredis 等),因此绝对相信它们可能是原因。

寻找可用于追踪此问题的方法。

最佳答案

您使用的是什么版本的 Python?在 Python 2.4 中,内存分配器不会将内存返回给操作系统。

仍然在较新的版本中,您会看到一个问题,该问题要么与保存已释放简单类型列表的 Python 内存分配器相关,要么如果您在 Linux 上运行,则存在 glibc 的 malloc 实现如何从操作系统分配内存的固有问题。看看http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htmhttp://pushingtheweb.com/2010/06/python-and-tcmalloc/ .

关于python - 莫名其妙的非对象python内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14230734/

有关python - 莫名其妙的非对象python内存泄漏的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  5. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  6. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  7. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  8. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  9. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  10. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

随机推荐