Использование памяти Python String во FreeBSD - PullRequest
6 голосов
/ 17 марта 2011

Я наблюдаю странную картину использования памяти со строками Python во Freebsd.Рассмотрим следующую сессию.Идея состоит в том, чтобы создать список, содержащий несколько строк, чтобы кумулятивные символы в списке составляли 100 МБ.

l = []
for i in xrange(100000):
    l.append(str(i) * (1000/len(str(i))))

При этом используется около 100 МБ памяти, как и ожидалось, и 'del l' очистит это.

l = []
for i in xrange(20000):
    l.append(str(i) * (5000/len(str(i))))

Используется 165 МБ памяти.Я действительно не понимаю, откуда берется дополнительное использование памяти.[Размер обоих списков одинаков]

Python 2.6.4 во FreeBSD 7.2.В Linux / Windows оба используют только около 100 МБ памяти.

Обновление: я измеряю память, используя 'ps aux'.Это можно выполнить с помощью os.sytem после приведенных выше фрагментов кода.Кроме того, они выполнялись отдельно.

Update2: похоже на память mallocs freebsd, кратную 2. Так что выделение 5KB фактически выделяет 8KB.Хотя я не уверен.

Ответы [ 3 ]

1 голос
/ 19 марта 2011

По-моему, это, вероятно, фрагменты в памяти.Прежде всего, фрагменты памяти, которые больше, чем 255 байтов, будут выделены с помощью malloc в CPython.Вы можете сослаться на

Улучшение распределения памяти Python

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

0x00003

. Он не выровнен на 4 байта, поэтому компьютер может очень медленно получить доступ к памяти.Следовательно, все адреса, которые вы получаете через malloc, должны быть

0x00000
0x00004
0x00008

и так далее.Выравнивание в 4 байта является только основным общим правилом, реальная политика выравнивания будет вариантом ОС.

И объем памяти, о котором вы говорите, должен быть RSS (не уверен).Для большинства ОС размер страницы виртуальной памяти составляет 4 КБ.Для того, что вы выделяете, вам нужно 2 страницы для хранения фрагмента 5000 байт.Давайте посмотрим на пример для иллюстрации утечки памяти.Мы предполагаем, что выравнивание здесь составляет 256 байт.

0x00000 {
...       chunk 1
0x01388 }
0x01389 {
...       fragment 1
0x013FF }
0x01400 {
...       chunk 2
0x02788 }
0x02789 {
...       fragment 2
0x027FF }
0x02800 {
...       chunk 3
0x03B88 }
0x03B89 {
...       fragment 3
0x04000 }

Как вы можете видеть, в памяти так много фрагментов, что их нельзя использовать, но, тем не менее, они занимают пространство памяти страницы,Я не уверен, какова политика выравнивания FreeBSD, но я думаю, что это вызвано такой причиной.Для эффективного использования памяти с Python вы можете использовать большой кусок заранее выделенного bytearray и выбрать хорошее число в качестве используемого чанка (необходимо проверить, какое число лучше, это зависит отOS).

0 голосов
/ 19 марта 2011

Я думаю, что все адреса памяти в freebsd должны быть выровнены до степени двойки. Таким образом, все пулы памяти Python несколько фрагментированы и не непрерывны.

Попробуйте использовать другой инструмент , чтобы найти что-нибудь интересное

0 голосов
/ 19 марта 2011

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

Как говорит @Hossein, попробуйте выполнить оба фрагмента кода за один прогон, а затем поменять их местами.

...