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

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

Страниц: 1 ... 4 5 [6] 7   Вниз
  Печать  
Автор Тема: Memory issues  (Прочитано 54030 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Проблема здесь совсем не в squeeze (это только частный случай). Почему они написали что обычно squeeze не нужна? Да потому что они затачивали resize и erase на освобождение (с пулом). В исходниках это хорошо видно. И это была хорошая и правильная задумка.

BRE, по смыслу у Вас должна память освобождаться по resize (пусть не вся, что-то на пул), без всякого squeeze. Проверьте когда будет возможность.

Но у них дыра в базовом распределении памяти, и это вылазит в виде самых разнообразных (у)течек. Я вообще столкнулся с этим на QByteArray.
Записан
BRE
Гость
« Ответ #76 : Сентябрь 17, 2009, 11:35 »

Проблема здесь совсем не в squeeze (это только частный случай). Почему они написали что обычно squeeze не нужна? Да потому что они затачивали resize и erase на освобождение (с пулом). В исходниках это хорошо видно. И это была хорошая и правильная задумка.
QVector из-за его особенности (необходимость непрерывного участка памяти) затачивался захватывать буфер с запасом и чем больше пользователь задает размер, тем больший запас делает QVector. Делается это что бы уменьшить фрагментацию памяти, но при превышении запаса необходимо было перезахватить новый буфер. Память, которую раньше занимал буфер освобождается, из нее в дальнейшем выделяется память для объектов не превышающих ее.

BRE, по смыслу у Вас должна память освобождаться по resize (пусть не вся, что-то на пул), без всякого squeeze. Проверьте когда будет возможность.
Она освобождается. Только буфер становится размером больше чем указал пользователь (резерв). Если после resize вызвать capacity(), то он сообщит на сколько элементов реально выделен буфер. (последний пример это хорошо показывает, если поиграться с размерами QVector).

Но у них дыра в базовом распределении памяти, и это вылазит в виде самых разнообразных (у)течек. Я вообще столкнулся с этим на QByteArray.
Ну тогда у них еще огромная дыра: никак не получается запустить сразу миллион QThread.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Igors, попробуй последний пример.
Код
C++ (Qt)
       qDebug() << v1.size() << v1.capacity() << &v1[ 0 ] << &v1[ 0 ] + v1.capacity() * [b]sizeof( int )[/b];
 
Подправьте пожалуйста оригинал чтобы не было путаницы (если Вы добавляете к адресу, домножать на sizeof не надо).
Записан
BRE
Гость
« Ответ #78 : Сентябрь 17, 2009, 11:43 »

Подправьте пожалуйста оригинал чтобы не было путаницы (если Вы добавляете к адресу, домножать на sizeof не надо).
Почему?
capacity() возвращает количество элементов для которых зарезервирован буфер. Размер элемента sizeif( int ).
Нужно умножать.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Почему?
capacity() возвращает количество элементов для которых зарезервирован буфер. Размер элемента sizeif( int ).
Нужно умножать.
&v1[0] есть указатель на int. Значит, сама адресная арифметика размер учтет. Вот если Вы бы привели его к (char *) - тогда надо.
Записан
BRE
Гость
« Ответ #80 : Сентябрь 17, 2009, 11:59 »

&v1[0] есть указатель на int. Значит, сама адресная арифметика размер учтет. Вот если Вы бы привели его к (char *) - тогда надо.
Туплю уже.  Улыбающийся

Вот немного измененный пример:
Код
C++ (Qt)
       QVector<int> v1;
       QVector<int> v2;
       const int sizeV1 = 100000;
       const int sizeV2 = 60000;
 
       v1.resize( sizeV1 );
       for( int i1 = 0; i1 < sizeV1; ++i1 )
               v1[ i1 ] = i1;              
       qDebug() << v1.size() << v1.capacity() << &v1[ 0 ] << &v1[ 0 ] + v1.capacity();
       v1.resize( 1 );                                                                
       qDebug() << v1.size() << v1.capacity() << &v1[ 0 ] << &v1[ 0 ] + v1.capacity();
 
       v2.resize( sizeV2 );
       for( int i2 = 0; i2 < sizeV2; ++i2 )
               v2[ i2 ] = i2;              
       qDebug() << v2.size() << v2.capacity() << &v2[ 0 ] << &v2[ 0 ] + v2.capacity();
 

Вывод:
100000 131068 0xb7f80018 0xb8000008
        1         2 0xb7f80018 0xb7f80020
 60000   65532 0xb7fc0018 0xb8000008

По моему все по адресам видно.
P.S. На счет адресов: в linux большие буферы выделяются с конца хипа, маленькие с начала.
« Последнее редактирование: Сентябрь 17, 2009, 12:05 от BRE » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Вывод:
100000 131068 0xb7f80018 0xb8000008
        1         2 0xb7f80018 0xb7f80020
 60000   65532 0xb7fc0018 0xb8000008

По моему все по адресам видно.
А у меня

Код:
100000 131068 0x1c010 0x9c000 
1 2 0x1c010 0x1c018
60000 65532 0x9c010 0xdc000
И, судя по тому что Spectre проверял, - то же на Вындоуз
Записан
BRE
Гость
« Ответ #82 : Сентябрь 17, 2009, 12:20 »

А у меня

Код:
100000 131068 0x1c010 0x9c000 
1 2 0x1c010 0x1c018
60000 65532 0x9c010 0xdc000
И, судя по тому что Spectre проверял, - то же на Вындоуз

Да, как-то это грустно и неправильно.  Строит глазки
Но все таки, IMHO, это проблемы MacOS.
Записан
Winstrol
Гость
« Ответ #83 : Сентябрь 17, 2009, 13:55 »

Код:
100000 131068 0x1c010 0x9c000 
1 2 0x1c010 0x1c018
60000 65532 0x9c010 0xdc000
Попробуй использовать сторонний распределитель
http://www.hoard.org/

Под WinXp
Код:
100000 131068 0x7fe80050 0x7ff00040
1 2 0x7ff701b8 0x7ff701c0
60000 65532 0x7fec0050 0x7ff00040


Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Попробуй использовать сторонний распределитель
http://www.hoard.org/
За ссылку спасибо. Если я правильно понял:

Не используйте QVector, а используйте std::vector, усиленный кастомным аллокатором

Хорошо, проживу я без QVector. Но ведь у меня и с QString то же самое

Код:
#define NUM_TEST (20 * 1024 * 1024)

int i, j;
QString theS[100];

for (i = 0; i < 100; ++i) {
        for (j = 0; j < NUM_TEST; ++j)
theS[i] += "abc";
printf("String %d\r", i);
theS[i].truncate(2);   // вместо этого можно и theS[i].resize(2); эффект тот же
theS[i].squeeze();
}
Вылетает. Так что же, мне и QString избегать? Улыбающийся  Или все время думать "а не будет ли моя строка слишком большой"? Или "зачищать" ее каждый раз через копирование в др. строку?

"Абыдно, слюший" (классика советского кино)
Записан
SABROG
Гость
« Ответ #85 : Сентябрь 17, 2009, 16:23 »

Не используйте QVector, а используйте std::vector, усиленный кастомным аллокатором

А я бы сказал иначе: "не пишите нестабильные программы, которые съедят всю доступную оперативную память в погоне за скоростью, вместо того, чтобы написать программу, которая будет делать свою работу как часы и не мешать работать другим программам, которым тоже нужна память".
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

А я бы сказал иначе: "не пишите нестабильные программы, которые съедят всю доступную оперативную память в погоне за скоростью, вместо того, чтобы написать программу, которая будет делать свою работу как часы и не мешать работать другим программам, которым тоже нужна память".
Но ведь я так и делаю Улыбающийся Взял 120Mb (разве это сейчас "вся память"?), обработал этот кусок, освободил память, беру следующий.  Вернее - хотел освободить Улыбающийся
Записан
Winstrol
Гость
« Ответ #87 : Сентябрь 17, 2009, 16:30 »

Попробуй использовать сторонний распределитель
http://www.hoard.org/
За ссылку спасибо. Если я правильно понял:

Не используйте QVector, а используйте std::vector, усиленный кастомным аллокатором

Хорошо, проживу я без QVector. Но ведь у меня и с QString то же самое

Hoard переопределяет вызовы malloc/new. Про кастомные аллокаторы stl верно само собой, но это более высокого уровня пушка.
Записан
SABROG
Гость
« Ответ #88 : Сентябрь 17, 2009, 16:35 »

А я бы сказал иначе: "не пишите нестабильные программы, которые съедят всю доступную оперативную память в погоне за скоростью, вместо того, чтобы написать программу, которая будет делать свою работу как часы и не мешать работать другим программам, которым тоже нужна память".
Но ведь я так и делаю Улыбающийся Взял 120Mb (разве это сейчас "вся память"?), обработал этот кусок, освободил память, беру следующий.  Вернее - хотел освободить Улыбающийся

Ну и используй clean(), он работает нормально Улыбающийся
Записан
BRE
Гость
« Ответ #89 : Сентябрь 17, 2009, 16:52 »

Взял 120Mb (разве это сейчас "вся память"?), обработал этот кусок, освободил память, беру следующий.  Вернее - хотел освободить Улыбающийся
IMHO из-за этого все проблемы. Захотел 120Mb - получил - освободил, захотел 300Mb - получил - освободил, ... , захотел 500Mb - а адресное пространство исчерпалось. Хотя у нас остались свободные блоки 120Mb, 300Mb, ...
Наверное стоит изменить алгоритм хранения этих данных, что бы не было необходимости в больших непрерывных блоках памяти

На счет менеджера памяти на Mac это отдельный разговор, с ним наверное нужно по разбираться или заменить...
Записан
Страниц: 1 ... 4 5 [6] 7   Вверх
  Печать  
 
Перейти в:  


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