Я запускаю процесс импорта данных Java на 32-разрядной машине с ядром Ubuntu 10 PAE. После запуска процесса на некоторое время, oom-killer удаляет мой Java-процесс. После некоторого поиска в Google и документации выяснилось, что в системе заканчивается LowMem. Я запустил процесс в третий раз и смотрю free -lm
Покажи мне Low: 464 386 77
при этом свободное значение (77 МБ) медленно уменьшается.
Почему у меня заканчивается lowmem и как его увеличить?
Некоторые детали:
$ cat /proc/sys/vm/lowmem_reserve_ratio 256 256 32 $ free -lm total used free shared buffers cached Mem: 32086 24611 7475 0 0 24012 Low: 464 407 57 High: 31621 24204 7417 -/+ buffers/cache: 598 31487 Swap: 2047 0 2047
Проблема в том, что многие структуры данных ядра, такие как дескрипторы страниц (одна структура на каждую страницу размером 4 КБ в системе), должны находиться в нехватке памяти. По мере того как общий объем памяти в машине увеличивается, требуется все больше и больше низкой памяти, и в конечном итоге низкая память становится очень дефицитным ресурсом.
IIRC обычное практическое правило состоит в том, что общий объем 16 ГБ - это примерно верхний разумный предел для 32-разрядного ядра. С этим мало что можно сделать.
Вы можете попытаться загрузиться с меньшим объемом памяти (mem = параметр командной строки ядра). Но реальное решение - перейти на 64-битное ядро.
В этом отношении управление памятью в Linux оставляет желать лучшего. Потребуется первый 4G памяти и разделит их на 3/1. 1 ГБ - это LowMem. С 32 ГБ памяти в системе уже потребуется значительная часть этого 1 ГБ для адресации. В течение 2,4 дней шла дискуссия о том, чтобы приложить некоторые усилия, чтобы сделать это ограничение настраиваемым или интегрировать патч 4G / 4G, однако ничего из этого не произошло, поскольку Линус не видел в этом необходимости, и все было и без того уродливые, не говоря уже о том, что 4G / 4G тоже некрасивы. Для 2.6 все еще существует патч 4g, но изначально он был написан для 2.6.6, которая сегодня очень устарела. К версии 2.6.7 было довольно ясно, что она никогда не будет объединена, накладные расходы на ее производительность в любом случае были гигантскими, поэтому было принято решение, что система виртуальных машин и так достаточно хороша. Таким образом, на 32-битной версии, вероятно, нет никакого способа обойти эту проблему, поскольку система памяти просто не предназначена для масштабирования до таких объемов памяти.
С другой стороны, на 64-битной версии адресация значительно изменилась, поэтому здесь вы не найдете этой проблемы.
Что ж, не уверен, прав ли я, размер нехватки памяти - это один из параметров ядра. Я думаю, что из-за PAE один процесс не может превысить размер низкой памяти, но проверьте это http://www.makelinux.net/ldd3/chp-15-sect-1.shtml
Отключите oom killer и посмотрите, каков будет конечный результат. Также опубликуйте информацию об использовании памяти процессом, если применимо. Взгляните на вывод pmap, чтобы помочь расшифровать. Я запускал очень большие кучи Java под 64-битной RHEL5 и никогда не видел этой проблемы.