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

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

Страниц: 1 [2] 3 4 ... 7   Вниз
  Печать  
Автор Тема: Memory issues  (Прочитано 54116 раз)
spectre71
Гость
« Ответ #15 : Сентябрь 14, 2009, 16:02 »

Видно что squeeze освобождает память! Не могу понять прикола, в чем разница между этими двумя вариантами?

Разница похоже в squeeze, не срабатывает что ли. В первом случае первые 800Мб освобождает delete и второй вектор выделяет снова 800Мб. Во втором случае squeeze похоже ничего не делает в итоге идет попытка откушать память до 1600Мб.
Я же писал про Mem Usage & VM Size, останавливал в дебагере и смотрел. Так что squeeze работает.
Единственно в чем может быть разница между QVector<int> и моим sbw::Indices - я не использую realloc! Я создаю новый массив и копирую данные в него через memcpy. Может проблема в использовании realloc в QVector(если он использует именно realloc)?
Записан
spectre71
Гость
« Ответ #16 : Сентябрь 14, 2009, 16:04 »

Как ни странно, но Igors прав! Это явный глюк QVector, осталось понять в чем он заключается.
Из Ваших примеров я не могу понять почему я прав Улыбающийся

На Mac есть подлянка с ::realloc и т.к. Qt его активно использует...
Про Вындоуз не знаю.

Потому что с QVector<int> - глючит
А с мим аналогичным классом sbw::Indices - нет.
Смотри вверху тесты для QVector<int> и sbw::Indices

Да и кстати, я тестировал под Windows, ты на сколько понял тестировал под Mac. Но глюк одинаковый и там и там Грустный
« Последнее редактирование: Сентябрь 14, 2009, 16:12 от Spectre » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Сентябрь 14, 2009, 16:23 »

Может проблема в использовании realloc в QVector(если он использует именно realloc)?
Файл qmalloc.cpp

void *qRealloc(void *ptr, size_t size)
{
    return ::realloc(ptr, size);
}

На Mac это память НЕ освобождает, на Вындоуз - не в курсе
« Последнее редактирование: Сентябрь 14, 2009, 16:27 от Igors » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Сентябрь 14, 2009, 16:34 »

Да и кстати, я тестировал под Windows, ты на сколько понял тестировал под Mac. Но глюк одинаковый и там и там Грустный
Уточните плз: то есть отот код (theVector[10]) валится и на Вындоуз?
И еще одна мелочь: потянет ли на Вындоуз

QVector<int> theV;
theV.reserve(400 * 1024 * 1024);  // то есть > 1Gb

На Mac - нет, хотя на борту 4Gb

Спасибо
Записан
spectre71
Гость
« Ответ #19 : Сентябрь 14, 2009, 17:27 »

Да и кстати, я тестировал под Windows, ты на сколько понял тестировал под Mac. Но глюк одинаковый и там и там Грустный
Уточните плз: то есть отот код (theVector[10]) валится и на Вындоуз?
И еще одна мелочь: потянет ли на Вындоуз

QVector<int> theV;
theV.reserve(400 * 1024 * 1024);  // то есть > 1Gb

На Mac - нет, хотя на борту 4Gb

Спасибо

Да этот код(приведенный вами) валиться на Windows. И тот упрощенный код(который я приводил) тоже.
theV.reserve(400 * 1024 * 1024);  -  валиться на Windows сразу(Windows XP).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Сентябрь 14, 2009, 17:48 »

Да этот код(приведенный вами) валиться на Windows. И тот упрощенный код(который я приводил) тоже.
theV.reserve(400 * 1024 * 1024);  -  валиться на Windows сразу(Windows XP).
Ага, спасибо, Spectre
Давайте сочинять баг репорт (vers 2.0)?  Улыбающийся
Записан
spectre71
Гость
« Ответ #21 : Сентябрь 14, 2009, 18:30 »

Да этот код(приведенный вами) валиться на Windows. И тот упрощенный код(который я приводил) тоже.
theV.reserve(400 * 1024 * 1024);  -  валиться на Windows сразу(Windows XP).
Ага, спасибо, Spectre
Давайте сочинять баг репорт (vers 2.0)?  Улыбающийся
Это проблемы использования realloc
Код:
  int* a;
  int* b;
 
  a = (int*) malloc(200*1024*1024*sizeof(int));
  a = (int*) realloc(a, sizeof(int));
  b = (int*) malloc(200*1024*1024*sizeof(int));
// b == NULL Error !!!
  delete a;
  delete b;
Видимо эта зараза(realloc) не освобождает память, в надежде на то, что ее снова будут аллоцировать для данного указателя, идиотизм!
Не помню чтобы что-то подобное было описано в его спецификации(посмотрел сейчас в MSDN и ничего токого не нашел), хотя я им в последний раз пользовался лет 10 назад, поскольку он практически не нужен(так сходу и не придумать нормальной задачи где нужен - оптимален realloc).
Записан
SABROG
Гость
« Ответ #22 : Сентябрь 14, 2009, 18:44 »

Ноги похоже отсюда растут: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove

erase не удаляет ничего, он подчищает мусор, который остается после использования метода remove().
Записан
BRE
Гость
« Ответ #23 : Сентябрь 14, 2009, 18:47 »

Погонял тесты под linux. Полет нормальный.
Код с двумя векторами работает нормально: захватывает - освобождает.
С выделением: theV.reserve(400 * 1024 * 1024);  // то есть > 1Gb
тоже все Ок.
Записан
spectre71
Гость
« Ответ #24 : Сентябрь 14, 2009, 18:48 »

Ноги похоже отсюда растут: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove
erase не удаляет ничего, он подчищает мусор, который остается после использования метода remove().
Ноги ростут от кривой работы realloc! Что показано на предыдущем тесте.
А то что ты привел связано с различием между "Count/Size" и "Capacity/AllocSize"
Записан
spectre71
Гость
« Ответ #25 : Сентябрь 14, 2009, 18:55 »

Погонял тесты под linux. Полет нормальный.
Код с двумя векторами работает нормально: захватывает - освобождает.
С выделением: theV.reserve(400 * 1024 * 1024);  // то есть > 1Gb
тоже все Ок.

1) Возможно под Linux - realloc работает другим образом?
2) Скольки разрядный Linux, если 64, то возможно разница в этом?
Записан
BRE
Гость
« Ответ #26 : Сентябрь 14, 2009, 19:07 »

1) Возможно под Linux - realloc работает другим образом?
2) Скольки разрядный Linux, если 64, то возможно разница в этом?
linux - 32bit.

Код
C++ (Qt)
 a = (int*) malloc(200*1024*1024*sizeof(int));
 a = (int*) realloc(a, sizeof(int));          
 b = (int*) malloc(200*1024*1024*sizeof(int));
 
 qDebug() << a;
 qDebug() << b;
 
Вывод:
0x85fb8008               
0x53fb7008               

Код
C++ (Qt)
 //#1 - Откушано памяти: 19 Мб
 a = (int*) malloc(400*1024*1024*sizeof(int));
 //#2 - Откушано памяти: 1,5 Гб
 a = (int*) realloc(a, sizeof(int));          
 //#3 - Откушано памяти: 19 Мб
 b = (int*) malloc(400*1024*1024*sizeof(int));
 //#4 - Откушано памяти: 19 Мб
 
 qDebug() << a;
 qDebug() << b;
 
Вывод:
0x53ed6008
0x0

Т.е. realloc освобождает блок, malloc пытается захватить такой же, но обламывается т.к. ему не хватает адресного пространства для нового блока (хотя память есть). Вроде все согласно документации.

А вот так новый блок выделиться в перераспределенном:
Код
C++ (Qt)
 //#1 - Откушано памяти: 19 Мб
 a = (int*) malloc(400*1024*1024*sizeof(int));
 //#2 - Откушано памяти: 1,5 Гб
 a = (int*) realloc(a, sizeof(int));          
 //#3 - Откушано памяти: 19 Мб
 b = (int*) malloc(399*1024*1024*sizeof(int));
 //#4 - Откушано памяти: 1,5 Гб
 
 qDebug() << a;
 qDebug() << b;
 
Вывод:
0x54087008
0x54487008
« Последнее редактирование: Сентябрь 14, 2009, 19:34 от BRE » Записан
spectre71
Гость
« Ответ #27 : Сентябрь 14, 2009, 20:25 »

Кроче, я тут проконсультировался. Абсолютно гарантировать что все точно так не могу, но схема работы с памятью примерна такова:
1) Программа имеет кучу(heap)
2) Максимальный размер кучи определятся системой.
3) Куча может иметь несколько страниц.
4) Страницы могут имет различный размер. Максимальный/минимальный размер страницы и их кол-во(для программы) видимо определяется процом и системой(не очень точно).
5) При выделении памяти программой идет просмотр страниц(в ее куче),
- если в одной из них есть свободный непрерывный кусок, то память выделяется из этой страницы
- если ни в одной нет, то идет запрос к системе на добавление страницы достаточного размера(к нашей куче) под запрашиваемый нами непрерывный кусок памяти
6) Память может быть выделена только из одной страницы!!!
7) Страницы памяти самой программой не могут быть объединены!!!

Собственно и получаем - последний пример(под Linux от BRE):
Код:
  a = (int*) malloc(400*1024*1024*sizeof(int)); 
// ОК получили страницу памяти 1600 MB
// Имеем теперь 2 страницы в куче, изначальную, не очень большую и большую на 1600 MB
  a = (int*) realloc(a, sizeof(int));                   
// Освободили во второй странице 1600 MB без 4 byte
  b = (int*) malloc(400*1024*1024*sizeof(int));
// Просим 1600 MB.
// В первой странице совсем мало памяти
// Во второй странице не хватает 4 байт
// Просим у системы новую страницу для програмной кучи под наши 1600 MB, облом, превысили лимит!

/* Во втором варианте */

  b = (int*) malloc(399*1024*1024*sizeof(int));
// А в данном случае во второй странице памяти хватило (1600 MB - 4 byte > 1596 MB)

Вот такая фигня Улыбающийся
Записан
SABROG
Гость
« Ответ #28 : Сентябрь 14, 2009, 20:43 »

Ну вот erase под WindowsXP у меня тоже не сработал (список стал пуст, а память осталась занятой), хотя clean работает идеально. Remove тоже работает, но медленно.
Еще Qt у меня отказалась выделять 800Мб памяти, выдало в консоль "Out of memory". При этом программа на BCB, основанная на обычном std::vector, спокойно выделила 2Гб памяти (в системе всего 1.5Гб ОЗУ).

Я так понимаю, чтобы решить проблему это надо в Qt некий аналог дефрагментатора памяти писать?
« Последнее редактирование: Сентябрь 14, 2009, 20:45 от SABROG » Записан
spectre71
Гость
« Ответ #29 : Сентябрь 14, 2009, 21:16 »

Ну вот erase под WindowsXP у меня тоже не сработал (список стал пуст, а память осталась занятой), хотя clean работает идеально. Remove тоже работает, но медленно.
Еще Qt у меня отказалась выделять 800Мб памяти, выдало в консоль "Out of memory". При этом программа на BCB, основанная на обычном std::vector, спокойно выделила 2Гб памяти (в системе всего 1.5Гб ОЗУ).

Я так понимаю, чтобы решить проблему это надо в Qt некий аналог дефрагментатора памяти писать?

Читай топик выше, а лучше внимательно с самого начала, все уже разъяснили!
То что ты написал совершенно не относиться к делу, возможно ты не совсем понял о чем было обсуждение.
Записан
Страниц: 1 [2] 3 4 ... 7   Вверх
  Печать  
 
Перейти в:  


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