Python: потребление памяти накапливается в цикле while - PullRequest
0 голосов
/ 29 мая 2020

Сначала признание - здесь программист-новичок время от времени пишет сценарии. Я пытался вычислить потребление памяти для этого простого фрагмента кода, но не мог этого понять. Я попытался найти ответы на вопросы, но не понял. Я получаю данные json с помощью REST API, и приведенный ниже фрагмент кода потребляет много оперативной памяти. Я проверил диспетчер задач Windows, и потребление памяти постепенно увеличивается с каждой итерацией l oop. Я перезаписываю одну и ту же переменную для каждого вызова API, поэтому я думаю, что предыдущая переменная response должна быть перезаписана.

while Flag == True:
        urlpart= 'data/device/statistics/approutestatsstatistics?scrollId='+varScrollId
        response = json.loads(obj1.get_request(urlpart))
        lstDataList = lstDataList + response['data']
        Flag = response['pageInfo']['hasMoreData']
        varScrollId = response['pageInfo']['scrollId']
        count += 1
        print("Fetched {} records out of {}".format(len(lstDataList), recordCount))
        print('Size of List is now {}'.format(str(sys.getsizeof(lstDataList))))
    return lstDataList

Я пытался профилировать использование памяти, используя memory_profiler ... вот что это показывает

    92  119.348 MiB    0.000 MiB       count = 0
    93  806.938 MiB    0.000 MiB       while Flag == True:
    94  806.938 MiB    0.000 MiB           urlpart= 'data/device/statistics/approutestatsstatistics?scrollId='+varScrollId
    95  807.559 MiB   30.293 MiB           response = json.loads(obj1.get_request(urlpart))
    96  806.859 MiB    0.000 MiB           print('Size of response within the loop  is {}'.format(sys.getsizeof(response)))
    97  806.938 MiB    1.070 MiB           lstDataList = lstDataList + response['data']
    98  806.938 MiB    0.000 MiB           Flag = response['pageInfo']['hasMoreData']
    99  806.938 MiB    0.000 MiB           varScrollId = response['pageInfo']['scrollId']
   100  806.938 MiB    0.000 MiB           count += 1
   101  806.938 MiB    0.000 MiB           print("Fetched {} records out of {}".format(len(lstDataList), recordCount))
   102  806.938 MiB    0.000 MiB           print('Size of List is now {}'.format(str(sys.getsizeof(lstDataList))))
   103                                 return lstDataList

obj1 - это объект класса Cisco rest_api_lib. Ссылка на код здесь

Фактически программа потребляет ~ 1,6 ГБ ОЗУ. Данные, которые я получаю, содержат примерно 570 КБ записей. API ограничивает количество записей до 10 КБ за раз, поэтому l oop выполняется ~ 56 раз. Строка 95 кода потребляет ~ 30 МБ ОЗУ согласно выходу memory_profiler. Это как если бы каждая итерация потребляла 30M, заканчивая u на ~ 1.6G, так что примерно на том же уровне. Невозможно понять, почему потребление памяти продолжает накапливаться для l oop. Спасибо.

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

это как если бы каждая итерация потребляла 30M

Именно это и происходит. Вам нужно освободить память, которая вам не нужна, например, после того, как вы извлекли данные из ответа. Вы можете удалить его так:

del response

подробнее del

еще сборка мусора

0 голосов
/ 29 мая 2020

Я подозреваю, что это строка lstDataList = lstDataList + response['data']

Это накапливается response['data'] с течением времени. Кроме того, ваш отступ кажется неправильным, если он будет:

while Flag == True:
    urlpart= 'data/device/statistics/approutestatsstatistics?scrollId='+varScrollId
    response = json.loads(obj1.get_request(urlpart))
    lstDataList = lstDataList + response['data']
    Flag = response['pageInfo']['hasMoreData']
    varScrollId = response['pageInfo']['scrollId']
    count += 1
    print("Fetched {} records out of {}".format(len(lstDataList), recordCount))
    print('Size of List is now {}'.format(str(sys.getsizeof(lstDataList))))
return lstDataList

Насколько я могу судить, lstDataList будет продолжать расти с каждым запросом, что приводит к увеличению памяти. Надеюсь, это поможет, с пятницей!

...