Форкинг и вопрос выделения памяти
Я унаследовал сценарий Perl, который запускается на экземпляре EC2, который в основном сканирует кучу URL-адресов для данных (также называемый анализом). Этот сценарий вызывается через сценарий оболочки, который разветвляется на несколько таких сценариев perl. В любой момент могут быть запущены сотни этих Perl-сценариев, в зависимости от процесса очистки.
Каждый скрипт Perl делает это:
## create a temporary hash to hold everything ##
my %products = ();
и, как вы можете себе представить, этот массив растет по мере того, как все больше продуктов очищается в рамках этого процесса.
Мой вопрос заключается в следующем: что происходит, когда Perl пытается добавить следующий продукт в массив 'product', а памяти недостаточно? Это просто ждет или умирает? Моя интуиция говорит мне, что он умирает, но как я могу использовать выделение памяти в стиле malloc, если он не может выделить память, которую он ждет?
Лучше ли просто ограничить количество дочерних процессов?
Любые идеи очень приветствуются.
ps Это perl, v5.10.1 (*), созданный для i486-linux-gnu-thread-multi
1 ответ
Не уверен насчет специфики Perl, но в других динамических языках, таких как Python, вы получите ошибку выделения памяти и последующий сбой вашей программы. Некоторые языки (включая Python) позволяют вам установить обработчик для условия, Perl, вероятно, делает то же самое.
Я не уверен, откуда вы взяли, что malloc ждет, когда он не может выделить память, реализация в Linux либо возвращает указатель, либо NULL, если запрос не выполняется.
Ситуация в Linux усложняется еще и тем, что Linux по умолчанию допускает перераспределение памяти. Например, если в вашей системе доступно 4 ГБ виртуальной памяти, у вас может быть несколько процессов, выделяющих почти 4 ГБ памяти. До тех пор, пока они не испортят распределение, память фактически используется. Если несколько процессов в конечном итоге делают это, они исчерпают фактическую доступную память, а процесс-убийца Out Of Memory запускает и убивает некоторые процессы.
Простым решением для вас будет просто посмотреть, сколько памяти используют ваши процессы, и разрешить запускать только определенное количество одновременно. Более сложные решения включают использование структур данных фиксированной длины, чтобы использование памяти было известно, или потоковую передачу результатов на диск либо напрямую, либо через буфер, чтобы сохранить низкое использование. Решение действительно зависит от приложения, и трудно предложить что-то более конкретное без подробностей его функции.