Рубрики
Без рубрики

Управление памятью в Python

Управление памятью – это процесс хранения памяти динамически и освобождает его, когда он не используется.

Автор оригинала: Pankaj Kumar.

Управление памятью – это процесс хранения памяти динамически и освобождает его, когда он не используется.

Понимание управления памятью в Python

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

Вывоз мусора

Коллекция мусора в Python – это процесс управления памятью для освобождения неиспользованной и нежелательной памяти для наших программ переводчика. В Python это делается автоматически.

Сборщик мусора находит объект, который не имеет ссылки на его, а затем удаляет этот объект из памяти кучи. Для этого Python использует алгоритм отсчета ссылок.

Пример:

class Python:

    def __init__(self):
        print('The object is created.')

    def __del__(self):
        print('The object is destroyed.')

obj1 = Python()
obj2 = obj1
obj3 = obj1
print("Set obj1 to None")
obj1 = None
print("Set obj2 to None")
obj2 = None
print("Set obj3 to None")
obj3 = None

Выход:

The object is created.
Set obj1 to None
Set obj2 to None
Set obj3 to None
The object is destroyed.

Здесь мы создали объект класса Python и передал свою ссылку на obj1, obj2, obj3 Отказ Это делает ссылку на счет этого объекта 3. Тогда, когда мы присваиваем эти ссылки на Нет Все ссылки из этого объекта удаляются и становятся 0. Поскольку нет никаких ссылок на объект, он разрушен сборщиком мусора Python, а метод __del __ () выполнен.

Отсчет ссылки

Подсчет ссылки в Python – это методика, в которой объект определяется из памяти, когда нет никаких ссылок, указывающих на него. Когда ссылочный счетчик становится ноль, объект удаляется.

У нас есть встроенная функция getrefcount () Присутствует в модуле Python sys который возвращает количество ссылок на данный объект Python.

Пример:

import sys
str = "Welcome to Python"
print(sys.getrefcount(str))

arr = []
arr.append(str) # appending to an array
print(sys.getrefcount(str))

dict = {}
dict['str'] = str # adding to a dictionary
print(sys.getrefcount(str))

arr = [] # resetting the array
sys.getrefcount(str)
dict['my_str'] = "Some other string"
print(sys.getrefcount(str))
 

Выход:

4
5
6
5

Значение ссылочного подсчета – это один высокий, чем то, что вы ожидаете, потому что он также считает, что объект, переданный в функции sys.getrefcount ().

Иногда ссылочный счетчик объекта никогда не достигает нуля. Это происходит потому, что объект относится к себе. Это называется Опорный цикл Отказ

Пример:

import sys
x = []
x.append(x) # x contains reference to itself
print("Reference count of object is",sys.getrefcount(x))

Выход:

Reference count of object is 3

Здесь создается объект X, который относится к себе. Ссылочный счет никогда не достигнет 0, так как у него есть собственная ссылка. Объект X будет занимать память, пока не вызывается сборщик мусора Python.

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

Выделение памяти

Чтобы понять распределение памяти, мы должны понимать память произвольного доступа (RAM). ОЗУ также называется основной памятью, которая позволяет хранить информацию и получить на компьютере.

В верхней части оперативной памяти у нас есть стек и внизу, у нас есть куча. Куча отвечает за хранение переменных/значений, а стек несет ответственность за проведение ссылок на объект в куче.

Куча

В Python, когда более одной переменных имеют одинаковое значение, вторая переменная, указывающая на исходное значение, создается в куче.

Пример:

x = 5
y = x 
if(id(x) == id(y)):
   print("x and y refer to the same object")

x = x+1
if(id(x) != id(y)):
    print("x and y refer to different objects")

z = 5
if(id(y) == id(y)):
   print("y and z refer to same memory")

Выход:

x and y refer to the same object
x and y refer to different objects
y and z refer to same memory

Есть два типа ассигнований памяти:

  • Распределение памяти стека
  • Распределение кучи памяти.

1. Распределение памяти стека

Распределение памяти стека – это хранение статической памяти внутри определенной функции или вызова метода. Когда функция называется, память хранится в стеке вызовов функций. Любые локальные инициализации переменных хранятся в стеке вызовов и удалены после возврата функции.

Итак, когда мы запуская нашу программу, все функции впервые хранятся в стеке вызовов, а затем удалены, когда функция возвращается.

Пример:

def func():
    #These initializations are stored in stack memory
    x = 10 
    y = "Apple"
     

2. Распределение кучи памяти

Распределение кучи памяти – это хранение памяти, которое необходимо вне конкретной функции или вызова метода. Эта память используется в программе в глобальном объеме.

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

В Python Geap Memory управляет самим интерпретатором, и пользователь не имеет контроля над ним.

Пример:

def func()
    #Allocates memory for 5 integers in heap memory
    x=[None]*5

Заключение

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

Рекомендации

Официальные документы