У меня есть веб-приложение, которое использует хранилище данных Google, и после достаточного количества запросов у него не хватает памяти.
Я сузил это до запроса хранилища данных. Ниже приведено минимальное значение Po C, чуть более длинная версия , которая включает измерение памяти, на Github.
from google.cloud import datastore
from google.oauth2 import service_account
def test_datastore(entity_type: str) -> list:
creds = service_account.Credentials.from_service_account_file("/path/to/creds")
client = datastore.Client(credentials=creds, project="my-project")
query = client.query(kind=entity_type, namespace="my-namespace")
query.keys_only()
for result in query.fetch(1):
print(f"[+] Got a result: {result}")
for n in range(0,100):
test_datastore("my-entity-type")
Профилирование процесса RSS показывает рост примерно на 1 МБ за итерацию. Это происходит, даже если результаты не возвращаются. Ниже приведен вывод из моего списка Github:
[+] Iteration 0, memory usage 38.9 MiB bytes
[+] Iteration 1, memory usage 45.9 MiB bytes
[+] Iteration 2, memory usage 46.8 MiB bytes
[+] Iteration 3, memory usage 47.6 MiB bytes
..
[+] Iteration 98, memory usage 136.3 MiB bytes
[+] Iteration 99, memory usage 137.1 MiB bytes
Но в то же время Python ' mprof показывает плоский график (работает как mprof run python datastore_test.py
):
![mprof output for 100 Datastore fetches](https://i.stack.imgur.com/rg3Wl.png)
Вопрос
Я делаю что-то не так с тем, как я называю Datastore, или это вероятно основная проблема с библиотекой?
Среда Python 3.7.4 на Windows 10 (также протестирована на 3.8 на Debian в Docker) с google-cloud-datastore==1.11.0
и grpcio==1.28.1
.
Edit 1
Пояснение: это не типичное Python поведение распределителя, когда оно запрашивает память у ОС, но не освобождает ее сразу от внутренних арен / пулов. Ниже приведен график из Kubernetes, где работает мое уязвимое приложение:
![Memory usage graph from Kubernetes, showing a linear increase in memory usage as the process runs](https://i.stack.imgur.com/u3Dwf.png)
Это показывает:
- Линейный рост памяти до около 2 ГБ, где приложение фактически зависало из-за нехватки памяти (технически Kubernetes вытеснил модуль, но это не имеет значения).
- То же веб-приложение, которое работает, но не взаимодействует ни с GCP Storage, ни с Datastore.
- Взаимодействие только с добавленным хранилищем GCP (очень небольшой рост со временем, потенциально нормальный).
- Взаимодействие только с добавленным хранилищем данных GCP (значительно больший прирост памяти, около 512 МБ в час). Запрос хранилища данных точно такой же, как и код Po C в этом сообщении.
Редактировать 2
Чтобы быть абсолютно уверенным в Python ' Используя память, я проверил состояние сборщика мусора, используя g c. Перед выходом программа сообщает:
gc: done, 15966 unreachable, 0 uncollectable, 0.0156s elapsed
Я также принудительно собирал мусор вручную, используя gc.collect()
во время каждой итерации l oop, что не имело никакого значения.
Поскольку есть нет объектов, которые невозможно собрать, кажется маловероятным, что утечка памяти происходит от объектов, выделенных с помощью управления внутренней памятью Python. Поэтому более вероятно, что внешняя библиотека C вызывает утечку памяти.
Потенциально связана
Существует open grp c проблема я не уверен, что это связано, но у меня есть много общего с моей проблемой.