LINUX.ORG.RU

Найти где течет память в пистоне

 ,


1

4

Сабж. Кто-нибудь знает нормальный метод это сделать?

Есть скрипт, у которого ну прям очень явно течет память. При этом gc debug рапортует что усе собирается, а tracemalloc вообще считает что скрипт больше 10 метров не ест.

Память течет только под нагрузкой в проде, на локальной машине и тестовом стенде все чисто.

Пока думаю попробовать снять дамп через haystack посмотреть чем эта зараза сожрала полтора гига

upd: залез gdb, говорит 20 метров. система говорит 400. wtf?

★★★★★

Последнее исправление: upcFrost (всего исправлений: 2)

Возможно течет не Питон, а операционная система. Утечки это не про Питон, а скорее Си или С++ …

Владимир

anonymous
()
Ответ на: комментарий от anonymous

есть еще полсотни сервисов с на 99% аналогичными образами. Течет только этот. Там минимальный дебиан и пистон, больше нет нифига, три процесса, из которых один - entrypoint, а другой - хелсчек (тоже типовый, нигде не течет)

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от upcFrost

Там минимальный дебиан

Вот то-то и оно …

Владимир

anonymous
()
Ответ на: комментарий от upcFrost

так это скорее всего не течет, а gc не может собрать какую-то срань которую ты генерируешь и которую скорее всего хранишь глобально. надо смотреть что занимает сколько место в памяти, но я хз как это в питоне делать.

не владимир

anonymous
()

Если его можно перезапускать (ну в смысле это веб), то проще перезапускать чем искать проблемы.

x3al ★★★★★
()
Ответ на: комментарий от anonymous

надо смотреть что занимает сколько место в памяти

вот я потому и написал что tracemalloc нифига не видит. Глобальный зашквар там бы отразился

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от x3al

Если его можно перезапускать (ну в смысле это веб), то проще перезапускать чем искать проблемы.

x3al ★★★★★

Избранные теги: безопасность, решето

почему я не удивлен?

anonymous
()
Ответ на: комментарий от x3al

valgrind

под продовую нагрузку, да еще и внутри сварма? чет мне сцыкотно

upcFrost ★★★★★
() автор топика

Нормального способа не знаю

Всё, что пробовал изнутри питона, говорило «всё ок, ничего не течёт, объекты не накапливаются». А RSS нагло полз вверх почти линейно

Обратил внимание, что много (порядка мегабайта) возвращал через return. Стал возвращать по частям, заменив return на yield, утечки пропали

router ★★★★★
()
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от router

Обратил внимание, что много (порядка мегабайта) возвращал через return

можно попробовать. в целом там есть куски, возвращающие довольно жЫрно, но на метр там точно не набежит.

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от upcFrost

Что пробовал (но не помогло) :

from pympler.process import ProcessMemoryInfo
from resource import getrusage, RUSAGE_SELF

....
    def memdebug_init(self):
        self.pmi = ProcessMemoryInfo()

    def memdebug_tick(self):
        self.pmi.update()
        usage = getrusage(RUSAGE_SELF)

        fields_tmpl=','.join(
            [   
                'stack_segment={pmi.stack_segment:d}i',
                'data_segment={pmi.data_segment:d}i',
                'code_segment={pmi.code_segment:d}i',
                'shared_segment={pmi.shared_segment:d}i',
                'vsz={pmi.vsz:d}i',
                'rss={pmi.rss:d}i',

                'ru_utime={ru.ru_utime:f}',
                'ru_stime={ru.ru_stime:f}',
                'ru_maxrss={ru.ru_maxrss:d}i',
                'ru_ixrss={ru.ru_ixrss:d}i',
                'ru_idrss={ru.ru_idrss:d}i',
                'ru_isrss={ru.ru_isrss:d}i',

                'ru_minflt={ru.ru_minflt:d}i',
                'ru_majflt={ru.ru_majflt:d}i',
                'ru_nswap={ru.ru_nswap:d}i',
                'ru_inblock={ru.ru_inblock:d}i',
                'ru_oublock={ru.ru_oublock:d}i',
                'ru_msgsnd={ru.ru_msgsnd:d}i',
                'ru_msgrcv={ru.ru_msgrcv:d}i',
                'ru_nsignals={ru.ru_nsignals:d}i',
                'ru_nvcsw={ru.ru_nvcsw:d}i',
                'ru_nivcsw={ru.ru_nivcsw:d}i',

            ]
        )
        fields_str = fields_tmpl.format(pmi=self.pmi, ru=usage)


router ★★★★★
()

Ну обычно со строками надо быть осторожно. Конкатенация там…

Если прям надо подпереть костылем, то может перезапуск всего этого и ну и ладно.

fornlr ★★★★★
()
Ответ на: комментарий от upcFrost

tracemalloc

Вот он особенно выбесил. Говорил, ничего у тебя не накапливается, всё зашились. И take_snapshot, и statistics

Возможно (только предположение), return шёл через стек и это вне юрисдикции gc

gc.set_debug, haystack-live-dump

Спасибо, посмотрю

router ★★★★★
()
Ответ на: комментарий от anonymous

Утечки это не про Питон

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

X512 ★★★★★
()
Ответ на: комментарий от anonymous

Нашлось уже 2 человека, у которых в питоне течёт память. Но ты продолжай убеждать себя, что всё хорошо

Возможно течет не Питон, а операционная система

В ОСи с ни с чем другим проблем не было

Утечки это не про Питон, а скорее Си или С++ …

Питон написан на Си. Сюрприз

router ★★★★★
()
Ответ на: комментарий от router

Питон написан на Си. Сюрприз

Не сюрприз. Но там реализована сборка мусора. Регистрант выше подтверждает.

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Но там реализована сборка мусора

в Брюсселе она тоже «реализована», но почему-то воняет все время.

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от fornlr

Перезапуск и сейчас есть, просто это немного задрало

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от upcFrost

Но он говорит 1:1 то же, что и остальные - «ничего не течёт»

Но вы все равно продолжаете упорствовать …

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Но вы все равно продолжаете упорствовать

не, лучше рестартить сервис раз в 30 минут, фигня же

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Увы. Если есть другие идеи, с интересом послушаю ;)

router ★★★★★
()

Версия питона, какие зависимости у сервиса?

anonymous
()

говорит 20 метров. система говорит 400. wtf?

Такое бывает при фрагментации памяти. Если сборщик мусора в питоне выполняет не передвигает объекты в памяти, то память со временем может разбухнуть.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Вот чую оно и происходит, при том крайне резко

upcFrost ★★★★★
() автор топика

А оно правда течёт или так надо? Просто я, например, у себя в скрипте специально контролировал потребление памяти, а не в лоб делал, чтобы на проде адекватно работало, а не сразу жрать бесконечно большие файлы и грузить их в память. Т.е. у тебя могут объекты какие-то создаваться, например json-ы грузиться и их количество и размер могут не учитываться. Формально это не утечка памяти, а реально придёт OOM killer и всё позавершает.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

не, там весь хип метров 20-30. Это реально фрагментация похоже, только непонятно где. Вот только что еще в одном модуле нашел аналогичное поведение, продолжу копать

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от peregrine

Во втором есть, там даже есть бомбезная строка ctypes.memmove, но там уже вручную память чистится. А вот первый (сабж) чист как слеза леволиберала, там даже зависимости на 90% из стандартных (остальные 10% обертки к requests)

upcFrost ★★★★★
() автор топика

Найти где течет память в пистоне

Везде. Ты пробовал проверить везде?

anonymous
()
Ответ на: комментарий от fornlr

Конкатенация

Сцепка. С твоими-то интересами таких слов не знать, лол

anonymous
()
Ответ на: комментарий от peregrine

У вас там нету сишных батареек каких в зависимостях? Теоретически они ещё могут течь.

Вы тоже молодец. Поддерживаете мою версию …

Владимир

anonymous
()

Короче если кому интересно - во втором случае где есть ctypes и много сишного веселья помогает окружить обработчик try-finally, сделать gc.freeze, после обработки собрать шлак и отфризить обратно. Иначе тузик начинает растягивать грелку, которая тупо расползается, а обратно сползтись не может.

Правда в этом случае надо следить чтоб в этом промежутке ничего никуда в io не встало и gil не ушёл, иначе с фризом может быть некрасиво

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

upcFrost ★★★★★
() автор топика
Ответ на: комментарий от upcFrost
export LD_PRELOAD=/usr/lib/libjemalloc.so
export MALLOC_CONF=narenas:1  # пистон однопоточный, больше одной арены не нужно, только лишняя фрагментация
intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.