Использование памяти PyPy со временем увеличивается

Я заметил некоторые странности в использовании памяти моей программой, работающей под PyPy и Python. В PyPy программа использует не только значительно больший начальный объем памяти, чем CPython, но это использование памяти со временем значительно увеличивается. В конце программы под PyPy она использует около 170 МБ по сравнению с 14 МБ при запуске под CPython.

Я нашел пользователя с точно такой же проблемой, хотя и в меньшем масштабе, но решения, которые сработали для него, оказали лишь незначительную помощь моей программе использование памяти pypy растет вечно? Две вещи, которые я пытался изменить, это установка переменных среды PYPY_GC_MAX на 100 МБ и PYPY_GC_GROWTH = 1.1, а также ручной вызов gc.collect() при каждом поколение.

Я определяю использование памяти с помощью

resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1000

Вот время выполнения и использование памяти в разных условиях:

Version: time taken, memory used at end of run
PyPy 2.5.0: 100s, 173MB
PyPy with PYPY_GC_MAX = 100MB and PYPY_GC_GROWTH = 1.1: 102s, 178MB
PyPy with gc.collect(): 108s, 131MB
Python 2.7.3: 167s, 14MB

Как видите, под PyPy программа работает намного быстрее, чем под CPython, поэтому я и перешел на него, но ценой десятикратного увеличения объема памяти.

Программа представляет собой реализацию генетического программирования, в которой я создаю арифметическое бинарное дерево более 100 поколений с 200 особями в популяции. Каждый узел в дереве имеет ссылку на своих 2 дочерних элементов, и эти деревья могут увеличиваться в размерах, хотя для этого эксперимента они остаются относительно стабильными. В зависимости от приложения эта программа может работать от 10 минут до нескольких часов, но для результатов здесь я установил меньший набор данных, чтобы выделить проблему.

Кто-нибудь знает, а) что может быть причиной этого, и б) возможно ли ограничить использование памяти до несколько более респектабельных уровней?


person Stuart Lacy    schedule 12.03.2015    source источник
comment
Выполнение gc.collect увеличивает использование памяти для меня. И CPython использовал больше памяти, чем PyPy. Странный.   -  person noɥʇʎԀʎzɐɹƆ    schedule 23.07.2016


Ответы (1)


Известно, что PyPy использует больше базовой памяти, чем CPython, и известно, что это число со временем увеличивается, поскольку JIT компилирует все больше и больше машинного кода. Он действительно (или, по крайней мере, должен) сходится --- это означает, что использование памяти должно увеличиваться по мере выполнения вашей программы, но только до максимума. Вы должны получить примерно такое же использование после 10 минут работы или после нескольких часов.

Мы можем бесконечно обсуждать, много ли 170 МБ для «базового уровня». Что я могу сказать, так это то, что программа, которая использует несколько ГБ памяти на CPython, использует не намного больше на PyPy — это наша цель и наш опыт на данный момент; но, пожалуйста, сообщите об этом как об ошибке, если ваш опыт отличается.

person Armin Rigo    schedule 12.03.2015
comment
Проблема, которую я наблюдаю в своей программе, заключается в том, что это использование памяти не сходится. В нормальных условиях я запускаю программу 10 раз подряд в одном и том же процессе. Я только что проверил это, и PyPy в конце использовал 500 МБ, в то время как Python все еще использовал 14 МБ. Я использую PyPy для научных исследований, и компьютер, на котором я запускаю свои программы, завершает их, если они используют более ГБ, что случалось несколько раз. Я мог бы заставить программу запускать 10 экспериментов как отдельные процессы, но тогда JIT не будет долго разогреваться. Я буду больше играть с параметрами GC. - person Stuart Lacy; 12.03.2015
comment
Мы (команда PyPy) всегда готовы разобраться в подобных проблемах. Не стесняйтесь сообщать, например. на bugs.pypy.org или поговорить с нами на irc.freenode.net, #pypy. - person Armin Rigo; 13.03.2015