Как я могу профилировать память о многопоточной программе в Python?

StackOverflow https://stackoverflow.com/questions/4799166

Вопрос

Есть ли способ профилировать память о многопоточной программе в Python?

Для профилирования процессора я использую Cprofile для создания отдельных статистических данных для профилировщика для каждой потока, а затем объединяю их. Тем не менее, я не мог найти способ сделать это с профилировщиками памяти. Я использую Heypy.

Есть ли способ объединить статистику в Heypy, как Cprofile? Или какие еще профилировщики памяти вы бы предположили, что это больше подходит для этой задачи.

Связанный вопрос был задан для профилирования использования ЦП в программе многопоточного. Как я могу профилировать многопоточную программу в Python?

Также еще один вопрос, касающийся профилировщика памяти: Python Memory Profiler

Это было полезно?

Решение

Если вы рады профилировать объекты, а не сырую память, вы можете использовать gc.get_objects() Функция, так что вам не нужно пользовательское Metaclass. В более поздних версиях Python, sys.getsizeof() Также позволит вам сделать снимок, чтобы выяснить, сколько основной память используется этими объектами.

Другие советы

Есть способы получить Valgrind для профиля памяти программ Python: http://www.python.org/dev/faq/#can-i-run-valgrind-against-python

Ok. То, что я точно искал, кажется, не существует. Итак, я нашел решение-обходной путь для этой проблемы.

Вместо профилирования памяти я профилю объекты. Таким образом, я смогу увидеть, сколько объектов существует в определенное время в программе. Чтобы достичь своей цели, я использовал MetaClasses с минимальной изменением к уже существующему коду.

Следующий Metaclass добавляет очень простую подпрограмму к __init__ а также __del__ функции класса. Подпрограмма для __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

Фиктивная функция - просто очень простой обходной путь. Я уверен, что есть гораздо лучшие способы сделать это.

Наконец, всякий раз, когда вы хотите увидеть количество существующих объектов, вам просто нужно посмотреть на счетчик Страдец. Пример;

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

Я надеюсь, это поможет вам. Этого было достаточно для моего дела.

Я использовал Яппи, с которым я добился успеха для нескольких специальных многопоточных случаев. У него отличная документация, так что у вас не должно быть слишком больших проблем с настройкой.

Для специфического профилирования памяти, проверьте Куча. Анкет Будьте осторожны, это может создать некоторые из крупнейших файлов журналов, которые вы когда -либо видели!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top