[問題] 在thread裡面free memory

作者: Lipraxde (Lipraxde)   2017-12-05 20:31:17
開發平台(Platform): (Ex: Win10, Linux, ...)
Linux 4.12.13-1-ARCH x86_64
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
gcc 7.2.0
Glibc 2.26
問題(Question):
我想要在main裡面malloc後把指標傳到thread裡,在thread結束前free記憶體。
結果記憶體用量會隨著操作次數漸漸變大。
程式大致上長像這樣:
void *test(void *p)
{
pthread_detach(pthread_self());
free(p);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
... other code ...
pthread_t tid;
void *p = malloc(8*1024*1024);
pthread_create(&tid, NULL, test, p);
... other code ...
}
在main裡面做了很多次malloc、pthread_create的動作。
有確認過free都有執行到,如果不做malloc、free,單純建立theard然後退出都正常。
不過兩者合在一起用的時候就漸漸的把記憶體吃掉了。
還有哪裡可能有記憶體沒釋放到嗎?
預期的正確結果(Expected Output):
記憶體用量不會一直增加
錯誤結果(Wrong Output):
記憶體用量漸漸增加
程式碼(Code):(請善用置底文網頁, 記得排版)
完整的程式:https://ideone.com/SKWT5Q
補充說明(Supplement):
1.執行程式每次被吃的記憶體量會有一點點不一樣。
2.如果是在main裡面free的話就不會這樣。
作者: jerryh001   2017-12-05 20:44:00
你有檢查thread結束了嗎? 會不會只是還沒切換到那個thread
作者: stupid0319 (徵女友)   2017-12-05 21:01:00
你知道8*1024*1024要多少個分頁嗎感覺pthread_detach放的位置很奇怪...是我的錯覺嗎假如主線程跑比較多迴圈,而執行緒卡住這種情況呢?
作者: Qbsuran (Qbsuran)   2017-12-05 21:43:00
detach位置沒問題 malloc在某些情況不是thread safe
作者: galic (嘎利)   2017-12-05 21:48:00
detach沒問題 他只是改狀態而已先報個環境版本上來吧 glibc kernel等等malloc和free從很早開始就一直都是thead safety
作者: jasonwu23 (jasonwu)   2017-12-05 22:01:00
看起來沒問題 有沒有完整一點的程式碼 我想看會一點點增加的版本 有可能別的地方leak
作者: galic (嘎利)   2017-12-05 22:20:00
我猜啦 你配置的記憶體很大 glibc會改用mmap/munmap這會比小記憶體用的brk/sbrk方法慢上許多你可以用malloc_stats() 觀察小是多小? 預設是超過128*1024就會用mmap
作者: Killercat (殺人貓™)   2017-12-05 23:11:00
valgrind跑一次看看 這個應該抓得出來
作者: galic (嘎利)   2017-12-05 23:19:00
同樓上 我用相似環境跑沒問題... 用valgrind跑吧然後你所謂的"記憶體用量" 是從哪邊觀察的?
作者: Bencrie   2017-12-06 10:46:00
都要跑 valgrind 了就直接用它測記憶體用量吧google 一下 valgrind massif
作者: galic (嘎利)   2017-12-06 10:56:00
XD 竟然能用top觀察到 這程式跑沒幾秒still reachable的那個別管他 pthread_create配置的空間thread死掉不會歸還 為了效能 下次pthread_create會reuse很多std library實作上都有類似操作 光malloc系列有一大堆
作者: Lipraxde (Lipraxde)   2017-12-06 13:47:00
pthread會reuse的話應該不會一直無限膨脹阿。如果是在main裡面用pthread_join把指標接回來free,過一陣子自己就會變回遠本的大小了。(而且沒有still reachable)我之後應該會避免這樣用吧,雖然變大的速度不快但是看起來真的很不舒服。
作者: galic (嘎利)   2017-12-06 14:00:00
我的意思是你從valgrind觀察到的still reachable是pthread走detach的話沒辦法free pthread create的空間 但是下次pthread create的時候會去reuse 若沒被reuse 整個程式結束後 還是能正確的被OS回收 所以這種std library實作造成的常見的still reachable 並不算是真正的memory leak也不該是造成你程式記憶體不斷膨脹的主因
作者: Lipraxde (Lipraxde)   2017-12-06 14:07:00
恩,瞭解了…那真正的問題是出在error發生的時候嗎?那次的still reachable特別大。
作者: galic (嘎利)   2017-12-06 14:23:00
下"--leak-check=full --show-leak-kinds=reachable"看看看看特別大的那次是誰造成的 XD你提了之後我才想到 你改成全部由malloc的thread來free之後狀況就不存在 所以問題可能出在由不同thread來malloc和free
作者: Lipraxde (Lipraxde)   2017-12-06 14:48:00
我剛剛想到之前用malloc_stats看的時候的確是有一直增加記憶體用量(每做一次多佔用1184bytes),跟用valgrind得到的log不太一樣。那個error是偶然間跑出來的,目前只出現一次QQ

Links booklink

Contact Us: admin [ a t ] ucptt.com