Как Numpy имеет дело с распределением памяти, когда передается в качестве аргументов или возвращается? - PullRequest
2 голосов
/ 21 января 2020

СЦЕНАРИЙ 1

Учитывая приведенный ниже код, запущенный в IDLE и Python3:

np.ones((1000,1000,1000), dtype=np.float64)

def func1(b):
    b = np.ones((1000,1000,1000), dtype=np.float32)

def func2(b):
    b = np.ones((1000,1000,1000), dtype=np.float32)
    return b

Вызов func1(a) приводит к короткому всплеску памяти, который немедленно освобождается сборщиком мусора однако, вызов func2(a) немедленно приведет к скачку памяти и останется там (пока явно не будет вызван gc.collect()), даже если возвращаемое значение не было присвоено какой-либо переменной. У меня нет других ссылок на это значение, доступное где-либо еще.

enter image description here

СЦЕНАРИЙ 2:

Упрощение:

def func1():
    b = np.ones((1000,1000,1000), dtype=np.float32)

def func2():
    b = np.ones((1000,1000,1000), dtype=np.float32)
    return b

def func3():
    return np.ones((1000,1000,1000), dtype=np.float32)

Тогда вызов func1() такой же, как и в предыдущем сценарии, скачок памяти и ее немедленное освобождение. Вызовы func2() и func3() вообще не выделяются памяти , что противоположно первому сценарию.

Что происходит под капотом, чтобы объяснить это поведение выделения памяти? Как оператор return влияет на распределение?

1 Ответ

2 голосов
/ 21 января 2020

Вы упомянули, что работаете в IDLE.

Интерактивный сеанс сохранит ссылку на последнее возвращенное значение в переменной _, что означает, что ваш массив numpy имеет счетчик ссылок, предотвращающий его от собирать немедленно. Удаление builtins._ должно освободить память.

См. sys.displayhook документы для получения дополнительной информации.

...