9

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

对于 CPU 分析,我使用 cProfile 为每个线程创建单独的分析器统计信息,然后将它们组合起来。但是,我找不到使用内存分析器执行此操作的方法。我正在使用大量。

有没有办法像cProfile一样将统计数据组合在一起?或者您会建议哪些其他内存分析器更适合此任务。

有人问了一个相关的问题来分析多线程程序的 CPU 使用情况:如何在 Python 中分析多线程程序?

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

4

4 回答 4

8

如果您乐于分析对象而不是原始内存,则可以使用该gc.get_objects()函数,这样您就不需要自定义元类。在最近的 Python 版本中,sys.getsizeof()还可以让您了解这些对象使用了多少底层内存。

于 2011-02-14T02:00:22.220 回答
3

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

于 2011-02-07T05:12:13.187 回答
1

行。我正在寻找的东西似乎并不存在。所以,我找到了一个解决方案——一个解决这个问题的方法。

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

下面的元类为该类添加了一个非常简单的子例程__init____del__函数。for 子例程__init__将具有该类名称的对象的数量增加一并__del__减少一。

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 函数使用它们存在的模块的全局变量。

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 只是一个非常简单的解决方法。我相信有更好的方法来做到这一点。

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

>>> 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}

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

于 2011-02-13T23:36:12.833 回答
-1

我使用了Yappi,在一些特殊的多线程案例中我已经成功了。它有很好的文档,所以你不应该在设置它时遇到太多麻烦。

For memory specific profiling, check out Heapy. Be warned, it may create some of the largest log files you've ever seen!

于 2011-02-18T17:31:46.760 回答