У меня есть конечная точка API D8, которая запрашивает определенный тип контента, применяет любые необязательные условия, преобразует результат в JSON и возвращает клиенту.Я обновил ограничение памяти PHP до 512M, и все еще работаю с ним.В Drupal всего 1500 записей, так что на самом деле не должно быть никаких причин, почему это так плохо (341 КБ на запись ?!).Если я просто продолжаю накачивать память, чтобы заставить ее работать, визуализированный JSON составляет менее 2 МБ.
Я знаю, что сборка мусора в PHP автоматическая, поэтому я предполагаю, что есть ссылки, которые хранятся.
Я предпринял несколько попыток сохранить его, например, пакетирование запросов, рефакторинг в функции и явный вызов gc_collect_cycles
, но ничего не изменилось.
Как сохранить потребление памяти при итерациипо результатам Drupal EntityQuery?
protected function get() {
echo "memory (start): " . memory_get_usage() . "\n<br>";
//some setup and validation
$query = $this->build_query($params);
echo "memory (build_query): " . memory_get_usage() . "\n<br>";
$results = $query->execute();
echo "memory (execute): " . memory_get_usage() . "\n<br>";
$items = [];
$chunk_size = 50;
$chunks = array_chunk(array_values($results), $chunk_size);
echo "memory (chunk): " . memory_get_usage() . "\n<br>";
foreach ($chunks as $chunk) {
$items = array_merge($items, $this->load_nodes($chunk));
echo "memory (chunk loaded): " . memory_get_usage() . "\n<br>";
}
echo "memory (all loaded): " . memory_get_usage() . "\n<br>";
$response = [ 'results' => $items ];
return new ResourceResponse($response);
}
protected function load_nodes($ids) {
$items = [];
$nodes = node_load_multiple($ids);
foreach ($nodes as $node) {
$items[] = $this->transform($node);
}
return $items;
}
protected function transform($array) {
$new = [
"field1" => $array['field1'],
"field2" => $array['field2'],
//... for about 30 more fields, with some processing/manipulation ...
];
return $new;
}
И вывод в отношении эхо-памяти:
память (начало): 28297032
память (build_query): 29984168
память (выполнение): 31004048
память (чанк): 31083864
память (чанк загружен): 42175976
память (чанк загружен): 50447792
память (загруженный чанк): 57609344
память (загруженный чанк): 66762688
память (загруженный чанк): 74555712
память (загруженный чанк): 86663016
память (загруженный чанк): 98514192
память (загруженный чанк): 110908336
память (загруженный чанк): 122792592
память (загруженный чанк): 134651328
память (загруженный чанк): 145622512
память (загруженный чанк): 156546072
память (загруженный чанк): 167805352
память (загруженный чанк): 178617040
память (загруженный чанк): 190400936
память (загруженный чанк): 201246256
память (загруженный чанк): 212387384
память (чанк загружен): 223756088
память (чанк загружен): 234898632
память (загруженный чанк): 246125624
память (загруженный чанк): 257136304
память (загруженный чанк): 268205304
память (загруженный чанк): 278744896
память (загруженный чанк): 289693184
память (загруженный чанк): 300491840
память (загруженный чанк): 310564624
память (загруженный чанк): 321204064
память (загруженный чанк): 333842760
память (загруженный чанк): 343723672
память (загруженный блок): 344960728
память (все загружено): 344960728
Не должно ли потребление памяти оставаться постоянным при каждой итерации load_nodes
какGC очищает старые ссылки?
Вы заметите, что моя конечная точка заканчивается только с 344 МБ.Фактически ошибка генерируется где-то в ядре Drupal.Поскольку я хочу сохранить максимальную память PHP на уровне 128 МБ, мне все еще нужно освободить часть памяти.