Как выделить больше памяти pycharm
Я большой поклонник PyCharm от JetBrains, но я сталкиваюсь с некоторыми проблемами, о которых я подумал, возможно, я спрошу здесь.
- Неожиданно зависает и такое случается часто. В целом, на мой вкус, это немного медленно, и мне хотелось бы получить несколько советов о том, как повысить производительность IDE.
- Часто, когда я открываю проект, PyCharm помечает все встроенные модули как предупреждения о неразрешенных ссылках. такие вещи, как open (), str () и т.д., а также некоторые из модулей, которые я импортирую, например sys (это наиболее распространенные нарушители :)).
Моя конфигурация: Mac OSX Lion работает на MacBook Pro (середина 2010 г.) с 8 ГБ ОЗУ
Теперь послушайте, я понимаю, что диагностировать подобные вещи сложно без какого-либо снимка или дополнительной информации о том, что происходит, но я просто спрашиваю, сталкивался ли кто-нибудь с этими проблемами раньше, и если да, то как они были решены?
PS Я также связывался с JetBrains по поводу этих проблем, но, честно говоря, я обычно нахожу здесь хорошие решения общих проблем, и я подумал, что могу также спросить
Мой PyCharm работал очень медленно (очень часто зависал на несколько секунд), когда в консоли было много строк. => Я удалил несколько отпечатков, и все вернулось в норму – Vincent J 22/11/2021
1. Измените уровень проверки.
Текущие версии PyCharm позволяют изменять тип выполняемого статического анализа кода, а также имеют функцию экономии энергии / ЦП (щелкните значок в правом нижнем углу рядом с замком):
2. Измените проиндексированные каталоги.
Исключить из индексации каталоги, которые заданы в путях проекта, но фактически не требуются для поиска и индексации. Нажмите ALT+CTRL+S и найдите project .
3. Проведите чистку памяти
Есть еще одна интересная особенность:
Зайдите в настройки (Файл / Настройки) и найдите память . В IDE Settings>Appearance -> отметьте Show memory indicator . В правом нижнем углу появится панель памяти (см. Рисунок ниже). Щелкните эту панель, чтобы запустить сборку мусора / очистку памяти .
Разве такие вещи не должны время от времени запускаться автоматически? – Berry Tsakala 30/08/2013
ctrl + alt + s -> настройки – mateuszb 30/08/2013
Я бы также отключил все плагины, которые вы не используете. Двойной сдвиг и поиск «плагины» и снятие отметок со всех, которые вам не нужны. – Steve Rossiter 30/08/2013
Отключение плагинов помогает ускорить запуск. – Ciasto piekarz 30/08/2013
Пункт № 1 мне очень помог, я собирался удалить и вернуться к Sublime 3, потому что я не мог плавно прокручивать, но теперь PyCharms можно использовать. – wilblack 30/08/2013
Просто хочу поделиться тем, что пункт № 2 работает, пожалуйста, исключите и вашу папку ".git" . – Steven Du 30/08/2013
В OSX, на PyCharm CE 2016.3.2, №1 не существовало, а для №2 и №3 эти ярлыки, конечно, не работают, но я сделал CMD- (слева) Shift-A, который вызывает диалог поиска параметров, который поможет мне их найти. Для меня наличие корней проекта в качестве всего моего домашнего каталога вызывало серьезные проблемы с замедлением. Спасибо, что написали это. – Emmel 30/08/2013
есть ли способ увеличить размер кучи? – Yuda Prawira 30/08/2013
Я выполнил большинство решений, изменив уровень проверки, решение 2 и 3, даже я удалил некоторые плагины, но мой pycharm все еще зависает, когда я печатаю, я использую WIn10 на ПК с 8 ГБ ОЗУ и i core5, изначально IDE работал очень хорошо, теперь продолжает замедляться. – Lutaaya Huzaifah Idris 30/08/2013
У меня были самые большие проблемы с автоматическим форматированием (я практически нажимаю ctrl + alt + l каждые две или три строки кода), и проблема возникла после создания очень больших исходников; Решение №2 решило проблему: сначала я исключил эти сгенерированные большие источники, затем выполнил очистку кеша и перезапустил, и снова работал нормально. Эти большие источники представляют собой определение очень больших массивов python в источнике (данные непосредственно в источнике) для целей тестирования / пробной версии (не для производства), поэтому их можно было исключить из индексации. – Ettore Galli 30/08/2013
После анализа снимка состояния ЦП команда PyCharm будет работать над исправлением и выпускать новую версию, на которую (надеюсь) не повлияет эта конкретная проблема с производительностью. Команда также может предложить вам изменить конфигурацию или способ решения проблемы на основе анализа предоставленных данных.
Чтобы прояснить, я хочу выяснить, что PyCharm застряло при обработке. Я публикую как комментарий, так как не думаю, что PyCharm нуждается в большом количестве плохих вопросов SO, и мне не очень повезло с проблемами, которые не являются очевидными ошибками в процессе поддержки. Мой вентилятор просто остановился на несколько часов, и его использование снова упало до 5%, но оно снова резко возросло. Я ничего не делал в PyCharm. – Chris 28/04/2012
Это связано с запуском iPython в консоли Python, возможно, при попытке запустить Django при наличии ошибок. Удаление ipython из моей виртуальной среды, похоже, решило проблему - пока консоль, отличная от ipython, не вызывает такой же проблемы. Так что нечего делать с PyCharm. Спасибо @CrazyCoder за продолжение. – Chris 28/04/2012
«Каждая проблема производительности с PyCharm уникальна», другими словами, PyCharm не может быть исправлен :-( Напротив, общая неуникальная проблема, похоже, связана с большой папкой данных в проекте, которую следует исключить из проверки. – jolvi 28/04/2012
Что ж, у Лоренца Ло Зауэра уже есть хороший вопрос на этот счет. но если вы хотите решить эту проблему с помощью настройки Pycharm (без отключения проверки кода Pycharm). вы можете настроить размер кучи по своему усмотрению. поскольку я предпочитаю использовать решение с увеличивающимся размером кучи для медленно работающего приложения Pycharm.
Вы можете настроить размер кучи, отредактировав файл pycharm.exe.vmoptions. и pycharm64.exe.vmoptions для 64-битного приложения. а затем отредактируйте на нем значения -Xmx и -Xms.
Поэтому я выделяю 2048 м для значений xmx и xms (что составляет 2 ГБ) для моего размера кучи Pycharm. Вот моя конфигурация. У меня 8 ГБ памяти, поэтому я установил ее со следующим параметром:
сохраните настройку и перезапустите IDE. И включаю "Показывать индикатор памяти" в настройках-> Внешний вид и поведение-> Внешний вид. чтобы увидеть это в действии:
и Pycharm теперь работает быстро и нормально.
Отлично :) Следует упомянуть о перезапуске IDE. – Appyx 08/05/2017
Это лучший ответ (см. Ответ JMJ ниже, который дает простой способ его отредактировать). Я думаю, что максимальный объем памяти PyCharm по умолчанию, равный 2 ГБ, немного мал для многих пользователей. – Stephen 08/05/2017
В моем случае проблема заключалась в папке в каталоге проекта, содержащей более 300 тыс. Файлов общим объемом 11 ГБ. Это была временная папка с изображениями, полученными в результате каких-то вычислений. После перемещения этой папки из структуры проекта пропала медлительность. Я надеюсь, что это может кому-то помочь, пожалуйста, проверьте структуру своего проекта, чтобы увидеть, есть ли что-то ненужное.
Этот! Если вы хотите сохранить папку в каталоге проекта, исключите ее из индексации: щелкните правой кнопкой мыши папку, которую вы хотите исключить, «Пометить каталог как» -> «Исключено». – dtadres 21/05/2018
Это была моя точная проблема, слишком много изображений хранится вместе с моим кодом, и, пометив каталог как исключенный, медлительность / заикание исчезли. – IntegrateThis 21/05/2018
Это очень просто, изменив размер кучи, как уже упоминалось. Просто перейдя в Pycharm HELP -> Edit custom VM option . и измените его на:
Что касается проблемы с зависанием, мы обнаружили, что это произошло при обработке файлов CSV, по крайней мере, с одной очень длинной строкой.
Однако, похоже, это было исправлено в PyCharm 4.5.4 , поэтому, если вы столкнулись с этим, попробуйте обновить свой PyCharm.
Я нашел решение этой проблемы, которое прекрасно работает в Windows, и хотел им поделиться.
Решения, которые не сработали: у меня 16 ГБ ОЗУ, и все еще было ужасное отставание. PyCharm занимает для меня менее 1 ГБ ОЗУ, так что проблема не в этом. Отключение инспекций совершенно не помогло, и я не помню никаких специальных плагинов. Я также попытался поиграть с привязкой к процессору для процесса, что на короткое время сработало, но не совсем.
Что сработало красиво, почти идеально:
- Установите приоритет процессора PyCharm на выше нормального
- Установите приоритет ЦП для процессов Python ниже нормального
Вы можете сделать это вручную, но я рекомендую использовать программу, которая сохранит настройки при перезапусках и для нескольких экземпляров. Я использовал Process Hacker: щелкните правой кнопкой мыши процесс -> Приоритет -> Установите приоритет. Затем щелкните правой кнопкой мыши еще раз -> Процесс -> и выберите «Сохранить для pycharm64.exe» и аналогично для python «Сохранить для python.exe». Наконец, в Process Hacker перейдите в «Параметры» и выберите «Начать при входе в систему». Это сделает так, чтобы ВСЕ исполняемые файлы Pycharm и python получали эти приоритеты ЦП даже после перезапуска программы и / или Windows, независимо от того, сколько экземпляров python вы запускаете.
По сути, большая часть задержек PyCharm может быть связана с конфликтом с другими программами. Подумайте об этом: да, PyCharm требует много ресурсов процессора, но разработчики PyCharm не глупы. Они, вероятно, по крайней мере, убедились, что он может работать без задержек на пустом ядре. Но теперь вы открываете Chrome и 30 вкладок, Fiddler, программу FTP, iTunes, Word, Slack и т. Д., И все они конкурируют с PyCharm на одном уровне приоритета ЦП. Когда сумма всех программ на ядре> 100%, вы видите отставание. Переключение на приоритет Above Normal дает PyCharm что-то более близкое к пустому ядру, на котором он, вероятно, был протестирован.
Что касается «Ниже нормального» на python.exe, в основном вы не хотите замедлять работу компьютера собственной разработкой. Большинство программ на Python по сути являются «пакетными» программами, и вы, вероятно, не заметите дополнительного времени, необходимого для их выполнения. Я не рекомендую это делать, если вы разрабатываете графическую интерактивную программу.
Все это может быть менее серьезной проблемой для компьютера с 4 физическими ядрами (8 логическими ядрами). В моем случае я застрял с 2 физическими ядрами (4 логическими), поэтому более важно управлять процессами, выполняющими локальную разработку. – Stephen 20/08/2017
Предупреждение : не превышайте норму выше нормы. Если вы сделаете это, вы будете конкурировать с процессами Windows и, возможно, вызовете хаос на вашем компьютере. И вы бы даже не сделали это намного быстрее, если бы вообще. – Stephen 20/08/2017
Все работало, но у меня было ужасное отставание в редакторе кода, пока я не определил свой Файл - Настройки - Проект: имя - Python Interpreter.
Я думал, что у меня проблема со скоростью с PyCharm, но в итоге оказалось, что консоль вывода в PyCharm не обязательно эмулирует вывод современных терминальных приложений.
Вот мое решение: щелкните значок раскрывающегося списка (стрелка) вашей конфигурации -> щелкните edit configuration -> щелкните emulate terminal in output console -> щелкните ok -> Запустите конфигурацию.
В моем случае это было очень медленно, и мне нужно было изменить настройки проверок, я все перепробовал, единственное, что сработало, - это переход с версии 2018.2 на 2016.2, иногда лучше оставить какие-то обновления позади .
Python - это фантастический язык программирования. Он также известен как довольно медленный, в основном из-за его огромной гибкости и динамических характеристик. Для многих приложений и областей это не проблема из-за их требований и различных методов оптимизации. Менее известно, что графы объектов Python (вложенные словари списков, кортежей и примитивных типов) занимают значительный объем памяти. Это может быть гораздо более серьезным ограничивающим фактором из-за его влияния на кеширование, виртуальную память, многопользовательскую работу с другими программами и в целом более быстрое исчерпание доступной памяти, которая является дефицитным и дорогим ресурсом.
Оказывается, нетривиально выяснить, сколько памяти фактически потребляется. В этой статье я расскажу о тонкостях управления памятью объекта Python и покажу, как точно измерить потребляемую память.
В этой статье я остановлюсь исключительно на CPython - основной реализации языка программирования Python. Эксперименты и выводы здесь не относятся к другим реализациям Python, таким как IronPython, Jython и PyPy.
Также я запустил числа на 64-битном Python 2.7. В Python 3 числа иногда немного отличаются (особенно для строк, которые всегда являются Unicode), но концепции одинаковы.
Практическое исследование использования памяти Python
Во-первых, давайте немного разберемся и получим конкретное представление о фактическом использовании памяти объектами Python.
Встроенная функция sys.getsizeof()
Модуль sys стандартной библиотеки предоставляет функцию getsizeof(). Эта функция принимает объект (и необязательный параметр по умолчанию), вызывает метод sizeof() объекта и возвращает результат, поэтому вы также можете сделать ваши объекты инспектируемыми.
Измерение памяти объектов Python
Давайте начнем с некоторых числовых типов:
Интересно. Целое число занимает 24 байта.
Хм . float также занимает 24 байта.
Вот это да. 80 байтов! Это действительно заставляет задуматься о том, хотите ли вы представлять большое количество вещественных чисел как числа с плавающей запятой или десятичные дроби.
Давайте перейдем к строкам и коллекциям:
Хорошо. Пустая строка занимает 37 байтов, и каждый дополнительный символ добавляет еще один байт. Это многое говорит о компромиссе между сохранением нескольких коротких строк, когда вы будете платить 37 байтов за каждую, а не одну длинную строку, где вы платите только один раз.
Строки Unicode ведут себя аналогично, за исключением того, что служебные данные составляют 50 байтов, и каждый дополнительный символ добавляет 2 байта. Это стоит учитывать, если вы используете библиотеки, которые возвращают строки Unicode, но ваш текст может быть представлен в виде простых строк.
Кстати, в Python 3 строки всегда имеют Unicode, а служебные данные составляют 49 байт (они где-то сохранили байт). Объект байтов имеет служебную информацию только 33 байта. Если у вас есть программа, которая обрабатывает много коротких строк в памяти, и вы заботитесь о производительности, рассмотрите Python 3.
В чем дело? Пустой список занимает 72 байта, но каждый дополнительный int добавляет всего 8 байтов, где размер int составляет 24 байта. Список, который содержит длинную строку, занимает всего 80 байтов.
История повторяется для кортежей. Накладные расходы пустого кортежа составляют 56 байтов против 72 списка. Опять же, эта разница в 16 байтов на последовательность - это низко висящий плод, если у вас есть структура данных с большим количеством небольших неизменяемых последовательностей.
Наборы и словари якобы вообще не растут при добавлении элементов, но отмечают огромные накладные расходы.
Суть в том, что у объектов Python огромные фиксированные накладные расходы. Если ваша структура данных состоит из большого количества объектов коллекций, таких как строки, списки и словари, которые содержат небольшое количество элементов каждый, вы много платите.
Функция deep_getsizeof()
Теперь, когда я напугал вас до полусмерти и продемонстрировал, что sys.getsizeof() может только сказать вам, сколько памяти занимает примитивный объект, давайте посмотрим на более адекватное решение. Функция deep_getsizeof() рекурсивно выполняет детализацию и вычисляет фактическое использование памяти графом объектов Python.
У этой функции есть несколько интересных аспектов. Она учитывает объекты, на которые ссылаются несколько раз, и учитывает их только один раз, отслеживая идентификаторы объектов. Другая интересная особенность реализации заключается в том, что она в полной мере использует абстрактные базовые классы модуля коллекций. Это позволяет функции очень лаконично обрабатывать любую коллекцию, которая реализует базовые классы Mapping или Container, вместо непосредственного обращения к множеству типов коллекций, таких как: строка, Unicode, байты, список, кортеж, dict, frozendict, OrderedDict, set, frozenset и т.д.
Давайте посмотрим на это в действии:
Строка длиной 7 занимает 44 байта (37 служебных данных + 7 байтов для каждого символа).
Пустой список занимает 72 байта (только накладные расходы).
python deep_getsizeof ([x], set ()) 124
Список, содержащий строку x, занимает 124 байта (72 + 8 + 44).
Список, содержащий строку x 5 раз, занимает 156 байтов (72 + 5 * 8 + 44).
Последний пример показывает, что deep_getsizeof() подсчитывает ссылки на один и тот же объект (строку x) только один раз, но подсчитывается указатель каждой ссылки.
Баг или фича
Оказывается, что у CPython есть несколько хитростей, поэтому числа, которые вы получаете от deep_getsizeof(), не полностью отражают использование памяти программой Python.
Подсчет ссылок
Python управляет памятью, используя семантику подсчета ссылок. Когда на объект больше не ссылаются, его память освобождается. Но пока есть ссылка, объект не будет освобожден. Такие вещи, как циклические ссылки, могут вас сильно укусить.
Маленькие объекты
Целые числа
CPython хранит глобальный список всех целых чисел в диапазоне [-5, 256]. Эта стратегия оптимизации имеет смысл, потому что маленькие целые числа всплывают повсюду, и, учитывая, что каждое целое число занимает 24 байта, оно экономит много памяти для типичной программы.
Это также означает, что CPython предварительно выделяет 266 * 24 = 6384 байта для всех этих целых чисел, даже если вы не используете большинство из них. Вы можете проверить это с помощью функции id(), которая дает указатель на фактический объект. Если вы называете id(x) несколько для любого x в диапазоне [-5, 256], вы будете каждый раз получать один и тот же результат (для одного и того же целого числа). Но если вы попробуете это для целых чисел за пределами этого диапазона, каждый из них будет отличаться (новый объект создается на лету каждый раз).
Вот несколько примеров в этом диапазоне:
Вот несколько примеров за пределами диапазона:
Память Python против системной памяти
Теперь эта память 100X может быть бесполезно захвачена в вашей программе, никогда больше не использоваться и лишать систему возможности выделять ее другим программам. Ирония заключается в том, что если вы используете модуль обработки для запуска нескольких экземпляров вашей программы, вы строго ограничите количество экземпляров, которые вы можете запустить на данном компьютере.
Профилировщик памяти
Чтобы измерить и измерить фактическое использование памяти вашей программой, вы можете использовать модуль memory_profiler. Я немного поиграл с этим, и я не уверен, что доверяю результатам. Он очень прост в использовании. Вы декорируете функцию (может быть главной (0 функция)) с помощью декоратора @profiler, и когда программа завершает работу, профилировщик памяти выводит на стандартный вывод удобный отчет, который показывает общее количество и изменения в памяти для каждой строки. Вот пример программы, которую я запускал под профилировщиком:
Как вы можете видеть, занято 22,9 МБ дополнительной памяти. Причина, по которой память не увеличивается при добавлении целых чисел как внутри, так и вне диапазона [-5, 256], а также при добавлении строки, заключается в том, что во всех случаях используется один объект. Непонятно, почему первый цикл диапазона (100000) в строке 8 добавляет 4,2 МБ, в то время как второй цикл в строке 10 добавляет всего 0,4 МБ, а третий цикл в строке 12 добавляет 0,8 МБ. Наконец, при удалении списков a, b и c освобождается -0.6MB для a и c, но для b добавляется 0.2MB. Я не могу понять эти странные результаты.
Заключение
CPython использует много памяти для своих объектов. Он использует различные приемы и оптимизации для управления памятью. Отслеживая использование памяти вашим объектом и зная модель управления памятью, вы можете значительно уменьшить объем памяти вашей программы.
Я использую pycharm, и его память показана в правом нижнем углу - 750M. Я не мог найти никаких настроек, где я могу это увеличить. Где я могу увеличить эту память. Я использую версию 3.4.
Я много искал, но не смог найти и Google.
4 ответа
В каталоге /bin вашей установки pycharm есть файл pycharm.vmoptions . Вы можете использовать это, чтобы настроить параметры, которые передаются в JVM. Максимальный размер кучи должен быть задан
- Справка - > Найти действие - > (введите « Параметры виртуальной машины ») - > (щелкните) « Изменить пользовательскую виртуальную машину параметры "
- Pycharm (2016.2) откроет соответствующий файл vmoptions (pycharm.vmoptions или pycharm64.options) в редакторе перед вами.
- Измените -Xmx750m на -Xmx1024m или любой размер, который вы хотите. Сохраните его.
- Перезапустить Pycharm (Файл- > Выход и т. д.).
Вместо того, чтобы вручную искать нужные файлы, вы можете (по крайней мере, в PyCharm 5) теперь просто выполнить поиск или перейти к «Редактировать пользовательские параметры виртуальной машины», и он создаст и откроет для вас файл vmoptions по умолчанию, как описано в Ссылка . Тогда,
To increase PyCharm heap size, . modify the -Xmx setting.
EDIT: я не знаю почему, но этот процесс создал для меня файл pycharm64.vmoptions , и это фактически не изменило размер кучи (как указано внизу справа " Показывать индикатор памяти "). Мне действительно пришлось переименовать этот файл в pycharm.vmoptions , чтобы он работал.
В случае 64-битной версии будет два файла. pycharm.vmoptions и pycharm64.vmoptions.
Увеличьте размер кучи и Perm Size
Примечание. Вы можете увеличить его в соответствии с конфигурацией вашей системы. Так что сделайте это с умом: если PyCharm не откроется для вас, это означает, что вы переопределили память. Я думал, что это не работает для меня из-за ожидающего перезапуска, но также не работает после перезапуска. Просто откройте файлы «vmoptions» и итеративно идите до тех пор, пока PyCharm не запустится.
В этом руководстве мы узнаем, как Python управляет памятью или как обрабатывает наши данные внутренне. Это руководство даст глубокое понимание основ управления памятью Python. Когда мы выполняем наш скрипт, в его памяти запускается много логических процессов, чтобы сделать код эффективным.
Вступление
Управление памятью в Python очень важно для разработчиков программного обеспечения для эффективной работы с любым языком программирования. Мы не можем упускать из виду важность управления памятью при реализации большого количества данных. Неправильное управление памятью приводит к замедлению работы приложения и серверных компонентов. Это также становится причиной неправильной работы. Если память не используется должным образом, предварительная обработка данных займет много времени.
В Python памятью управляет менеджер Python, который определяет, куда поместить данные приложения в память.
Предположим, что память выглядит как пустая книга, и мы хотим написать что-нибудь на странице книги. Когда мы записываем любые данные, менеджер находит свободное место в книге и передает их приложению. Процедура предоставления памяти объектам называется распределением.
С другой стороны, когда данные больше не используются, они могут быть удалены менеджером памяти Python. Но вопрос в том, как? А откуда взялось это воспоминание?
Распределение памяти Python
- Распределение статической памяти
- Распределение динамической памяти
Статической памяти
Размещение стека
Структура данных Stack используется для хранения статической памяти. Это необходимо только внутри конкретной функции или вызова метода. Функция добавляется в стек вызовов программы всякий раз, когда мы ее вызываем. Назначение переменной внутри функции временно сохраняется в стеке вызова функции; функция возвращает значение, и стек вызовов переходит к текстовой задаче. Компилятор обрабатывает все эти процессы, поэтому нам не нужно об этом беспокоиться.
Стек вызовов(структура данных стека) содержит рабочие данные программы, такие как подпрограммы или вызовы функций, в порядке их вызова. Эти функции выходят из стека при вызове.
Динамической памяти
Как мы знаем, все в Python является объектом, а это означает, что динамическое распределение памяти вдохновляет управление памятью Python. Диспетчер памяти Python автоматически исчезает, когда объект больше не используется.
Распределение памяти в куче
Структура данных кучи используется для динамической памяти, которая не имеет отношения к именованию аналогов. Это тип памяти, который используется вне программы в глобальном пространстве. Одним из лучших преимуществ кучи памяти является то, что она освобождает пространство памяти, если объект больше не используется или узел удален.
В приведенном ниже примере мы определяем, как переменная функции хранится в стеке и куче.
Реализация Python по умолчанию
В основном язык Python написан на английском языке. Однако это определено в справочном руководстве, что само по себе бесполезно. Итак, нам нужен код, основанный на интерпретаторе правила в руководстве.
Преимущество реализации по умолчанию заключается в том, что она выполняет код Python на компьютере, а также преобразует наш код Python в инструкции. Итак, мы можем сказать, что реализация Python по умолчанию удовлетворяет обоим требованиям.
Программа, которую мы пишем на языке Python, сначала преобразует в байт-код компьютерных инструкций. Виртуальная машина интерпретирует этот байт-код.
Сборщик мусора Python
Как мы объясняли ранее, Python удаляет те объекты, которые больше не используются, можно сказать, что освобождает пространство памяти. Этот процесс удаления ненужного пространства памяти объекта называется сборщиком мусора. Сборщик мусора Python запускает свое выполнение вместе с программой и активируется, если счетчик ссылок падает до нуля.
Когда мы назначаем новое имя или помещаем его в контейнеры, такие как словарь или кортеж, счетчик ссылок увеличивает свое значение. Если мы переназначаем ссылку на объект, счетчик ссылок уменьшает свое значение. Он также уменьшает свое значение, когда ссылка на объект выходит за пределы области видимости или объект удаляется.
Как мы знаем, Python использует динамическое выделение памяти, которым управляет структура данных Heap. Куча памяти содержит объекты и другие структуры данных, которые будут использоваться в программе. Диспетчер памяти Python управляет выделением или отменой выделения пространства кучи с помощью функций API.
Объекты Python в памяти
Как мы знаем, в Python все является объектом. Объект может быть простым(содержащий числа, строки и т. д.) или контейнером(словарь, списки или определенные пользователем классы). В Python нам не нужно объявлять переменные или их типы перед их использованием в программе.
Давайте разберемся в следующем примере.
Как видно из вышеприведенного вывода, мы присвоили значение объекту x и распечатали его. Когда мы удаляем объект x и пытаемся получить доступ в дальнейшем коде, будет ошибка, утверждающая, что переменная x не определена.
Следовательно, сборщик мусора Python работает автоматически, и программистам не нужно беспокоиться об этом, в отличие от C.
Подсчет ссылок в Python
Подсчет ссылок показывает, сколько раз другие объекты ссылаются на данный объект. Когда назначается ссылка на объект, счетчик объектов увеличивается на единицу. Когда ссылки на объект удаляются, количество объектов уменьшается. Когда счетчик ссылок становится равным нулю, диспетчер памяти Python выполняет освобождение. Давайте сделаем это простым для понимания.
Предположим, есть две или более переменных, которые содержат одно и то же значение, поэтому виртуальная машина Python скорее создает другой объект с таким же значением в частной куче. Фактически это указывает на то, что вторая переменная указывает на изначально существующее значение в частной куче.
Это очень полезно для сохранения памяти, которая может использоваться другой переменной.
Когда мы присваиваем значение переменной x, целочисленный объект 10 создается в памяти кучи, и его ссылка присваивается x.
В приведенном выше коде мы присвоили y = x, что означает, что объект y будет ссылаться на тот же объект, потому что Python выделил ту же ссылку на объект новой переменной, если объект уже существует с тем же значением.
Теперь посмотрим на другой пример.
Переменные x и y не ссылаются на один и тот же объект, потому что x увеличивается на единицу, x создает новый объект ссылки, а y по-прежнему ссылается на 10.
Преобразование сборщика мусора
Сборщик мусора Python классифицировал объекты с помощью своей генерации. Сборщик мусора Python имеет три поколения. Когда мы определяем новый объект в программе, его жизненный цикл обрабатывается первым поколением сборщика мусора. Если объект используется в другой программе, он будет стимулироваться до следующего поколения. У каждого поколения есть порог.
Сборщик мусора вступает в действие, если превышен порог количества выделений за вычетом числа отмененных.
Мы можем изменить пороговое значение вручную с помощью модуля GC. Этот модуль предоставляет метод get_threshold() для проверки порогового значения другого поколения сборщика мусора. Давайте разберемся в следующем примере.
Пороговое значение для запуска сборщика мусора можно изменить с помощью метода set_threshold().
В приведенном выше примере значение порога увеличилось для всех трех поколений. Это повлияет на частоту запуска сборщика мусора. Программистам не нужно беспокоиться о сборщике мусора, но он играет важную роль в оптимизации среды выполнения Python для целевой системы.
Сборщик мусора Python обрабатывает низкоуровневые детали для разработчика.
Важность выполнения ручной сборки мусора
Как мы обсуждали ранее, интерпретатор Python обрабатывает ссылку на объект, используемый в программе. Он автоматически освобождает память, когда счетчик ссылок становится равным нулю. Это классический подход для подсчета ссылок, если он не работает, когда программа ссылается на циклы. Цикл ссылок происходит, когда один или несколько объектов ссылаются друг на друга. Следовательно, счетчик ссылок никогда не становится нулевым.
Мы создали справочный цикл. Объект list1 ссылается на сам объект list1. Когда функция возвращает объект list1, память для объекта list1 не освобождается. Так что подсчет ссылок не подходит для решения ссылочного цикла. Но мы можем решить эту проблему, изменив сборщик мусора или производительность сборщика мусора.
Для этого мы будем использовать функцию gc.collect() для модуля gc.
Приведенный выше код даст количество собранных и освобожденных объектов.
Метод gc.collect() используется для выполнения сборки мусора по времени. Этот метод вызывается через фиксированный интервал времени для выполнения сборки мусора на основе времени.
При четной сборке мусора функция gc.collect() вызывается после возникновения события. Давайте разберемся в следующем примере.
В приведенном выше коде мы создали объект list1, на который ссылается переменная list. Первый элемент объекта списка ссылается на себя. Счетчик ссылок на объект списка всегда больше нуля, даже если он удален или выходит за рамки программы.
Управление памятью в Python
В этом разделе мы подробно обсудим архитектуру памяти C Python. Как мы обсуждали ранее, существует уровень абстракции от физического оборудования до Python. Различные приложения или Python обращаются к виртуальной памяти, созданной операционной системой.
Python использует часть памяти для внутреннего использования и необъектную память. Другая часть памяти используется для объекта Python, такого как int, dict, list и т. д.
CPython содержит распределитель объектов, который выделяет память в области объекта. Распределитель объектов получает вызов каждый раз, когда новому объекту требуется место. Распределитель предназначен для небольшого количества данных, потому что Python не задействует слишком много данных за раз. Он выделяет память, когда это абсолютно необходимо.
Стратегия выделения памяти CPython состоит из трех основных компонентов.
Распространенные способы уменьшить сложность пространства
Мы можем следовать некоторым передовым методам, чтобы уменьшить сложность пространства. Эти методы должны сэкономить достаточно места и сделать программу эффективной. Ниже приведены несколько практик в Python для распределителей памяти.
Мы определяем список на Python; распределитель памяти распределяет память кучи соответственно индексации списка. Предположим, нам нужен подсписок к данному списку, затем мы должны выполнить нарезку списка. Это простой способ получить подсписок из исходного списка. Он подходит для небольшого количества данных, но не подходит для емких данных.
Следовательно, нарезка списка генерирует копии объекта в списке, просто копирует ссылку на них. В результате распределитель памяти Python создает копию объекта и выделяет ее. Поэтому нам нужно избегать разрезания списка.
Лучший способ избежать этого: разработчик должен попытаться использовать отдельную переменную для отслеживания индексов, а не нарезать список.
Разработчик должен попытаться использовать «для элемента в массиве» вместо «для индекса в диапазоне(len(array))» для экономии места и времени. Если программе не нужна индексация элемента списка, не используйте ее.
Конкатенация строк не подходит для экономии места и времени. По возможности, мы должны избегать использования знака «+» для конкатенации строк, потому что строки неизменяемы. Когда мы добавляем новую строку к существующей строке, Python создает новую строку и присваивает ее новому адресу.
Каждая строка требует фиксированного размера памяти в зависимости от символа и его длины. Когда мы меняем строку, ей требуется другой объем памяти и ее необходимо перераспределить.
Мы создали переменную a для ссылки на строковый объект, который является информацией о строковом значении.
Затем мы добавляем новую строку с помощью оператора «+». Python перераспределяет новую строку в памяти в зависимости от ее размера и длины. Предположим, что размер памяти исходной строки равен n байтам, тогда новая строка будет размером m байтов.
Вместо использования конкатенации строк мы можем использовать «.join(iterable_object)» или формат или%. Это оказывает огромное влияние на экономию памяти и времени.
Итераторы очень полезны как для времени, так и для памяти при работе с большим набором данных. Работая с большим набором данных, нам нужна немедленная обработка данных, и мы можем дождаться, пока программа сначала обработает весь набор данных.
В следующем примере мы реализуем итератор, который вызывает специальную функцию генератора. Ключевое слово yield возвращает текущее значение, переходя к следующему значению только на следующей итерации цикла.
- По возможности используйте встроенную библиотеку
Если мы используем методы, которые уже были предопределены в библиотеке Python, импортируйте соответствующую библиотеку. Это сэкономит много места и времени. Мы также можем создать модуль, чтобы определить функцию и импортировать ее в текущую рабочую программу.
Заключение
Читайте также: