У меня есть компьютер с 128 ГБ ОЗУ, работающий под управлением Linux (3.19.5-200.fc21.x86_64). Однако я не могу выделить более 30 ГБ ОЗУ в одном процессе. Помимо этого, malloc
завершается с ошибкой:
#include <stdlib.h>
#include <iostream>
int main()
{
size_t gb_in_bytes = size_t(1)<<size_t(30); // 1 GB in bytes (2^30).
// try to allocate 1 block of 'i' GB.
for (size_t i = 25; i < 35; ++ i) {
size_t n = i * gb_in_bytes;
void *p = ::malloc(n);
std::cout << "allocation of 1 x " << (n/double(gb_in_bytes)) << " GB of data. Ok? " << ((p==0)? "nope" : "yes") << std::endl;
::free(p);
}
}
Это приводит к следующему выводу:
/tmp> c++ mem_alloc.cpp && a.out
allocation of 1 x 25 GB of data. Ok? yes
allocation of 1 x 26 GB of data. Ok? yes
allocation of 1 x 27 GB of data. Ok? yes
allocation of 1 x 28 GB of data. Ok? yes
allocation of 1 x 29 GB of data. Ok? yes
allocation of 1 x 30 GB of data. Ok? yes
allocation of 1 x 31 GB of data. Ok? nope
allocation of 1 x 32 GB of data. Ok? nope
allocation of 1 x 33 GB of data. Ok? nope
allocation of 1 x 34 GB of data. Ok? nope
Я искал довольно давно и обнаружил, что это связано с максимальным размером виртуальной памяти:
~> ulimit -all
[...]
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
virtual memory (kbytes, -v) 32505856
[...]
Я могу увеличить этот предел до ~ 64 ГБ через ulimit -v 64000000
, но не дальше. Помимо этого, я получаю ошибки operation not permitted
:
~> ulimit -v 64000000
~> ulimit -v 65000000
bash: ulimit: virtual memory: cannot modify limit: Operation not permitted
~> ulimit -v unlimited
bash: ulimit: virtual memory: cannot modify limit: Operation not permitted
Еще один поиск показал, что в принципе можно установить эти ограничения через запись "как" (адресное пространство) в /etc/security/limits.conf
. Однако, делая это, я мог только уменьшить максимальное количество виртуальной памяти, а не увеличивать ее.
Есть ли способ полностью снять этот лимит виртуальной памяти на один процесс или увеличить его за пределы 64 ГБ? Я хотел бы использовать всю физическую память в одном приложении.
EDIT:
-
После Ingo Leonhardt я пробовал
ulimits -v unlimited
после входа в систему как root, а не как обычный пользователь. Это решает проблему для root (программа может затем распределить всю физическую память, запустив ее как root). Но это работает только для root, а не для других пользователей. Однако, по крайней мере, это означает, что в принципе ядро может справиться с этим просто отлично, и что есть только проблема с конфигурацией. -
Относительно
limits.conf
: я попытался явно добавить- жесткий как неограниченный
- soft как неограниченный
до
/etc/security/limits.conf
и перезагрузка. Это не имело никакого эффекта. После входа в качестве стандартного пользователяulimit -v
все еще возвращает около 32 ГБ, аulimit -v 65000000
все еще говоритpermission denied
(покаulimit -v 64000000
работает). Остальная частьlimits.conf
закомментирована, а в/etc/security/limits.d
имеется только одна другая несвязанная запись (ограничениеnproc
до 4096 для пользователей без полномочий root). То есть ограничение виртуальной памяти должно происходить от другого места, кромеlimits.conf
. Любые идеи, что еще может привести кulimits -v
не "неограниченному"?
ИЗМЕНИТЬ/Решение:
-
Это было вызвано моей собственной глупостью. У меня была (давно забытая) программа в моей пользовательской настройке, которая использовала
setrlimit
, чтобы ограничить объем памяти для каждого процесса, чтобы не допустить замены Linux. Он был непреднамеренно скопирован с 32-гигабайтной машины на 128-гигабайтную машину. Спасибо Полю и Эндрю Янке и всем остальным за то, что они помогли отследить его. Извините всех:/. -
Если кто-то еще сталкивается с этим: найдите
ulimit/setrlimit
в настройках bash и профиля, а также программы, потенциально вызывающие их (как ваши собственные, так и общесистемные /etc ) и убедитесь, что/security/limits.conf
не включает этот предел... (или, по крайней мере, попробуйте создать нового пользователя, чтобы убедиться, что это происходит в вашем пользователе или в настройке системы)