Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> При заполнении ОЗУ близко к максимуму, падает при обращении к памяти 
V
    Опции темы
georain
Дата 13.11.2008, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Linux HSLab 2.6.25-gentoo-r7
x86_64
AMD Athlon 64
4Gb RAM

При выделении максимально доступной памяти в последних блоках при заполнении программа падает. В дебаге не сообщается о seg.fail, а просто процесс заканчивается, память освобождается, а управление не возвращается.

Вот простой код:
Код

// с какого размера начать выделять память
static const size_t bytes_start = size_t(1024)*size_t(1024)*size_t(10000);
// каким размером закончить
static const size_t bytes_end = 1024*1024;
// сколько раз пытаться
static const size_t n = 1000;
// счётчик полного размера
static size_t full = 0;

// блоки памяти
struct Al{

    Al(): s(0), arr(0){

        // пытаемся выделить скока можем
        for(size_t b = bytes_start; b > bytes_end; b /= 2){
            s = b;
            arr = new(nothrow) uint8[b];
            if( arr != 0) break;
        };

        cout << "Al created with " << s << " bytes"<< endl;
        if (arr == 0) return;
        // заполняем
        for(size_t i = 0; i < s; ++i){
            arr[i] = static_cast<uint8>(i);
        };

        full += s;
        cout << "full Mb= " << full/(1024*1024) << endl;
    };
    ~Al(){
        delete[] arr; // vTictor спасибо
        cout << "Al deleted" << endl;
    };

    size_t s;
    uint8 * arr;
};

int main(){
    Al h[n];
    if(h){};

    cout << "full Mb= " << full/(1024*1024) << endl;
};


Вот вывод:
Код

Al created with 2621440000 bytes
full Mb= 2500
Al created with 655360000 bytes
full Mb= 3125
Al created with 81920000 bytes
full Mb= 3203
Al created with 40960000 bytes
full Mb= 3242
Al created with 20480000 bytes

Press ENTER to continue.


В дебаге вывод меньше:
Код

Al created with 2621440000 bytes
full Mb= 2500
Al created with 655360000 bytes
full Mb= 3125
Al created with 81920000 bytes
full Mb= 3203
Al created with 40960000 bytes
full Mb= 3242
Al created with 20480000 bytes

:((((

Падает здесь:
Код

        // заполняем
        for(size_t i = 0; i < s; ++i){
            arr[i] = static_cast<uint8>(i);
        };


Это сообщение отредактировал(а) georain - 13.11.2008, 16:53
PM MAIL   Вверх
GrayCardinal
Дата 13.11.2008, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 3039
Регистрация: 9.11.2003

Репутация: 8
Всего: 58



georain, 
Наверно своп отключен или маленький

Добавлено через 2 минуты и 42 секунды
А вообще линь при нехватке памяти имеет право погасить любую прогу smile

Добавлено через 4 минуты и 55 секунд
И я не догнал, с какого боку там "struct" ?
struct Al{


--------------------
PM MAIL WWW   Вверх
georain
Дата 13.11.2008, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Цитата(GrayCardinal @  13.11.2008,  13:52 Найти цитируемый пост)
Наверно своп отключен или маленький

Да своп отключен, это не должно влиять

Цитата(GrayCardinal @  13.11.2008,  13:52 Найти цитируемый пост)
А вообще линь при нехватке памяти имеет право погасить любую прогу

А что это да за нахальство такое? Не хватает памяти, возвращай ноль, как обычно.


Цитата(GrayCardinal @  13.11.2008,  13:52 Найти цитируемый пост)
И я не догнал, с какого боку там "struct" ?
struct Al{ 

Да какая тут разница то...? smile
PM MAIL   Вверх
georain
Дата 13.11.2008, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Я кажется понял, ядро память выделяет, выделяет, отдаёт всё что есть, а потом она ему самому становится нужна, и оно грохает прогу. Если так, то почему именно эту, и как интересно съедать именно столько, чтобы не падало?
PM MAIL   Вверх
destrd
Дата 13.11.2008, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 1.10.2008

Репутация: нет
Всего: 4



Цитата(georain @  13.11.2008,  14:06 Найти цитируемый пост)
Да своп отключен, это не должно влиять

всё правильно, убивает процесс который сожрал всю память. Вы о других то подумали?smile Может у вас там у течка памяти.
--------------------
Some people, when confronted with a problem, think, "I known, I'll use regular expressions." Now they have two problems.        -- Jamie Zawinski in comp.lang.emacs
PM MAIL ICQ   Вверх
georain
Дата 13.11.2008, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Ну хорошо, а как тогда написать программу которая бы корректно работала? Пусть мне надо памяти очень много, но если больше не дают, обойдусь чем есть.

Точнее так: взять у системы максимально много памяти, но не упасть.

Это сообщение отредактировал(а) georain - 13.11.2008, 14:47
PM MAIL   Вверх
destrd
Дата 13.11.2008, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 1.10.2008

Репутация: нет
Всего: 4



Цитата(georain @  13.11.2008,  14:36 Найти цитируемый пост)
Если так, то почему именно эту, 

Потому что она всё сожралаsmile

Добавлено через 7 минут и 55 секунд
Цитата(georain @  13.11.2008,  14:44 Найти цитируемый пост)
Точнее так: взять у системы максимально много памяти, но не упасть.

Ну попробуйте 
Код

int main(){
  try{
    Al h[n];
    if(h){};
}
catch(...)
{
  std::cerr<<"Кончилась память"<<std::endl;
}
    cout << "full Mb= " << full/(1024*1024) << endl;
};

Ну и убрать nothrow при выделении памяти.

Добавлено через 11 минут и 11 секунд
Хотя врядли это поможет, ядро всё равно может кильнуть
--------------------
Some people, when confronted with a problem, think, "I known, I'll use regular expressions." Now they have two problems.        -- Jamie Zawinski in comp.lang.emacs
PM MAIL ICQ   Вверх
vTictor
Дата 13.11.2008, 14:57 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 13.2.2008

Репутация: нет
Всего: нет



Код

        // заполняем
        for(size_t i = 0; i < s; ++i){
            arr[i] = static_cast<uint8>(i);
        };


 Мне не нравится ++i, получается arr[0] не участвует в цикле? Следовательно выход за рамки массива.


ЗЫ  Ядро линух, в 32-х разрядной машине, не даёт выделиь память для одного процесса больше 3.8Гиг(или около того). Это жестко записано в ядре. Может ядро надо пересобрать? (Я не в курсе как у тебя, проверь)
PM MAIL   Вверх
georain
Дата 13.11.2008, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Цитата(destrd @  13.11.2008,  14:44 Найти цитируемый пост)
Ну попробуйте 

Тоже самое будет, проверка на ноль с nothrow аналогична перехвату исключения. Память выделяется, но не может быть использована.

Добавлено @ 15:00
Цитата(vTictor @  13.11.2008,  14:57 Найти цитируемый пост)
ЗЫ  Ядро линух, в 32-х разрядной машине, не даёт выделиь память для одного процесса больше 3.8Гиг(или около того). Это жестко записано в ядре. Может ядро надо пересобрать? (Я не в курсе как у тебя, проверь) 

У меня полная 64-х разрядность.

Цитата(vTictor @  13.11.2008,  14:57 Найти цитируемый пост)
Мне не нравится ++i, получается arr[0] не участвует в цикле? Следовательно выход за рамки массива.

Это не правильно. arr[0] участвует. Но даже если бы не участвовал, с чего выход за границу будет?

Добавлено
Кстати, винда так делает? Или что она делает? А UNIXы стандартно?

Это сообщение отредактировал(а) georain - 13.11.2008, 15:10
PM MAIL   Вверх
vinick
Дата 13.11.2008, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 4
Всего: 22



У тебя всего 4 гига RAM,  ты захватил 3,2 гига физической памяти,когда начал писать в массив arr, и при попытке захватить больше твой процесс убивает oom-killer.  Как побороть? Отключить oom-kiler и тогда я не представляю как будет вести себя система или следить за количеством захваченой памяти и не выходить за рамки приличия или подключить своп терабайта на 2-3. 
PM MAIL ICQ Jabber   Вверх
georain
Дата 13.11.2008, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



vinick, я спрашиваю как это сделать средствами языка. Это же ведь не нормально, когда приложение падает! Оно не выполняет никаких запрещённых действий и тут нет логических ошибок!
Мне это вообще не понятно, зачем он её тогда выделяет, мог бы просто перестать выделять.
Столько мороки в стандартах и в коде по поводу исключения bad allocate, а реально оказывается оно на фиг не нужно, всё равно всё умрёт.
Короче моему возмущению нет придела smile
PM MAIL   Вверх
vinick
Дата 13.11.2008, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 4
Всего: 22



Цитата(georain @  13.11.2008,  15:42 Найти цитируемый пост)
vinick, я спрашиваю как это сделать средствами языка.

Средствами языка это не решить. Никак. Ты сожрал всю память и хочешь чтобы тебе послали исключение  или сигнал? а ведь им тоже для этого ресурсы нужны.
Цитата(georain @  13.11.2008,  15:42 Найти цитируемый пост)

Мне это вообще не понятно, зачем он её тогда выделяет, мог бы просто перестать выделять.

Он не может не выделять. так как тебе положено 2^64-1 байт виртуального адресного пространства на процесс. 

Цитата(georain @  13.11.2008,  15:42 Найти цитируемый пост)
Столько мороки в стандартах и в коде по поводу исключения bad allocate, а реально оказывается оно на фиг не нужно, всё равно всё умрёт.

Не путай выделение памяти и отображение виртуальной памяти на физические адреса. bad allocate, это для первого, а у тебя проблема во втором.

Цитата(georain @  13.11.2008,  15:42 Найти цитируемый пост)

Это же ведь не нормально, когда приложение падает! 

Ненормально когда приложение жрет столько памяти smile

Это сообщение отредактировал(а) vinick - 13.11.2008, 16:03
PM MAIL ICQ Jabber   Вверх
vTictor
Дата 13.11.2008, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 13.2.2008

Репутация: нет
Всего: нет



Ещё замечание: 
выделаеш память так arr = new(nothrow) uint8[b];, а освобождаешь так  delete arr;. Нужно  delete [] arr;   smile 

Ты в цикле выделяешь память для масива arr, на каждой итерации ему присваевается новое значение указателя, а старое теряется. 
Когда ты его заполняешь, то заполняешь не всю выделеную память. если надо увеличивать один и тот же блок, юзай realloc.

Да и вообще, зачем такие извращения? smile Цель какая??  smile 

Это сообщение отредактировал(а) vTictor - 13.11.2008, 16:17
PM MAIL   Вверх
vinick
Дата 13.11.2008, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 4
Всего: 22



Цитата(vTictor @  13.11.2008,  16:10 Найти цитируемый пост)
Ты в цикле выделяешь память для масива arr, на каждой итерации ему присваевается новое значение указателя, а старое теряется. 


Да нет, там у него все нормально.
Код

  if( arr != 0) break; // Если выделение прошло успешно, то выход из цикла

PM MAIL ICQ Jabber   Вверх
vTictor
Дата 13.11.2008, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 13.2.2008

Репутация: нет
Всего: нет



vinick, точно. Я не заметил :( 
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0560 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.