LINUX.ORG.RU

[embedded][системщина] errno=Cannot allocate memory, но памяти достаточно


0

1

Отчего это может быть? В системе 64 МБ памяти, программа по показаниям htop занимает обычно не больше 40%, ulimit'ы выставлены по максимуму:

# ulimit -a
-f: file size (blocks)             unlimited
-t: cpu time (seconds)             unlimited
-d: data seg size (kb)             unlimited
-s: stack size (kb)                unlimited
-c: core file size (blocks)        unlimited
-m: resident set size (kb)         unlimited
-l: locked memory (kb)             unlimited
-p: processes                      unlimited
-n: file descriptors               10240
-v: address space (kb)             unlimited
-w: locks                          unlimited
-e: scheduling priority            0
-r: real-time priority             0

В настоящее время мне известно 2 варианта как можно «доканать» программу:

1) У меня настроен небольшой скрипт /proc/sys/kernel/hotplug и я заставляю ядро вызывать этот скрипт десятки раз, пока не получу ошибку

2) Корень на nfs, сохраняется много отладочных данных. Было подозрение, что это nfs как-то что-то кеширует, пока сегодня не узнал про способ 1.

Так на всякий случай

# free
             total         used         free       shared      buffers
Mem:         61212        36604        24608            0          736
-/+ buffers:              35868        25344
Swap:            0            0            0

# cat /proc/meminfo 
MemTotal:        61212 kB
MemFree:         16728 kB
Buffers:           736 kB
Cached:          15972 kB
SwapCached:          0 kB
Active:          24948 kB
Inactive:        13144 kB
SwapTotal:           0 kB
SwapFree:            0 kB
Dirty:               0 kB
Writeback:           0 kB
AnonPages:       21412 kB
Mapped:           8480 kB
Slab:             2592 kB
SReclaimable:      724 kB
SUnreclaim:       1868 kB
PageTables:        856 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:     30604 kB
Committed_AS:    91180 kB
VmallocTotal:   581632 kB
VmallocUsed:     33180 kB
VmallocChunk:   540668 kB


при монтировании NFS ведь можно отключить опции кэширования? и еще, какой проц? есть ли флэшка чтобы swap на ней забабахать? а еще я слышал про swap через NFS, правда так и не осилил заставить это работать...

кста, не знаю, может поможет, удобно использовать sshfs для расшаривания каталогов с host-pc, сборки в них, работы с ними и т.п.

а еще я извращенец, юзал SAMBA для embedded чтобы файлами обмениваться, но sshfs существенно проще и без проблем

I-Love-Microsoft ★★★★★ ()

В системе 64 МБ памяти

Committed_AS: 91180 kB

Честно говоря, не понимаю, как у тебя вообще что-то работает и что значат твои слова «памяти достаточно».

tailgunner ★★★★★ ()
Ответ на: комментарий от anonymous

а сколько тебе на embedded памяти нужно?

Сколько нужно мне, я знаю. Сколько нужно ТС - не знаю, но, судя по Committed_AS, ему нужно явно больше, чем у него есть.

tailgunner ★★★★★ ()
Ответ на: комментарий от vertexua

Стандартными средствами отключить шифрование в OpenSSH нельзя. Из рабочих вариантов предлагается накатывать HPN-SSH патч. В большинстве случаев проще рядом иметь rsync.

BigAlex ★★★ ()
Ответ на: комментарий от I-Love-Microsoft

и еще, какой проц?

PXA270

есть ли флэшка чтобы swap на ней забабахать?

Можно. И бабахал. Но это не решение проблемы. Я хочу, чтобы моя программа как бы стабильно работала.

кста, не знаю, может поможет, удобно использовать sshfs для расшаривания каталогов с host-pc, сборки в них, работы с ними и т.п.

Так у меня для этого nfs же. И шифрование мне тут не нужно. Ну и ядро умеет грузиться по nfs, чего о ssh я на вскидку не скажу.

юзал SAMBA для embedded чтобы файлами обмениваться

Я тоже так делал по первости, пока не осилил nfs.

gogi ()
Ответ на: комментарий от tailgunner

Ну free же пишет, что достаточно. Ещё, когда я программу «убаюкиваю», она продолжает висеть в памяти. И я могу продолжать её занимать чем-нибудь другим.

gogi ()
Ответ на: комментарий от tailgunner

Committed_AS

Что это? И почему мне тогда free, top и прочие htop'ы показывают, что половина памяти свободна?

ему нужно явно больше, чем у него есть.

Ну это вообще сборка отладочная. Релизная будет явно худее. Но если проблема не ясна, есть шанс, что она останется и в релизе. Этого и боюсь.

gogi ()
Ответ на: комментарий от gogi

Ну free же пишет, что достаточно

У тебя Committed_AS больше объема памяти - это нормально? Я так понимаю, у тебя включен overcommitment - не лучшая идея для встраиваемой системы.

Ещё, когда я программу «убаюкиваю»

Мде. Описание симптомов, конечно, потрясающе точное. «Вызывать этот скрипт десятки раз, пока не получу ошибку», «убаюкиваю программу». Сколько памяти ты запрашиваешь, когда получаешь ошибку? Какой размер программа имеет в этот момент?

tailgunner ★★★★★ ()
Ответ на: комментарий от yoghurt

Возможно, фрагментация

Интересно, как это можно проверить? И сделать дефрагментацию? Программе нужно выделить от силы пару мегабайт из свободных 30. Не такой уж и большой непрерывный блок. Да и ядро, ЕМНИП, смежные страницы виртуальной памяти может выделять из несмежных блоков физической.

gogi ()
Ответ на: комментарий от gogi

Committed_AS

Что это?

ахаха, Ъ-ембеддед быдлокодеры в треде, все в машину!

anonymous ()
Ответ на: комментарий от tailgunner

У тебя Committed_AS больше объема памяти - это нормально? Я так понимаю, у тебя включен overcommitment - не лучшая идея для встраиваемой системы.

Если честно, я про это пока вообще не в курсе. Завтра с утра на свежую голову займусь гуглежом.

Мде. Описание симптомов, конечно, потрясающе точное. «Вызывать этот скрипт десятки раз, пока не получу ошибку», «убаюкиваю программу».

Ну извини, код привести не могу. Его много и всё не по делу будет. Да и кто такие простыни читать будет? Про скрипт напишу подробнее. То, что прописано в /proc/sys/kernel/hotplug вызывает ядро при наступлении какого либо hotplug'а. В моём случае - это подключение/отключение usb flash drive в usb-порт. А скрипт уже посылает сигнал программе. Костыльно, но я когда это делал не знал про netlink.

«Вызывать скрипт десятки раз» - это значит сижу и дрючу флешку туда-сюда. Вот такой вот тест-кейз. При получении сигнала программа кое-что делает, требующее выделения-освобождения памяти. И вот однажды память выделяться перестаёт. Вот тут я и наблюдая ошибку в логе. Но программа остаётся жива. С ней я ничего не делаю и в соседней консольке смотрю что же у меня с памятью происходит.

gogi ()
Ответ на: комментарий от gogi

У тебя Committed_AS больше объема памяти - это нормально? Я так понимаю, у тебя включен overcommitment - не лучшая идея для встраиваемой системы.

Если честно, я про это пока вообще не в курсе.

Стань в угол и покрасней. http://www.redhat.com/advice/tips/meminfo.html Documentation/vm/overcommit-accounting

А скрипт уже посылает сигнал программе. Костыльно, но я когда это делал не знал про netlink.

Это как раз не костыльно.

Ну извини, код привести не могу. Его много и всё не по делу будет

Код не нужен, нужно описание того, что он делает.

Вызывать скрипт десятки раз" - это значит сижу и дрючу флешку туда-сюда. Вот такой вот тест-кейз. При получении сигнала программа кое-что делает, требующее выделения-освобождения памяти.

Т.е. описание сводится к «программа не может выделить память», а скрипт, в общем, не причем. Вопросы по поводу программы я уже задал.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Стань в угол и покрасней. http://www.redhat.com/advice/tips/meminfo.html Documentation/vm/overcommit-accounting

Благодарствую. Похоже ситуация проясняется. Завтра как доберусь до железки буду попробовать. А вообще даже и не задумывался, что тут надо что-то подкручивать. Как ни посмотрю во free - вроде запас ещё ого-го.

Вопросы по поводу программы я уже задал.

Почти всегда большая часть занятой памяти - это память под программу. По free в момент отказа это ~ 30-35 Мб. После холодного старта - это примерно 20 Мб. Ничего криминального здесь не вижу.
Перед отказом запрашиваю от силы мегабайта 2.

gogi ()
Ответ на: комментарий от gogi

Почти всегда большая часть занятой памяти - это память под программу. По free в момент отказа это ~ 30-35 Мб

Если эта фраза означает «в момент неудачного запроса на выделение памяти программа занимает 30-35М», то это значение близко к CommitLimit.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

т.е.

sudo cat 100 > /proc/sys/vm/overcommit_ratio

решит проблему?

а почему ничего не отваливалось, когда я на 4х гиговой машине гонял 3+ гига данных на процесс, при этом vm.overcommit_ratio не трогал?

gunja ()
Ответ на: комментарий от gunja

и в догонку ответ на мой вопрос:

согласно документации, vm.overcommit_ratio учитывается, только если задействован строгий учёт перезапроса памяти (режим 2 vm.overcommit_memory ).

т.е. на машинах у меня стояло значение vm.overcommit_memory =0, что позволяло выделять памяти пока физическая не закончится?

а ТС нужно проверить значение vm.overcommit_memory и выставить его в 0, или сменить overcommit_ratio в сотню?

gunja ()
Ответ на: комментарий от gunja

sudo cat 100 > /proc/sys/vm/overcommit_ratio решит проблему?

При меньше 100 у меня программа вообще не запускается с надписью «killed».

При 100 стартанула с такой раскладкой

CommitLimit:     61212 kB
Committed_AS:    58808 kB

А потом сюрприз (ещё даже до моих тестов)

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Segmentation fault (core dumped)

а ТС нужно проверить значение vm.overcommit_memory и выставить его в 0, или сменить overcommit_ratio в сотню?

vm.overcommit_memory у меня по дефолту был 0. Выставил 2.

т.е. на машинах у меня стояло значение vm.overcommit_memory =0, что позволяло выделять памяти пока физическая не закончится?

Кажется даже больше физической.

gogi ()
Ответ на: комментарий от gogi

Кстати, не понятно откуда это взялось

new всегда для положительных чисел? всегда при попытке выделить память её достаточно?

вод бы всё же стоило вскрыть. а то очень чудно получается. при vm.overcommit_memory = 0 у вас было около 90М памяти выделено на 64М физики

gunja ()
Ответ на: комментарий от gunja

new всегда для положительных чисел? всегда при попытке выделить память её достаточно?

Думаю что да.

вод бы всё же стоило вскрыть. а то очень чудно получается. при vm.overcommit_memory = 0 у вас было около 90М памяти выделено на 64М физики

Я кажется немного разобрался: у меня памяти не хватает в момент форка. Объём виртуальной памяти как бы удваивается и тут происходит отказ.

Вот ещё нашёл по теме, практически моя ситуация: https://bugreports.qt.nokia.com/browse/QTBUG-17331

gogi ()
Ответ на: комментарий от gunja

Нет. Но высокий overcommit ratio может только замаскировать проблему (что выйдет боком впоследствие).

Отключенный overcommit накладывает ограничения, но дает предсказуемость.

tailgunner ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.