Russian Qt Forum
Май 21, 2024, 14:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как средствами Qt узнать инфу о свободной памяти?  (Прочитано 10447 раз)
fulkabaster
Гость
« : Январь 06, 2010, 10:23 »

Перед работой с массивом нужно определить размер свободной оперативки. Как это делать средствами Qt4? Просмотрел все Qt-классы, нашел только QSharedMemory, но это не то. Хотелось бы найти что-то вроде QMemory Улыбающийся
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #1 : Январь 06, 2010, 10:38 »

никак. Только платформозависимое АПИ. Более того, не под все ОС это даст что-то адекватное - вроде в винде прога не может кушать больше 2х ГБ оп, если я не ошибаюсь
Записан
Vass
Гость
« Ответ #2 : Январь 06, 2010, 14:31 »

Ошибаетесь, теоретически любой приложение в виндах может адресовать до 4Гб памяти, т.к. используется FLAT-модель: http://ru.wikipedia.org/wiki/Плоская_модель_памяти.
P.S. Речь, конечно, про 32-bit
Записан
niXman
Гость
« Ответ #3 : Январь 06, 2010, 14:40 »

Цитировать
т.к. используется FLAT-модель: http://ru.wikipedia.org/wiki/Плоская_модель_памяти.
это у unix систем. а не у вендов.
Записан
crackedmind
Гость
« Ответ #4 : Январь 06, 2010, 14:47 »

Если в винде включить PAE то можно более 2 гб на приложение адресовать Улыбающийся
Записан
SABROG
Гость
« Ответ #5 : Январь 06, 2010, 15:19 »

Вроде бы можно в местах где идет выделение памяти через new ставить обертку типа try{} catch(...) и пользователю сообщать типа "out of memory", затем спокойно продолжать работу и ждать пока памяти станет больше Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Январь 06, 2010, 15:26 »

Перед работой с массивом нужно определить размер свободной оперативки.
Не вдаваясь в детали: на сегодняшний день такая задача/подход лишен смысла даже в 32-bits (не говоря уже о 64). Я делаю так:

- отслеживаю сам сколько памяти распределено мною (свой менеджер кучи)
- в преференсах позволяю пользователю задать количество используемой памяти. По умолчанию - 80% физической памяти
- если предел превышен - swap на диск, если нет такой возможности - fatal error и выход

Все это обходится весьма недешево. Поэтому если нет абсолютной необходимости - разумно ограничиться простой проверкой не вернет ли new NULL (обычно с испусканием exception). Сделать "быстренько" (используя готовый инструмент) здесь не получится.
Записан
SABROG
Гость
« Ответ #7 : Январь 06, 2010, 15:35 »

К сожалению тут ты можешь быть ответственен только за собственные вызовы new, а вот чего может навыделять Qt или ОС. Тут уже от падения может и не спасти.
Записан
Vass
Гость
« Ответ #8 : Январь 06, 2010, 15:41 »

это у unix систем. а не у вендов.
Значит я ошибаюсь Подмигивающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Январь 06, 2010, 16:10 »

К сожалению тут ты можешь быть ответственен только за собственные вызовы new, а вот чего может навыделять Qt или ОС. Тут уже от падения может и не спасти.
Ах как хочется выдать "Учи матчасть !"  Улыбающийся Но не буду - непродуктивно. Операции new/delete могут быть перекрыты, если не ошибаюсь, с 1993 года. Легко проверить например так

Код:
void * operator new( unsigned long size )
{
  return malloc(size);
}

int main( int argc, char * argv[] )
{
  ...
}
Поставьте breakpoint на malloc и Вы увидите в отладчике что управление приходит "из недр Qt"
Записан
SABROG
Гость
« Ответ #10 : Январь 06, 2010, 18:51 »

О переопределении я знаю давно. Вот только в исходниках Qt еще используются прямые вызовы malloc() и GlobalAlloc() (WINAPI).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Январь 06, 2010, 20:32 »

Вот только в исходниках Qt еще используются прямые вызовы malloc() и GlobalAlloc() (WINAPI).
Да, но такие вызовы используются для "личных целей Qt" например таких как рисование имеджа  и.т.п. Это распределения временные, их пользовательской программе отслеживать и не нужно. Все остальное проходит через new или qMalloc - и может учитываться. Другое дело что забот с этим хватает, поэтому нужны серьезные основания начинать эту песню.

К слову сказать - ведь new может и не выделять память (малоизвестная но очень полезная возможность)
Записан
fulkabaster
Гость
« Ответ #12 : Январь 07, 2010, 11:11 »

Не вдаваясь в детали: на сегодняшний день такая задача/подход лишен смысла даже в 32-bits (не говоря уже о 64).
В моем случае массив может иметь около 250 млн. байтовых элементов, это изрядно для не самой мощной машинки с 512 Мб оперативки.
Цитировать
Поэтому если нет абсолютной необходимости - разумно ограничиться простой проверкой не вернет ли new NULL (обычно с испусканием exception).
Если б я юзал new... Массив считывается с файла, точное значение элементов заранее неизвестно (можно конечно предварительно просканировать файл и посчитать их, но это лишнее время). Поэтому юзаю QList с его append-ом.

Вообще-то я не очень хорошо понимаю всю кухню работы с памятью в ОС. Не знаю как в винде, но вот че я сделал в линуксе. Посмотрел с помощью "free -m" сколько свободной оперативки. Например, показало, что 150 Мб (из 512 Мб). Я беру и считываю в QList из файла 230 миллионов char-ов, т.е. 230 Мб. Загружается с полминуты, но загружается. Никаких ошибок и предупреждений. Работаю с массивом без проблем. Вопрос - ОС подгрузила на swap что-то свое или мой массив? И прокатит тот же фокус в винде? Если да, то необходимость в проверке в принципе отпадает, т.к. на машинках с памятью менее 512 Мб работать не предполагается.
« Последнее редактирование: Январь 07, 2010, 11:13 от fulkabaster » Записан
BRE
Гость
« Ответ #13 : Январь 07, 2010, 11:40 »

Поэтому юзаю QList с его append-ом.
Для эффективной работы QList с большими объемами данных желательно узнать и преаллоцировать память заранее. Т.е. общий размер данный узнать желательно (а при очень больших данных обязательно).
Стоит помнить, что QList это не связанный список и он будет пытаться аллоцировать непрерывный кусок памяти для данных (или указателей).
Было обсуждение проблем QList: http://www.prog.org.ru/topic_10610_0.html
« Последнее редактирование: Январь 07, 2010, 11:44 от BRE » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Январь 07, 2010, 13:08 »

В моем случае массив может иметь около 250 млн. байтовых элементов, это изрядно для не самой мощной машинки с 512 Мб оперативки.
Неясно кто такие "байтовые элементы" - просто байты? Есть ли у считываемых данных конструктор/деструктор, виртуальные методы и т. п? Если да - то Ваше решение использовать QList правильно. Если нет (пассивные данные, байты информации) то гораздо лучше использовать просто new или QVector (если требуется вставка/удаление).

Если б я юзал new... Массив считывается с файла, точное значение элементов заранее неизвестно (можно конечно предварительно просканировать файл и посчитать их, но это лишнее время). Поэтому юзаю QList с его append-ом.
На таких данных append съест гораздо больше времени и памяти чем предварительный проход.

Вопрос - ОС подгрузила на swap что-то свое или мой массив? И прокатит тот же фокус в винде?
При объеме 250 Мб - да, прокатит, и на Mac OSX тоже. Все OS в этом смысле примерно одинаковы. Везде память виртуальна, есть swap на диск и отключить это нельзя. Везде любому процессу выделяется адресное пространство 2 Gb (а кое-где и больше) в 32-bits. (поэтому кол-во свободной оперативки ни о чем не говорит).

Однако не все OS могут выделять непрерывные блоки больше 1 Gb (даже если столько памяти есть физически). Поэтому выбирать контейнер для больших данных нужно очень тщательно.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.051 секунд. Запросов: 22.