Задать вопрос
@r10d10

Не копятся ли строки в памяти при работе с python?

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

Тогда есть вопросы по примеру:

# Есть цикл
for string in parserList:
	
	#Парсим объект
	myData = requests.get()

	#Получаем текст
	html = myData.text

	#Делаем замену в тексте
	html = html.replace('rub', 'руб')


Вопросы:

1. Если строки не изменяемы, то значит ли это что при каждой итерации цикла myData и html накапливаются и занимают всё больше места в памяти?

2. Сборщик мусора запускается каждую итерацию цикла или он ждёт когда цикл закончится?

3. Если я делаю
html = html.replace('rub', 'руб')

То получается я утратил возможность обратиться к предыдущей версии переменной html при этом она осталась в памяти, т.е. я утратил возможность освободить память? Не выгоднее ли в этом случае сделать так:
html2 = html.replace('rub', 'руб')
del html
  • Вопрос задан
  • 114 просмотров
Подписаться 1 Простой 1 комментарий
Решения вопроса 2
Maksim_64
@Maksim_64
Data Analyst
Нет при такой конструкции, не копятся.

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

html (упрощенно это именованный указатель на адресс в памяти) = myData.text (сам объект)
html - это выполнится потом = myData.text - сначала выполнится эта часть кода. счетчик = 1
html = html.replace('rub', 'руб') сначала выполнится эта часть кода. счетчик = 1 при этом myData.text - счетчик для этого объекта стал 0, он уже навсегда потерян.

del html - сам по себе не удаляет объект, а понижает счетчик на один, что в свою очередь, если у объекта, только один именованный указатель приведет к удалению.

Это упрощенно, у этого есть свои нюансы, связанные с оптимизацией. Плюс в первую очередь для понимания поведения объектов надо учитывать мутабельность/не мутабельность.
Ответ написан
Комментировать
Vindicar
@Vindicar
RTFM!
Попробовал накидать скрипт для проверки:
import tracemalloc

tracemalloc.start()

for i in range(4):
    snapshotA = tracemalloc.take_snapshot()
    s = f'Строка №{i+1}'
    snapshotB = tracemalloc.take_snapshot()
    s = s.replace('Строка', 'Другая строка')
    snapshotC = tracemalloc.take_snapshot()
    print('>', s)
    statab = snapshotB.compare_to(snapshotA, 'lineno')
    print("[A->B]")
    for stat in statab[:10]:
        if stat.traceback[0].filename == __file__:
            print(stat)
    statbc = snapshotC.compare_to(snapshotB, 'lineno')
    print("[B->C]")
    for stat in statbc[:10]:
        if stat.traceback[0].filename == __file__:
            print(stat)

Если я верно интерпретирую вывод, неиспользуемые строки "умирают" на каждой итерации.
Но ситуация усложняется, если на них есть ссылки в других местах, особенно если имеют место циклические ссылки.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы