Введение
Python - интерпретируемый язык программирования, поэтому перед выполнением код транслируется в машиночитаемые инструкции - байт-код. Байт-код интерпретируется виртуальной машиной, определяемой реализацией языка, например, стандартной - CPython.
Python не взаимодействует с памятью - только с её виртуальным представлением. В процессе выполнения программы операционная система создаёт процесс и выделяет под него ресурсы. В отличие от С/С++ мы не можем управлять памятью из кучи напрямую, а делаем это посредством memory manager, который и обращается к памяти через Python/C API.
Организация доступной виртуальной памяти
Непосредственно с сырой памятью взаимодействует raw memory allocator. Поверх него работают аллокаторы, специфичные для отдельных типов объектов.
Python использует динамическую стратегию распределения памяти, то есть распределение памяти происходит во время выполнения программы.
Виртуальная память представляет собой иерархическую структуру, оптимизированную под блоки размером 256Кб.
Арена - 256Кб
Пул - 4Кб
Блок - от 16 до 512 байт
Блок
Содержит не более одного объекта и находится в одном из трёх состояний:
untouched
- блок ещё не использовалсяfree
- блок использовался механизмом памяти, но больше не содержит использованных программой данныхallocated
- блок хранит данные
Пул
Пул также имеет три состояния:
used
- занятfull
- заполненempty
- пуст (отused
отличаются отсутствиемallocated
блоков) Пулы одного типа и одного размера блоков организованы в двусвязные списки.
Арена
Хранит в себе пулы любых видов. Арены хранятся в двусвязном списке и отсортированы по количеству доступных пустых пулов.
Освобождение памяти: счётчик ссылок и сборщик мусора
Так в Python всё является объектом, то каждое существо имеет прародителя - это PyObject. В нём определены счётчики ссылок и указатель на фактический тип объекта. Это хорошо работает пока Python не сталкивается с циклическим созданием ссылок. Например, когда два объекта ссылаются друг на друга. Для борьбы с такими проблемами поднимается сборщик мусора.
Советы
Обращайте внимание на работу с неизменяемыми объектами. К примеру, вместо присваивания строк, используйте
.join()
или.format()
.Избегайте вложенных циклов. Это приводит к созданию чрезмерно большого количество объектов в виртуальной памяти процесса.
Используйте кэширование.
Профилируйте код.
Заключение
При использовании базовых возможностей Python знание о внутреннем устройстве память в интерпретаторе не обязательно, но когда дело доходит до широкомасштабных коммерческих проектов, то узнать тонкости для лучшей оптимизации кодовой базы всё же будет полезным.
Комментарии (5)
CrazyElf
00.00.0000 00:00+2Не понял насчёт присваивания строк. Наверное имелось в виду сложение строк? Присваивание строк - это присваивание ссылки на строку в новую переменную, само по себе это не проблема.
И что насчёт вложенных циклов? Сами по себе циклы не проблема. Имелось в виду создание каких-то локальных переменных внутри этих циклов или что?
Eugeen1948
00.00.0000 00:00-1Что особенно занимает, так это про "широкомасштабные коммерческие проекты". Какой язык программирования для соответствующего проекта будет наиболее эффективным? Вот, например, коды для расчета безопасности для АЭС (Атомных электростанций) ATHLET, Relap-5 стоят десятки тысяч долларов, да + еще и обучение. И все такие коды написаны на FORTRAN! А почему? Да потому, что многие умники пытались превзойти FORTRAN по компактности и быстродействию кода, переписывая на С++ или Pyton, и были сильно разочарованы результатами. У меня есть программка, написанная еще на FORTRAN - ЦЕРН для БЭСМ-6 в 1975 г. Мой старший сын попытался её ускорить на С++ (он, в свои 42 года весьма умелый и знающий специалист). После многих попыток он признал, что код на FORTRAN нельзя ничем улучшить, кроме Ассемблера (да и то не сильно). Интересно, что оптимизирующий компилятор с Фортрана для компьютеров IBM был написан на Фортране., что по мнению разработчиков позволило довести его до совершенства! А есть ли такие примеры в других языках?
CrazyElf
00.00.0000 00:00Кстати, для Фортрана есть и современный вполне компилятор. На нём часть математических библиотек для Питона написана. Судя по всему, этот код практически такой же быстрый как С++, раз никто эти библиотеки на С++ не переписывает.
fenrir1121
Так может расскажите как вы применили подобное знание на каком-то проекте пока не поздно?
А не этот вольный хромой пересказ статьи "Memory Management" с RealPython?