首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Python中分析多线程程序的内存?

如何在Python中分析多线程程序的内存?
EN

Stack Overflow用户
提问于 2011-01-26 05:41:01
回答 4查看 3.5K关注 0票数 9

在Python中有没有办法分析多线程程序的内存?

对于CPU profiler,我使用cProfile为每个线程创建单独的profiler统计信息,并在以后合并它们。然而,我找不到一种使用内存分析器来做到这一点的方法。我正在使用heapy。

有没有一种方法可以像cProfile一样在heapy中组合统计数据?或者您建议的其他内存分析器更适合这项任务。

在多线程程序上分析CPU使用率时,提出了一个相关问题:How can I profile a multithread program in Python?

还有一个关于内存分析器的问题:Python memory profiler

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-14 10:00:22

如果您希望分析对象而不是原始内存,那么可以使用gc.get_objects()函数,这样就不需要自定义元类了。在较新的Python版本中,sys.getsizeof()还可以让您尝试计算出这些对象使用了多少底层内存。

票数 8
EN

Stack Overflow用户

发布于 2011-02-07 13:12:13

有几种方法可以让valgrind分析python程序的内存:http://www.python.org/dev/faq/#can-i-run-valgrind-against-python

票数 3
EN

Stack Overflow用户

发布于 2011-02-14 07:36:13

好的。我所寻找的似乎并不存在。所以,我找到了一个解决方案--这个问题的变通方法。

我将分析对象,而不是分析内存。这样,我就能看到程序中某个特定时间有多少对象存在。为了实现我的目标,我使用了元类,只需对现有代码进行最小程度的修改。

下面的元类将一个非常简单的子例程添加到该类的__init____del__函数中。__init__的子例程将具有该类名的对象的数量增加1,而__del__减少1。

代码语言:javascript
复制
class ObjectProfilerMeta(type):
    #Just set metaclass of a class to ObjectProfilerMeta to profile object
    def __new__(cls, name, bases, attrs):
        if name.startswith('None'):
            return None

        if "__init__" in attrs:
            attrs["__init__"]=incAndCall(name,attrs["__init__"])
        else:
            attrs["__init__"]=incAndCall(name,dummyFunction)

        if "__del__" in attrs:
            attrs["__del__"]=decAndCall(name,attrs["__del__"])
        else:
            attrs["__del__"]=decAndCall(name,dummyFunction)

        return super(ObjectProfilerMeta, cls).__new__(cls, name, bases, attrs)

    def __init__(self, name, bases, attrs):
        super(ObjectProfilerMeta, self).__init__(name, bases, attrs)


    def __add__(self, other):
        class AutoClass(self, other):
            pass
        return AutoClass

incAndCall和decAndCall函数使用它们所在模块的全局变量。

代码语言:javascript
复制
counter={}
def incAndCall(name,func):
    if name not in counter:
        counter[name]=0

    def f(*args,**kwargs):
        counter[name]+=1
        func(*args,**kwargs)

    return f

def decAndCall(name,func):
    if name not in counter:
        counter[name]=0

    def f(*args,**kwargs):
        counter[name]-=1
        func(*args,**kwargs)

    return f

def dummyFunction(*args,**kwargs):
    pass

dummyFunction只是一个非常简单的变通方法。我相信有更好的方法去做。

最后,每当您想要查看存在的对象的数量时,您只需查看计数器字典。一个例子;

代码语言:javascript
复制
>>> class A:
    __metaclass__=ObjectProfilerMeta
    def __init__(self):
        pass


>>> class B:
    __metaclass__=ObjectProfilerMeta


>>> l=[]
>>> for i in range(117):
    l.append(A())


>>> for i in range(18):
    l.append(B())


>>> counter
{'A': 117, 'B': 18}
>>> l.pop(15)
<__main__.A object at 0x01210CB0>
>>> counter
{'A': 116, 'B': 18}
>>> l=[]
>>> counter
{'A': 0, 'B': 0}

我希望这对你有帮助。这对我的情况来说已经足够了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4799166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档