Много памяти забирает std::vector
От: gepard1980  
Дата: 06.01.09 12:31
Оценка:
База данных содержит 100.000 записей. Каждую запись считываю в обьект CRecObj.
Обьект помещаю в std::vector<CRecObj>, используя push_back. Смотрю размер CRecObj через sizeof(CObj) —
примерно около 80 байт каждый. Размер вектора получается в итоге 5 Мб.
А оперативной памяти сьедает более 100 МБ. В чем дело? И как
с этим справится?
Re: Много памяти забирает std::vector
От: Аноним  
Дата: 06.01.09 12:44
Оценка: 1 (1)
G>База данных содержит 100.000 записей. Каждую запись считываю в обьект CRecObj.
G>Обьект помещаю в std::vector<CRecObj>, используя push_back. Смотрю размер CRecObj через sizeof(CObj) —
G>примерно около 80 байт каждый. Размер вектора получается в итоге 5 Мб.
G>А оперативной памяти сьедает более 100 МБ. В чем дело? И как
G>с этим справится?
Приведите определение CRecObj. Почти уверен что у вас там есть члены содержащие динамически выделенную память которая sizeof'ом не учитывается.
Re: Много памяти забирает std::vector
От: Mager Украина  
Дата: 06.01.09 12:46
Оценка: -2
Здравствуйте, gepard1980, Вы писали:

G>База данных содержит 100.000 записей. Каждую запись считываю в обьект CRecObj.

G>Обьект помещаю в std::vector<CRecObj>, используя push_back. Смотрю размер CRecObj через sizeof(CObj) —
G>примерно около 80 байт каждый. Размер вектора получается в итоге 5 Мб.
G>А оперативной памяти сьедает более 100 МБ. В чем дело? И как
G>с этим справится?

1) В вектор лучше данные такого обьема не закидать потому что он много операций с памятью проводит(при ресайзе особенно). Лучше использовать указатели на те обьекты.
2) Вектор не обязательно держит столько памяти, сколько Вы его попросили. Он выделяет еще немного "для запаса". Причем немного может быть совсем немлаленьким числом.
Re: Много памяти забирает std::vector
От: K13 http://akvis.com
Дата: 06.01.09 12:49
Оценка:
G>База данных содержит 100.000 записей. Каждую запись считываю в обьект CRecObj.
G>Обьект помещаю в std::vector<CRecObj>, используя push_back. Смотрю размер CRecObj через sizeof(CObj) —
G>примерно около 80 байт каждый. Размер вектора получается в итоге 5 Мб.
G>А оперативной памяти сьедает более 100 МБ. В чем дело? И как
G>с этим справится?

ну как вариант -- попробовать сделать вектору reserve() перед циклом.
тогда push_back не будет приводить к переаллокации памяти.

И что значит "съедает 100 МБ"? как именно мерялось?
Re: Много памяти забирает std::vector
От: VoidEx  
Дата: 06.01.09 12:54
Оценка: -1
Здравствуйте, gepard1980, Вы писали:

G>Размер вектора получается в итоге 5 Мб.

Через size смотрели?
G>А оперативной памяти сьедает более 100 МБ. В чем дело? И как
G>с этим справится?
Проверьте capacity, 100 ли там Мб?
Re[2]: Много памяти забирает std::vector
От: gepard1980  
Дата: 06.01.09 12:57
Оценка: :)
CRecObj
{
CString s1;
CString s2;
CString s3;
DWORD dw1;
DWORD dw2;
DWORD dw3;
}
Re[2]: Много памяти забирает std::vector
От: gepard1980  
Дата: 06.01.09 12:59
Оценка:
Здравствуйте, K13, Вы писали:

K13>ну как вариант -- попробовать сделать вектору reserve() перед циклом.


Сделал.

K13>тогда push_back не будет приводить к переаллокации памяти.

K13>И что значит "съедает 100 МБ"? как именно мерялось?

В TaskManager в колонке MemUsage.
Re[3]: Много памяти забирает std::vector
От: VoidEx  
Дата: 06.01.09 13:03
Оценка:
Здравствуйте, gepard1980, Вы писали:

G>CRecObj

G>{
G> CString s1;
G> CString s2;
G> CString s3;
G> DWORD dw1;
G> DWORD dw2;
G> DWORD dw3;
G>}
CString сам себе память выделяет. Чтобы узнать, сколько сожрал сам вектор, вызови capacity.
Re[2]: Много памяти забирает std::vector
От: gepard1980  
Дата: 06.01.09 13:07
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, gepard1980, Вы писали:


G>>Размер вектора получается в итоге 5 Мб.

VE>Через size смотрели?

Да размер(примерный 80 байт) элемента на количество элементов в векторе.

G>>А оперативной памяти сьедает более 100 МБ. В чем дело? И как

G>>с этим справится?
VE>Проверьте capacity, 100 ли там Мб?

Capacity показывает 109500.
Re[3]: Много памяти забирает std::vector
От: rg45 СССР  
Дата: 06.01.09 13:12
Оценка:
Здравствуйте, gepard1980, Вы писали:

G>CRecObj

G>{
G> CString s1;
G> CString s2;
G> CString s3;
G> DWORD dw1;
G> DWORD dw2;
G> DWORD dw3;
G>}

Ну вот, как раз то, о чем и говорил Аноним 639. CString — это всего навсего умная обертка над указателем. Она имеет фиксирванный (сравнительно небольшой) размер. Размеры текстовых данных, адресуемых объектами типа CString, не учитывываются оператором sizeof. Вероятно, именно эти текстовые данные и занимают бОльшую часть занимаемой памяти.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: Много памяти забирает std::vector
От: VoidEx  
Дата: 06.01.09 13:35
Оценка:
Здравствуйте, gepard1980, Вы писали:

VE>>Проверьте capacity, 100 ли там Мб?


G>Capacity показывает 109500.

Т.е. элементов 100000, а реально выделенной памяти на 109500.
А столько памяти отнимает то, что CString — обёртка над указателем, которая сама указывает на кусок памяти, о чём Вам написали выше.
Re[3]: Много памяти забирает std::vector
От: Аноним  
Дата: 06.01.09 13:45
Оценка:
G>CRecObj
G>{
G> CString s1;
G> CString s2;
G> CString s3;
G> DWORD dw1;
G> DWORD dw2;
G> DWORD dw3;
G>}

разер памяти занятой под CRecObj будет равен не sizeof(CRecObj), а
sizeof(CRecObj) + размер памяти выделенной s1 + размер памяти выделенной s2 + размер памяти выделенной s3
Чтобы точно определить размер дополнительной памяти занятой CString'ом документированных путей нету. Но ориентировочно оно будет от одного до двух размеров хранящейся строки. Умножить в 2 раза если определен UNICODE.
Re: Много памяти забирает std::vector
От: gepard1980  
Дата: 06.01.09 14:29
Оценка:
Всем спасибо! Буду решать.
Re: Много памяти забирает std::vector
От: Sealcon190 Соломоновы острова  
Дата: 08.01.09 06:15
Оценка: -1
Здравствуйте, gepard1980, Вы писали:

G>Обьект помещаю в std::vector<CRecObj>, используя push_back.


Re[2]: Много памяти забирает std::vector
От: dotidot Россия  
Дата: 08.01.09 08:58
Оценка: +1
Здравствуйте, Sealcon190, Вы писали:

S>Здравствуйте, gepard1980, Вы писали:


G>>Обьект помещаю в std::vector<CRecObj>, используя push_back.


S>

а что такого? Cstring наверняка copyonwrite использует, в результате копируется 80 байт на одно копирование структуры.
если этот вектор по значению не передавать везде, то тормозов даже видно не будет. зато не нужно рулить памятью, мучаясь с указателями, или объяснять gepard1980-у что такое умные указатели и какие подводные камни встречаются при их использовании.
Re: Много памяти забирает std::vector
От: Adriano  
Дата: 08.01.09 16:09
Оценка: -3
Здравствуйте, gepard1980, Вы писали:

G>База данных содержит 100.000 записей. Каждую запись считываю в обьект CRecObj.

G>Обьект помещаю в std::vector<CRecObj>, используя push_back. Смотрю размер CRecObj через sizeof(CObj) —
G>примерно около 80 байт каждый. Размер вектора получается в итоге 5 Мб.
G>А оперативной памяти сьедает более 100 МБ. В чем дело? И как
G>с этим справится?

используй вместо вектора std::deque
Re[2]: Много памяти забирает std::vector
От: skeptik_  
Дата: 08.01.09 17:58
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, gepard1980, Вы писали:


G>>Размер вектора получается в итоге 5 Мб.

VE>Через size смотрели?
G>>А оперативной памяти сьедает более 100 МБ. В чем дело? И как
G>>с этим справится?
VE>Проверьте capacity, 100 ли там Мб?

capacity измеряется в элементах, а не в байтах.
Re[3]: Много памяти забирает std::vector
От: VoidEx  
Дата: 08.01.09 21:16
Оценка: +1
Здравствуйте, skeptik_, Вы писали:

_>capacity измеряется в элементах, а не в байтах.

И?
Re[3]: Много памяти забирает std::vector
От: Sealcon190 Соломоновы острова  
Дата: 10.01.09 03:03
Оценка: -2 :)
Здравствуйте, dotidot, Вы писали:

D>а что такого?


Да ничего. Но я бы расстреливал всех кто для вектора использует push_back.

Хотя осознаю что это у меня узко-профессиональное.
Re[4]: Много памяти забирает std::vector
От: Юрий Жмеренецкий ICQ 380412032
Дата: 10.01.09 13:22
Оценка: +1
Здравствуйте, Sealcon190, Вы писали:

S>Здравствуйте, dotidot, Вы писали:


D>>а что такого?


S>Да ничего. Но я бы расстреливал всех кто для вектора использует push_back.


Для push_back сложность вставки определена как 'amortized constant time'. Это значит, что вставка N элементов происходит за O(N) времени, но нет гарантий, что вставка одного элемента произойдет за O(1).

Если количество элементов известно, то для вставки одного элемента можно добиться O(1), вынеся факторы, которые делают эту сложность амортизированной вне push_back. Другими словами — производить выделение памяти заранее.

Для алгоритмов, в которых суммарное количество вставляемых элементов заранее неизвестно, использование push_back — практически единственный выход, и других, принципиально иных, сценариев для вставки в vector нет.

Варианты с изменением типа контейнера можно рассматривать только после выявления типичных сценариев использования.

Использование контейнеров, которые предполагают динамическое выделение памяти (множество мелких объектов в таких масштабах) помимо очевидных преимуществ может привести к таким неприятным последствиям, как дефрагментация кучи, слишком частые блокировки стандартного менеджера памяти в многопоточном окружении (при каждой вставке), плохая локальность данных и т.д. А может и не привести. Смотреть надо...
Re[5]: Много памяти забирает std::vector
От: Sealcon190 Соломоновы острова  
Дата: 12.01.09 03:09
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Варианты с изменением типа контейнера можно рассматривать только после выявления типичных сценариев использования.


Потому я и сказал что ненависть к vector push_back у меня узкопрофессионально обусловленная.
Re[4]: Много памяти забирает std::vector
От: Аноним  
Дата: 12.01.09 13:31
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, gepard1980, Вы писали:


G>>CRecObj

G>>{
G>> CString s1;
G>> CString s2;
G>> CString s3;
G>> DWORD dw1;
G>> DWORD dw2;
G>> DWORD dw3;
G>>}
VE>CString сам себе память выделяет. Чтобы узнать, сколько сожрал сам вектор, вызови capacity.
И помножь на соответствующий sizeof
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.