proba.c, malloc(), memset(), "Killed" ...
23 отговора
711 прегледа
proba.c, malloc(), memset(), "Killed" ...
мдаа
пускам си аз един цикъл, в който се маллоц()ва памет и вместо маллоц() да ми върне НУЛЛ и да разбера, че памет нема - програмката мре със съобщение (от киллъра й, подозирам) Killed! и толкоз! нема лабаво! защо умря не се разбира от тва Killed.
като задам малко по-малко да маллоц()не, колкото да успее, същата дивотия (т.е. Killed) се получава по някое време докато мемсет()вам успешно маллоц()натата памет (предполагах, че ще стане така, ама реших да се уверя).
=>
1. що така?
2. и като е така кво да праа, а (освен да го духам, примерно)?
Satan`s Defloration Incorporated
пускам си аз един цикъл, в който се маллоц()ва памет и вместо маллоц() да ми върне НУЛЛ и да разбера, че памет нема - програмката мре със съобщение (от киллъра й, подозирам) Killed! и толкоз! нема лабаво! защо умря не се разбира от тва Killed.
като задам малко по-малко да маллоц()не, колкото да успее, същата дивотия (т.е. Killed) се получава по някое време докато мемсет()вам успешно маллоц()натата памет (предполагах, че ще стане така, ама реших да се уверя).
=>
1. що така?
2. и като е така кво да праа, а (освен да го духам, примерно)?
Satan`s Defloration Incorporated
Бях чувал по едно време
че начинът да разбереш колко памет имаш не е с malloc докато ти върне NULL. Доколкото си спомням, Linux има агресивна стратегия за раздаване на памет и не ти гарантира 100%, че наистина malloc() ще ти върне фрагмент, който можеш да използваш _веднага_.
И точно в такава ситуация попадаш ти. Killed се случва, защото ядрото ти праща сигнал, който обаче ти не прехващаш; нещо като exception, който означава, че нещо не е съвсем в ред - в случая паметта. Не знам кой точно е сигнала, но можеш лесно да го разбереш, като си пуснеш програмата в ddd, например - той ще ти каже killed with signal колкото-е-там.
А ти защо искаш да разбереш колко памет имаш? Това при всички случаи е непостоянна информация - дори да установиш, че в момента имаш да кажем 100mb, точно преди да ги заемеш може да стане превключване към друг процес, който да хапне 10 от тях ...
Понякога седя и си мисля, а понякога само си седя ...
И точно в такава ситуация попадаш ти. Killed се случва, защото ядрото ти праща сигнал, който обаче ти не прехващаш; нещо като exception, който означава, че нещо не е съвсем в ред - в случая паметта. Не знам кой точно е сигнала, но можеш лесно да го разбереш, като си пуснеш програмата в ddd, например - той ще ти каже killed with signal колкото-е-там.
А ти защо искаш да разбереш колко памет имаш? Това при всички случаи е непостоянна информация - дори да установиш, че в момента имаш да кажем 100mb, точно преди да ги заемеш може да стане превключване към друг процес, който да хапне 10 от тях ...
Понякога седя и си мисля, а понякога само си седя ...
аз пък съм ***чел*** едно време
в една книга за програмиране в unix (за линукс не стана дума изобщо), че маллоц() не е това, което е - т.е. 1:1 на това, което ти спомена. това обаче не означава, че поведението на кърнъла трябва да е ЧАК ТОЛКОВА непочтително към юзърска програма.
целта да направя подобна проба беше съвсем друга. това, което се научих е чисто страничен ефект, при това неприятен:
1. хич не ми дреме колко памет имам - ако няма => маллоц() трябва да е == НУЛЛ !!!
(за справка - ман маллоц)
НУКЪДЕ в мана не се казва, че програмата ще умре ако няма памет! НОРМАЛНОТО е да отговори с НУЛЛ и аз да му бера грижа как да се оправя без допълнителната памет, която съм заявил. Щото в някои случаи и с по-малко памет ще се свърши работата, ако не те изхвърлят с ритници.
2. ако маллоц() успее => при опит за работа с тази памет аз ТРЯБВА да успея, макар и с некаф блоцкинг примерно.
в случая същността на питането ми е:
* КАК да си заявя памет, така че да няма Killed, а да има НУЛЛ и да бъде възможно нормално продължение ИЛИ нормално приключване на работата, което трябва да избера АЗ, а не кърнълна или който и да е друг, защото не може друг да знае дали мога или не да работя и без тази памет, която съм заявил.
в случая сигналите не ме устройват твърде. имах преди време проблеми със СИГ11 и така никой не можа да ми отговори как да разбера в кой от тхреадовете ми е проблема...
??????
Satan`s Defloration Incorporated
целта да направя подобна проба беше съвсем друга. това, което се научих е чисто страничен ефект, при това неприятен:
1. хич не ми дреме колко памет имам - ако няма => маллоц() трябва да е == НУЛЛ !!!
(за справка - ман маллоц)
НУКЪДЕ в мана не се казва, че програмата ще умре ако няма памет! НОРМАЛНОТО е да отговори с НУЛЛ и аз да му бера грижа как да се оправя без допълнителната памет, която съм заявил. Щото в някои случаи и с по-малко памет ще се свърши работата, ако не те изхвърлят с ритници.
2. ако маллоц() успее => при опит за работа с тази памет аз ТРЯБВА да успея, макар и с некаф блоцкинг примерно.
в случая същността на питането ми е:
* КАК да си заявя памет, така че да няма Killed, а да има НУЛЛ и да бъде възможно нормално продължение ИЛИ нормално приключване на работата, което трябва да избера АЗ, а не кърнълна или който и да е друг, защото не може друг да знае дали мога или не да работя и без тази памет, която съм заявил.
в случая сигналите не ме устройват твърде. имах преди време проблеми със СИГ11 и така никой не можа да ми отговори как да разбера в кой от тхреадовете ми е проблема...
??????
Satan`s Defloration Incorporated
Набарах го
Точно в man malloc:
# echo 2 > /proc/sys/vm/overcommit_memory
И си готов.
Ето ти го и целия коментар:
BUGS
By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. This is a really bad bug. In case it turns out that the system is out of memory, one or more processes will be killed by the infamous OOM killer. In case Linux is employed under circumstances where it would be less desirable to suddenly lose some randomly picked processes, and moreover the kernel version is sufficiently recent, one can switch off this overcommitting behavior using a command like
# echo 2 > /proc/sys/vm/overcommit_memory
See also the kernel Documentation directory, files vm/overcommit-accounting and sysctl/vm.txt.
Понякога седя и си мисля, а понякога само си седя ...
# echo 2 > /proc/sys/vm/overcommit_memory
И си готов.
Ето ти го и целия коментар:
BUGS
By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. This is a really bad bug. In case it turns out that the system is out of memory, one or more processes will be killed by the infamous OOM killer. In case Linux is employed under circumstances where it would be less desirable to suddenly lose some randomly picked processes, and moreover the kernel version is sufficiently recent, one can switch off this overcommitting behavior using a command like
# echo 2 > /proc/sys/vm/overcommit_memory
See also the kernel Documentation directory, files vm/overcommit-accounting and sysctl/vm.txt.
Понякога седя и си мисля, а понякога само си седя ...
Re: Набарах го
"In case Linux is employed under circumstances where it would be less desirable to suddenly lose some randomly picked processes"
Еее, това кефи :))) Интересно, кога би било 'more desirable' да умре случайно избран процес :)
Еее, това кефи :))) Интересно, кога би било 'more desirable' да умре случайно избран процес :)
Примерно
в ситуация, в която е невероятно (разбирай много малко вероятно) да ти свърши паметта и предпочиташ производителност. Да кажем - офис десктоп.
Освен това, не е задължително процесът да бъде убит с брадвата - той може да разбере какво се е случило по сигнала и да се спре по що-годе културен начин.
Наистина, не изглежда красиво, но досега на мен никога не ми се е случвало да ми свърши паметта, така че рискът наистина е малък. А човек така или иначе трябва да се оправя със сигналите и спокойно може да се приеме, че свършването на паметта е равносилно на SIGTERM. Достатъчно е да направиш така, че при умирането да не искаш памет и готово.
Понякога седя и си мисля, а понякога само си седя ...
Освен това, не е задължително процесът да бъде убит с брадвата - той може да разбере какво се е случило по сигнала и да се спре по що-годе културен начин.
Наистина, не изглежда красиво, но досега на мен никога не ми се е случвало да ми свърши паметта, така че рискът наистина е малък. А човек така или иначе трябва да се оправя със сигналите и спокойно може да се приеме, че свършването на паметта е равносилно на SIGTERM. Достатъчно е да направиш така, че при умирането да не искаш памет и готово.
Понякога седя и си мисля, а понякога само си седя ...
Re: overcommit_memory хич не е случайно .
Не знам за вас ама на мен през годините многократно ми се е случвало да се разправям със сървъри на които нещо е изяло всичката памет (разбирай целия RAM плюс Swap)
И в такива случаи утрепването на процеси е МНОГО по-добрия вориант!
Защото без този OOM трепач, който се появи в 2.4 ядрата положението е значително по-плачевно.
Когато паметта се свърши машината просто увисва в небитието. Ако имаш късмет може да видиш безумни стойности на load average от порядъка на 70-90 и то "по принцип" всичко си работи само дето е безкрайно бавно.
Връщането на един PING пакет примерно може да отнеме към 20 минути.
Та без overcommit_memory изходът е САМО ЕДИН а именно да дръпнеш щепсела от контакта .... следва рестартиране, проверка на дискове, оправяне на купища проблеми и т.н.
Определено утрепването на един или повече сървъри е МНОГО по-добрият вариант. В най-лошия случай губиш нещата на този само сървър, но спасяваш машината като цяло
salle.online.bg/sig
И в такива случаи утрепването на процеси е МНОГО по-добрия вориант!
Защото без този OOM трепач, който се появи в 2.4 ядрата положението е значително по-плачевно.
Когато паметта се свърши машината просто увисва в небитието. Ако имаш късмет може да видиш безумни стойности на load average от порядъка на 70-90 и то "по принцип" всичко си работи само дето е безкрайно бавно.
Връщането на един PING пакет примерно може да отнеме към 20 минути.
Та без overcommit_memory изходът е САМО ЕДИН а именно да дръпнеш щепсела от контакта .... следва рестартиране, проверка на дискове, оправяне на купища проблеми и т.н.
Определено утрепването на един или повече сървъри е МНОГО по-добрият вариант. В най-лошия случай губиш нещата на този само сървър, но спасяваш машината като цяло
salle.online.bg/sig
Re: Примерно
Хм, не ми се вижда културно. Много бих се объркал, ако програма в която не заделям явно памет (примерно използвам std::vector) гърми мистериозно. Поне да ме замери с bad_alloc. А това, че ситуацията е почти невероятна само прави бъга по-трудно откриваем.
Re: overcommit_memory хич не е случайно .
Едно нещо не разбрах - искам памет - ОС-а казва - на, пък после ме утрепва.
Не може ли просто да каже - няма?
Не може ли просто да каже - няма?
Re: Примерно
Има само една малка подробност -- в общия случай ООМ killer-a изпраща SIGKILL, а не SIGTERM. SIGKILL не можеш да игнорираш.
Справка: mm/oom_kill.c (__oom_kill_task).
Справка: mm/oom_kill.c (__oom_kill_task).
проблем 2 сякаш изчезна, но Killed си е Killed...
Значи, флага влияе само върху това заделената памет да си бъде наистина заделена. Ако обаче паметта свърши - нанайци. Killed.
На всичкото отгоре самия стринг Killed така и не го намирам къде е! Търсих в цялото дърво на 2.4.26 и на 2.6.7. В oom_kill.c има друго:
a не простичкото "Killed".
Другата тайна и загадка, която се появи е, че в .config # CONFIG_OOM_KILLER is not set, и въпреки това не процеса си мре.
Наистина ли няма начин malloc() да връща НУЛЛ???????? Все пак една от линукските идеи беше, че човек трябва да може да си настрои нещоситам както си иска.
Satan`s Defloration Incorporated
На всичкото отгоре самия стринг Killed така и не го намирам къде е! Търсих в цялото дърво на 2.4.26 и на 2.6.7. В oom_kill.c има друго:
void oom_kill_task(struct task_struct *p)
{
printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm);
...
...
a не простичкото "Killed".
Другата тайна и загадка, която се появи е, че в .config # CONFIG_OOM_KILLER is not set, и въпреки това не процеса си мре.
Наистина ли няма начин malloc() да връща НУЛЛ???????? Все пак една от линукските идеи беше, че човек трябва да може да си настрои нещоситам както си иска.
Satan`s Defloration Incorporated
killed...
според мен го изтърсва bash или който там ти е пуснал програмчето.
А дали малок може да върне 0 - ако се позадълбаеш в него, ще видиш.
remember, there is no fork()
А дали малок може да върне 0 - ако се позадълбаеш в него, ще видиш.
remember, there is no fork()
Re: проблем 2 сякаш изчезна, но Killed си е Killed...
При мен malloc работи правилно при vm.overcommit_memory=2. С коя версия на ядрото тестваш?
Re: killed...
abe сега съм се задълбочил над миене на бебешки задник и прочее...
Satan`s Defloration Incorporated
Satan`s Defloration Incorporated
Re: проблем 2 сякаш изчезна, но Killed си е Killed
2.4.26 => Killed независимо дали е 0 или каквото и да е там
2.6.7 => Segmentation fault при достигане на заветните 50%
бтв, от каквото пише доковете се оказва, че поведението на 2.4 трябва да е различно от на 2.6 при 0, 1, 2.
Satan`s Defloration Incorporated
2.6.7 => Segmentation fault при достигане на заветните 50%
бтв, от каквото пише доковете се оказва, че поведението на 2.4 трябва да е различно от на 2.6 при 0, 1, 2.
Satan`s Defloration Incorporated
Re: overcommit_memory хич не е случайно .
в случая става дума за компютърчето вкъщи и за момента освен мен няма кой да псува ако започне да се мотае от недостиг на памет.
Satan`s Defloration Incorporated
Satan`s Defloration Incorporated
Re: проблем 2 сякаш изчезна, но Killed си е Killed
При мен на 2.6.5 следната програмка:
отпечатва 30-ина точки и накрая null без никакви segfaults.
int main() {
while (1) {
void *p = malloc(10 * 1024 * 1024);
if (!p) {
printf("null\n");
return 0;
}
printf(".");
fflush(stdout);
memset(p, 0, 10 * 1024 * 1024);
}
}
отпечатва 30-ина точки и накрая null без никакви segfaults.
Re: проблем 2 сякаш изчезна, но Killed си е Killed
При мен на 2.6.7
..............................................................Killed
а при
# echo 2 > /proc/sys/vm/overcommit_memory
.................................................null
..............................................................Killed
а при
# echo 2 > /proc/sys/vm/overcommit_memory
.................................................null
Re: проблем 2 сякаш изчезна, но Killed си е Killed
# CONFIG_OOM_KILLER
не изключва "трепача" напълно само му променя навиците.
"This option selects the kernel behaviour during total out of memory condition. The default behaviour is to, as soon as no freeable memory and no swap space are available, kill the task which tries to allocate memory. The default behaviour is very reliable. If you select this option, as soon as no freeable memory is available, the kernel will try to select the 'best' task to be killed."
т.е. без тази опция се трепе последния процес, който иска памет а със нея "най-добрия" за целта. По моите наблюдения това е този, който е захапал най-много памет.
salle.online.bg/sig
не изключва "трепача" напълно само му променя навиците.
"This option selects the kernel behaviour during total out of memory condition. The default behaviour is to, as soon as no freeable memory and no swap space are available, kill the task which tries to allocate memory. The default behaviour is very reliable. If you select this option, as soon as no freeable memory is available, the kernel will try to select the 'best' task to be killed."
т.е. без тази опция се трепе последния процес, който иска памет а със нея "най-добрия" за целта. По моите наблюдения това е този, който е захапал най-много памет.
salle.online.bg/sig