Втрати пам’яті в Linux

поскільки на форумі є багато лінкус спеців, можливо ви зможете допомогти розібратись.

після того як до серверної проги була додана підтримка лінукс я помітив зростання RSS пам’яті процесу на 4-8кб при кожному конекті/дисконекті клієнта (при чому у віндрвс ніяких втрат пам’яті не спостерігається.

коли я зробив дамп proc/self/maps отримав:

00400000-00521000 r-xp 00000000 fd:00 786436 /home/myuser/myserver
 00721000-00722000 rw-p 00121000 fd:00 786436 /home/myuser/myserver
 00722000-00724000 rw-p 00000000 00:00 0 
 026e5000-02746000 rw-p 00000000 00:00 0 [heap]
 3535600000-353561f000 r-xp 00000000 fd:00 78751 /lib64/ld-2.14.so
 353581e000-353581f000 r--p 0001e000 fd:00 78751 /lib64/ld-2.14.so
 353581f000-3535820000 rw-p 0001f000 fd:00 78751 /lib64/ld-2.14.so
 3535820000-3535821000 rw-p 00000000 00:00 0 
 3535a00000-3535b8f000 r-xp 00000000 fd:00 78761 /lib64/libc-2.14.so
 3535b8f000-3535d8e000 ---p 0018f000 fd:00 78761 /lib64/libc-2.14.so
 3535d8e000-3535d92000 r--p 0018e000 fd:00 78761 /lib64/libc-2.14.so
 3535d92000-3535d93000 rw-p 00192000 fd:00 78761 /lib64/libc-2.14.so
 3535d93000-3535d99000 rw-p 00000000 00:00 0 
 3535e00000-3535e02000 r-xp 00000000 fd:00 78774 /lib64/libdl-2.14.so
 3535e02000-3536002000 ---p 00002000 fd:00 78774 /lib64/libdl-2.14.so
 3536002000-3536003000 r--p 00002000 fd:00 78774 /lib64/libdl-2.14.so
 3536003000-3536004000 rw-p 00003000 fd:00 78774 /lib64/libdl-2.14.so
 3536200000-3536216000 r-xp 00000000 fd:00 37268 /lib64/libpthread-2.14.so
 3536216000-3536415000 ---p 00016000 fd:00 37268 /lib64/libpthread-2.14.so
 3536415000-3536416000 r--p 00015000 fd:00 37268 /lib64/libpthread-2.14.so
 3536416000-3536417000 rw-p 00016000 fd:00 37268 /lib64/libpthread-2.14.so
 3536417000-353641b000 rw-p 00000000 00:00 0 
 3536600000-3536610000 r-xp 00000000 fd:00 78811 /usr/lib64/libodbcinst.so.2.0.0
 3536610000-3536810000 ---p 00010000 fd:00 78811 /usr/lib64/libodbcinst.so.2.0.0
 3536810000-3536811000 rw-p 00010000 fd:00 78811 /usr/lib64/libodbcinst.so.2.0.0
 3536a00000-3536a5f000 r-xp 00000000 fd:00 27010 /usr/lib64/libodbc.so.2.0.0
 3536a5f000-3536c5e000 ---p 0005f000 fd:00 27010 /usr/lib64/libodbc.so.2.0.0
 3536c5e000-3536c66000 rw-p 0005e000 fd:00 27010 /usr/lib64/libodbc.so.2.0.0
 3536c66000-3536c67000 rw-p 00000000 00:00 0 
 3536e00000-3536e15000 r-xp 00000000 fd:00 78775 /lib64/libgcc_s-4.6.0-20110428.so.1
 3536e15000-3537014000 ---p 00015000 fd:00 78775 /lib64/libgcc_s-4.6.0-20110428.so.1
 3537014000-3537015000 rw-p 00014000 fd:00 78775 /lib64/libgcc_s-4.6.0-20110428.so.1
 3538600000-3538617000 r-xp 00000000 fd:00 78786 /lib64/libresolv-2.14.so
 3538617000-3538817000 ---p 00017000 fd:00 78786 /lib64/libresolv-2.14.so
 3538817000-3538818000 r--p 00017000 fd:00 78786 /lib64/libresolv-2.14.so
 3538818000-3538819000 rw-p 00018000 fd:00 78786 /lib64/libresolv-2.14.so
 3538819000-353881b000 rw-p 00000000 00:00 0 
 353a200000-353a214000 r-xp 00000000 fd:00 12064 /usr/lib64/libelf-0.152.so
 353a214000-353a413000 ---p 00014000 fd:00 12064 /usr/lib64/libelf-0.152.so
 353a413000-353a414000 r--p 00013000 fd:00 12064 /usr/lib64/libelf-0.152.so
 353a414000-353a415000 rw-p 00014000 fd:00 12064 /usr/lib64/libelf-0.152.so
 353d600000-353d6e8000 r-xp 00000000 fd:00 78793 /usr/lib64/libstdc++.so.6.0.16
 353d6e8000-353d8e8000 ---p 000e8000 fd:00 78793 /usr/lib64/libstdc++.so.6.0.16
 353d8e8000-353d8f0000 r--p 000e8000 fd:00 78793 /usr/lib64/libstdc++.so.6.0.16
 353d8f0000-353d8f2000 rw-p 000f0000 fd:00 78793 /usr/lib64/libstdc++.so.6.0.16
 353d8f2000-353d907000 rw-p 00000000 00:00 0 
 3541a00000-3541a5c000 r-xp 00000000 fd:00 78808 /lib64/libfreebl3.so
 3541a5c000-3541c5b000 ---p 0005c000 fd:00 78808 /lib64/libfreebl3.so
 3541c5b000-3541c5d000 rw-p 0005b000 fd:00 78808 /lib64/libfreebl3.so
 3541c5d000-3541c61000 rw-p 00000000 00:00 0 
 3541e00000-3541e08000 r-xp 00000000 fd:00 78809 /lib64/libcrypt-2.14.so
 3541e08000-3542007000 ---p 00008000 fd:00 78809 /lib64/libcrypt-2.14.so
 3542007000-3542008000 r--p 00007000 fd:00 78809 /lib64/libcrypt-2.14.so
 3542008000-3542009000 rw-p 00008000 fd:00 78809 /lib64/libcrypt-2.14.so
 3542009000-3542037000 rw-p 00000000 00:00 0 
 3542a00000-3542a09000 r-xp 00000000 fd:00 22913 /usr/lib64/libltdl.so.7.3.0
 3542a09000-3542c08000 ---p 00009000 fd:00 22913 /usr/lib64/libltdl.so.7.3.0
 3542c08000-3542c09000 rw-p 00008000 fd:00 22913 /usr/lib64/libltdl.so.7.3.0
 3548600000-3548616000 r-xp 00000000 fd:00 14527 /lib64/libnsl-2.14.so
 3548616000-3548815000 ---p 00016000 fd:00 14527 /lib64/libnsl-2.14.so
 3548815000-3548816000 r--p 00015000 fd:00 14527 /lib64/libnsl-2.14.so
 3548816000-3548817000 rw-p 00016000 fd:00 14527 /lib64/libnsl-2.14.so
 3548817000-3548819000 rw-p 00000000 00:00 0 
 7f1dcc000000-7f1dcc021000 rw-p 00000000 00:00 0 
 7f1dcc021000-7f1dd0000000 ---p 00000000 00:00 0 
 7f1dd1c59000-7f1dd8000000 r--p 00000000 fd:00 77003 /usr/lib/locale/locale-archive
 7f1dd8000000-7f1dd8021000 rw-p 00000000 00:00 0 
 7f1dd8021000-7f1ddc000000 ---p 00000000 00:00 0 
 7f1ddcb61000-7f1ddcb62000 ---p 00000000 00:00 0 
 7f1ddcb62000-7f1ddd362000 rw-p 00000000 00:00 0 
 7f1ddd362000-7f1ddd363000 ---p 00000000 00:00 0 
 7f1ddd363000-7f1dddb63000 rw-p 00000000 00:00 0 
 7f1dddb63000-7f1dddb64000 ---p 00000000 00:00 0 
 7f1dddb64000-7f1dde364000 rw-p 00000000 00:00 0 
 7f1dde364000-7f1dde376000 r-xp 00000000 fd:00 79041 /usr/lib64/libodbcinst.so.1
 7f1dde376000-7f1dde576000 ---p 00012000 fd:00 79041 /usr/lib64/libodbcinst.so.1
 7f1dde576000-7f1dde577000 rw-p 00012000 fd:00 79041 /usr/lib64/libodbcinst.so.1
 7f1dde577000-7f1dde777000 r-xp 00000000 fd:00 35405 /usr/lib64/libmyodbc5-5.1.8.so
 7f1dde777000-7f1dde7c3000 rw-p 00200000 fd:00 35405 /usr/lib64/libmyodbc5-5.1.8.so
 7f1dde7c3000-7f1dde7c4000 rw-p 00000000 00:00 0 
 7f1dde7c4000-7f1dde7c5000 r-xp 00000000 fd:00 5943 /usr/lib64/gconv/ISO8859-1.so
 7f1dde7c5000-7f1dde9c5000 ---p 00001000 fd:00 5943 /usr/lib64/gconv/ISO8859-1.so
 7f1dde9c5000-7f1dde9c6000 r--p 00001000 fd:00 5943 /usr/lib64/gconv/ISO8859-1.so
 7f1dde9c6000-7f1dde9c7000 rw-p 00002000 fd:00 5943 /usr/lib64/gconv/ISO8859-1.so
 7f1dde9c7000-7f1dde9cd000 r-xp 00000000 fd:00 5731 /lib64/libnss_dns-2.14.so
 7f1dde9cd000-7f1ddebcc000 ---p 00006000 fd:00 5731 /lib64/libnss_dns-2.14.so
 7f1ddebcc000-7f1ddebcd000 r--p 00005000 fd:00 5731 /lib64/libnss_dns-2.14.so
 7f1ddebcd000-7f1ddebce000 rw-p 00006000 fd:00 5731 /lib64/libnss_dns-2.14.so
 7f1ddebce000-7f1ddebda000 r-xp 00000000 fd:00 5733 /lib64/libnss_files-2.14.so
 7f1ddebda000-7f1ddedd9000 ---p 0000c000 fd:00 5733 /lib64/libnss_files-2.14.so
 7f1ddedd9000-7f1ddedda000 r--p 0000b000 fd:00 5733 /lib64/libnss_files-2.14.so
 7f1ddedda000-7f1ddeddb000 rw-p 0000c000 fd:00 5733 /lib64/libnss_files-2.14.so
 7f1ddeded000-7f1ddedf2000 rw-p 00000000 00:00 0 
 7f1ddedf2000-7f1ddee75000 r-xp 00000000 fd:00 32411 /lib64/libm-2.14.so
 7f1ddee75000-7f1ddf074000 ---p 00083000 fd:00 32411 /lib64/libm-2.14.so
 7f1ddf074000-7f1ddf075000 r--p 00082000 fd:00 32411 /lib64/libm-2.14.so
 7f1ddf075000-7f1ddf076000 rw-p 00083000 fd:00 32411 /lib64/libm-2.14.so
 7f1ddf076000-7f1ddf078000 rw-p 00000000 00:00 0 
 7f1ddf080000-7f1ddf081000 rw-p 00000000 00:00 0 
 7f1ddf081000-7f1ddf088000 r--s 00000000 fd:00 76956 /usr/lib64/gconv/gconv-modules.cache
 7f1ddf088000-7f1ddf089000 rw-s 00000000 00:04 360454 /SYSV79003162 (deleted)
 7f1ddf089000-7f1ddf08b000 rw-p 00000000 00:00 0 
 7fff4fce4000-7fff4fd05000 rw-p 00000000 00:00 0 [stack]
 7fff4fd8c000-7fff4fd8d000 r-xp 00000000 00:00 0 [vdso]
 ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

після 30 ітерацій (конект/дисконект), отримав біля 70 нових рядків на зразок:

7f1da8fca000-7f1da8fcb000 ---p 00000000 00:00 0 
 7f1da8fcb000-7f1da97cb000 rw-p 00000000 00:00 0 
 7f1da97cb000-7f1da97cc000 ---p 00000000 00:00 0 
 7f1da97cc000-7f1da9fcc000 rw-p 00000000 00:00 0 
 7f1da9fcc000-7f1da9fcd000 ---p 00000000 00:00 0 
 7f1da9fcd000-7f1daa7cd000 rw-p 00000000 00:00 0 
 7f1daa7cd000-7f1daa7ce000 ---p 00000000 00:00 0 
 7f1daa7ce000-7f1daafce000 rw-p 00000000 00:00 0 
 7f1daafce000-7f1daafcf000 ---p 00000000 00:00 0 
 7f1daafcf000-7f1dab7cf000 rw-p 00000000 00:00 0 
 7f1dab7cf000-7f1dab7d0000 ---p 00000000 00:00 0 
 7f1dab7d0000-7f1dabfd0000 rw-p 00000000 00:00 0 
 7f1dabfd0000-7f1dabfd1000 ---p 00000000 00:00 0 
 7f1dabfd1000-7f1dac7d1000 rw-p 00000000 00:00 0 
 7f1dac7d1000-7f1dac7d2000 ---p 00000000 00:00 0 
 7f1dac7d2000-7f1dacfd2000 rw-p 00000000 00:00 0 
 7f1dacfd2000-7f1dacfd3000 ---p 00000000 00:00 0 
 7f1dacfd3000-7f1dad7d3000 rw-p 00000000 00:00 0 
 7f1dad7d3000-7f1dad7d4000 ---p 00000000 00:00 0 
 7f1dad7d4000-7f1dadfd4000 rw-p 00000000 00:00 0 
 7f1dadfd4000-7f1dadfd5000 ---p 00000000 00:00 0 
 7f1dadfd5000-7f1dae7d5000 rw-p 00000000 00:00 0 
 7f1dae7d5000-7f1dae7d6000 ---p 00000000 00:00 0 
 7f1dae7d6000-7f1daefd6000 rw-p 00000000 00:00 0 
 7f1daefd6000-7f1daefd7000 ---p 00000000 00:00 0 
 7f1daefd7000-7f1daf7d7000 rw-p 00000000 00:00 0 
 7f1daf7d7000-7f1daf7d8000 ---p 00000000 00:00 0 
 7f1daf7d8000-7f1daffd8000 rw-p 00000000 00:00 0 
 7f1daffd8000-7f1daffd9000 ---p 00000000 00:00 0

що вони означають?

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Похоже на классическую ошибку использования pthread, (for ex. использование pthread_join вместо pthread_detach), из мана по pthread_detach :

....
The pthread_detach() function marks the thread identified by thread as detached. When
a detached thread terminates, its resources are automatically released back to the sys-
tem without the need for another thread to join with the terminated thread.

...

Скорей всего в венде используется другая thread-абстракция. В таких случаях имеет смысл применять надежные кроссплатформенные решения аля commoncpp.

Могу посоветовать тот же валгринд для отлавливания утечек памяти.
К тому же хочу заметить, что стандартный аллокатор памяти в линухе не делает дефрагментацию памяти, со времением, при большом колл-ве вызовов new/delete или malloc/free, память процессом все равно будет съедаться.

Поэтому могу посоветовать перейти на работу со статическими блоками памяти, либо использовать альтернативные аллокаторы.

Как выделяется память в программе: malloc/new или mmap ?

Последовательная инкрементация адресов всё-таки говорит об утечке. Посмотри на такую тулзу, как valgrind, чтобы быть уверенным, что это всё-таки утечка, а не разростание хипа.

У Windows программ хип увеличивается, если мне не изменяет память по пол мегабайта, то, чтобы найти утечку визуально, то нужно запустить программу больше 130000 раз :)

malloc/new

эти строки не соответcвуют pthread ? или они просто говорят о выделении пямяти?

ок, попробую valgrind

или они просто говорят о выделении пямяти?
Да, выделение памяти.

7f1da8fca000-7f1da8fcb000 ---p 00000000 00:00 0

4Kb, «p» — это флажок copy on write, т.е. реальное выделение памяти будет только тогда, когда пойдёт в неё запись.

7f1da8fcb000-7f1da97cb000 rw-p 00000000 00:00 0

Было выделено 8Mb. Реальное выделение по copy-on-write.

7f1da97cb000-7f1da97cc000 ---p 00000000 00:00 0

4Kb, «p»

7f1da97cc000-7f1da9fcc000 rw-p 00000000 00:00 0

Было выделено 8Mb. Реальное выделение по copy-on-write.

ScorpZ прав, это может быть и фрагментацией (разростание хипа). Выделяются ли в программе куски по 8Mb? Если да, то может быть такая проблема:

1) Выделили 8Mb
2) Выделили 4Kb
3) Освободили 8Mb
4) Выделили 4Kb, оно будете выделено в первом фрагменте, где было изначально 8Mb. Теперт в том куске осталось 8Mb-4Kb.

Поэтому при следующем выделении 8Mb хип будет увеличен ещё на 8Mb, т.к. в старом куске не хватает 4Kb.

Если программа действительно работает с кусками памяти именно по 8Mb, то нужно переходить на выделение анонимной памяти через mmap, эта проблема уйдёт.

по 8Мб нигде не выделяю.

когда я вывожу количетсво RSS (из proc/self/stat) то разница на 30 итерациях около 2Мб

максималльно что выделяется это 1-2кб, хотя в основном выделение меньше 1кб.

(много истпользуется std::string и std::vector, но они небольшой длины)

А как растёт VSIZE (VSZ, VSS — не знаю как оно сейчас называется) по сравнению с RSS ?

такое происходит:
-----------------------
rss: 3704(kb) vsize: 319528960(byte)
rss: 3780(kb) vsize: 462139392(byte)
rss: 3788(kb) vsize: 470532096(byte)
rss: 3796(kb) vsize: 478924800(byte)
rss: 3804(kb) vsize: 487317504(byte)
rss: 5860(kb) vsize: 495710208(byte)
rss: 3836(kb) vsize: 504102912(byte)
rss: 3844(kb) vsize: 512495616(byte)
rss: 3852(kb) vsize: 520888320(byte)
rss: 3860(kb) vsize: 529281024(byte)
rss: 4096(kb) vsize: 537673728(byte)
rss: 4104(kb) vsize: 546066432(byte)
rss: 4112(kb) vsize: 554459136(byte)
rss: 4120(kb) vsize: 562851840(byte)
rss: 4128(kb) vsize: 571244544(byte)
rss: 4136(kb) vsize: 579637248(byte)
rss: 4144(kb) vsize: 588029952(byte)
rss: 4156(kb) vsize: 596422656(byte)
rss: 4164(kb) vsize: 604815360(byte)
rss: 4172(kb) vsize: 613208064(byte)
rss: 4436(kb) vsize: 621600768(byte)
rss: 4444(kb) vsize: 629993472(byte)
rss: 4452(kb) vsize: 638386176(byte)
rss: 4460(kb) vsize: 646778880(byte)
rss: 4468(kb) vsize: 655171584(byte)
rss: 4476(kb) vsize: 663564288(byte)
rss: 4484(kb) vsize: 671956992(byte)
rss: 4492(kb) vsize: 680349696(byte)
rss: 4500(kb) vsize: 688742400(byte)

-----------------------

Плохо. RSS — это сколько реальной памяти съела программа, а вот vsize — это сколько она захотела памяти виртуальной, туда, конечно, входят ещё и различные shared object’ы, типа библиотек. Т.е. если при каждом malloc/new делать что-то вроде memset(mem_ptr, 0×00, alloc_mem_size), то RSS будет догонять vsize.

А что говорит valgrind?

в «сумари» говорит, что есть потери.

попытаюсь из него вытянуть детали

даже без итераций выдало ошибки в основном в std::string (их очень много используется) и pthread_create, когда запустил с —leak-check=full
-----------
по крайней мене есть инфо :)
-----------
[myuser@s2]$ valgrind —leak-check=full ./myserver
==4580== Memcheck, a memory error detector
==4580== Copyright © 2002-2010, and GNU GPL’d, by Julian Seward et al.
==4580== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==4580== Command: ./myserver
==4580==
hello
my localhost (server) information:
Name: хххххххх.com
Address: хх.хх.хх.хх
params: -slave
==4580== Conditional jump or move depends on uninitialised value(s)
==4580== at 0×4A06E28: strlen (mc_replace_strmem.c:282)
==4580== by 0×353D6A4ADF: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×444A1C: dCommandParser::removeSpace(std::string&) const (in /home/myuser/svn/myserver)
==4580== by 0×44868E: dCommandParser::dCommandParser(std::string const&, bool, bool) (in /home/myuser/svn/myserver)
==4580== by 0×4066BC: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== Conditional jump or move depends on uninitialised value(s)
==4580== at 0×4A06E28: strlen (mc_replace_strmem.c:282)
==4580== by 0×353D6A4ADF: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×444A33: dCommandParser::removeSpace(std::string&) const (in /home/myuser/svn/myserver)
==4580== by 0×44868E: dCommandParser::dCommandParser(std::string const&, bool, bool) (in /home/myuser/svn/myserver)
==4580== by 0×4066BC: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==

running as slave

Summary of socket settings:
Socket Id: 3
port #: 2506
reuse addr: true
keep alive: false
send buf size: 16384
recv bug size: 87380
blocking: true
linger on: false

linger seconds: 0

ODBCConnection()
result Connected to database
starting worker
ctor
rss: 61664(kb) vsize: 268275712(byte)
==4580==
==4580== HEAP SUMMARY:
==4580== in use at exit: 36,373 bytes in 319 blocks
==4580== total heap usage: 3,879 allocs, 3,560 frees, 1,341,697 bytes allocated
==4580==
==4580== 29 bytes in 1 blocks are possibly lost in loss record 103 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A3189: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A332B: std::string::_M_replace_safe(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×471C0F: dListenThread::dListenThread( idSocketCallback*, idSocket*, idSemaphore*, idSemaphore*, idEvent*, idSQLqueue*, idThreadPool*, idLogEx*, char const*, unsigned int, unsigned int, bool) (in /home/myuser/svn/myserver)
==4580== by 0×48BA45: dServer::createListenerThread( idSocketCallback*, idSocket*, idSemaphore*, idSemaphore*, idEvent*, idThreadPool*, idLogEx*, unsigned int, unsigned int, bool) const (in /home/myuser/svn/myserver)
==4580== by 0×48FA20: dServerThread::thFn(void*) (in /home/myuser/svn/myserver)
==4580== by 0×3536207AF0: start_thread (in /lib64/libpthread-2.14.so)
==4580== by 0×3535ADFC2C: clone (in /lib64/libc-2.14.so)
==4580==
==4580== 32 bytes in 1 blocks are definitely lost in loss record 107 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A49A4: char* std::string::_S_construct<char const*="">(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A4AF2: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×406B5E: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== 33 bytes in 1 blocks are definitely lost in loss record 108 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A49A4: char* std::string::_S_construct<char const*="">(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A4AF2: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×406B41: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== 34 bytes in 1 blocks are definitely lost in loss record 109 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A49A4: char* std::string::_S_construct<char const*="">(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A4AF2: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×406B0A: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== 35 bytes in 1 blocks are possibly lost in loss record 110 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A49A4: char* std::string::_S_construct<char const*="">(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A4AF2: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×48E6B9: dServer::ServerStop(bool) (in /home/myuser/svn/myserver)
==4580== by 0×406C4A: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== 35 bytes in 1 blocks are possibly lost in loss record 111 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A49A4: char* std::string::_S_construct<char const*="">(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A4AF2: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×48E4FF: dServer::ServerStop(bool) (in /home/myuser/svn/myserver)
==4580== by 0×406C4A: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== 35 bytes in 1 blocks are possibly lost in loss record 112 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A49A4: char* std::string::_S_construct<char const*="">(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A4AF2: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×48E5B6: dServer::ServerStop(bool) (in /home/myuser/svn/myserver)
==4580== by 0×406C4A: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== 35 bytes in 1 blocks are definitely lost in loss record 113 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A49A4: char* std::string::_S_construct<char const*="">(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×353D6A4AF2: std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
==4580== by 0×406B24: threadFunction() (in /home/myuser/svn/myserver)
==4580== by 0×4073EE: main (in /home/myuser/svn/myserver)
==4580==
==4580== 36 bytes in 1 blocks are possibly lost in loss record 114 of 180
==4580== at 0×4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==4580== by 0×353D6A2F98: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.16)
...

...

ура, pthread_join() для клиентских threads (если даже закончилось выполнение )сократило потери RSS кардинально, а виртуалка не растет , в то время как pthread_detach() ничего не меняло

есть какокйто рост на vsize на первой и второй итерации ( но при последующих выглядит стабильно). не идеал, но намного лучше чем было
-------------------
rss: 3700(kb) vsize: 311140352(byte)
rss: 3700(kb) vsize: 319533056(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 3772(kb) vsize: 453750784(byte)
rss: 4000(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4004(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)
rss: 4032(kb) vsize: 453750784(byte)

-------------------

не идеал, но намного лучше чем было

Сейчас выглядит вообще хорошо. Слабый рост rss, возможно, теперь связан с небольшим ростом хипа. Надо по-больше итераций дать и посмотреть.

Некоторые заблуждения таки требуют развеяния.

7f1da8fca000-7f1da8fcb000 ---p 00000000 00:00 0
4Kb, «p» — это флажок copy on write, т.е. реальное выделение памяти будет только тогда, когда пойдёт в неё запись.

Нет. Буква «p» — это от «private», там же может стоять «s» (shared). Всего лишь индикатор того является ли регион разделяемым. Подробности в fs/proc/task_mmu.c:show_map_vma() lxr.linux.no/...task_mmu.c#L212

7f1da8fcb000-7f1da97cb000 rw-p 00000000 00:00 0
Было выделено 8Mb. Реальное выделение по copy-on-write.

Тоже не так. Это не есть «реальное выделение». В файле /proc/$PID/maps отображается базовая информация о списке структур vm_area_struct из дескриптора _виртуального_ адресного пространства процесса mm_struct. Для получения «реально выделенного» нужно обойти page tables процесса, аккумулируя информацию из всех PTE. Это делается, к примеру, при генерации вывода псевдофайла /proc/$PID/smaps. Пример: paste.in.ua/3706/raw

Ну и часто упоминавшийся heap в данном контексте не к месту, так как он выделен в отдельный регион, присутствующий в дампе из исходного сообщения:

026e5000-02746000 rw-p 00000000 00:00 0 [heap] 

По теме треда. Valgrind таки «рулит и педалит». Хотя и паттерн регионов памяти, в принципе, узнаваем и характерен для pthread-приложений. Относительно большие RW-регионы (дескриптор треда и стек), разделенные PROT_NONE guarding регионами дефолтного для glibc размера в одну страницу.

EDIT: formatting сообщений совсем таки не rich : (

Нет. Буква «p» — это от «private», там же может стоять «s» (shared). Всего лишь индикатор того является ли регион разделяемым. Подробности в fs/proc/task_mmu.c:show_map_vma() lxr.linux.no/...task_mmu.c#L212

И?. Тем не менее это прямой индикатор того, что был задействован lazy mmap, а не mmap’инг всего региона в память. Для этого этот флажок и ввели.

Тоже не так. Это не есть «реальное выделение».

Это реальное lazy выделение.

Ну и часто упоминавшийся heap в данном контексте не к месту, так как он выделен в отдельный регион, присутствующий в дампе из исходного сообщения:

И что? Это стартовый хип. А куда он растёт? А какой аллокатор использует данная версия Линукса? Тот же SLEL, RHEL используют не placement mmap(), и хип продолжает расти в другом месте.

Подписаться на комментарии