[問題] 在thread裡面free memory

看板C_and_CPP作者 (靜夜)時間8年前 (2017/12/05 20:31), 8年前編輯推噓5(5041)
留言46則, 8人參與, 8年前最新討論串1/1
開發平台(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的話就不會這樣。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 223.136.241.143 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1512477084.A.9EE.html

12/05 20:44, 8年前 , 1F
你有檢查thread結束了嗎? 會不會只是還沒切換到那個th
12/05 20:44, 1F

12/05 20:44, 8年前 , 2F
read
12/05 20:44, 2F

12/05 21:01, 8年前 , 3F
你知道8*1024*1024要多少個分頁嗎
12/05 21:01, 3F
我有cat /proc/${pid}/status看過,最後Threads=1。 malloc要多少個分頁會有影響嗎?我設這麼大是想說如果沒free到應該會很明顯。 不過我的程式不會佔到那麼大,這個動作大概做1000次才會多吃1Mib左右的空間。 ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 21:15:24

12/05 21:09, 8年前 , 4F
感覺pthread_detach放的位置很奇怪...是我的錯覺嗎
12/05 21:09, 4F
我是看網路上有人這樣用 OwO ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 21:21:50

12/05 21:37, 8年前 , 5F
假如主線程跑比較多迴圈,而執行緒卡住這種情況呢?
12/05 21:37, 5F
不太懂你的意思,我都在pthread_exit前一道指令free的,如果有thread卡住的話剩下的 thread應該不會只有1條。 ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 21:45:44

12/05 21:43, 8年前 , 6F
detach位置沒問題 malloc在某些情況不是thread safe
12/05 21:43, 6F
我有對malloc、free加互斥鎖過,結果一樣。(這個example比較單純,應該還好) ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 21:47:59

12/05 21:48, 8年前 , 7F
detach沒問題 他只是改狀態而已
12/05 21:48, 7F

12/05 21:49, 8年前 , 8F
先報個環境版本上來吧 glibc kernel等等
12/05 21:49, 8F
OK,glibc版本2.26(其他有更新在上面)

12/05 21:49, 8年前 , 9F
malloc和free從很早開始就一直都是thead safety
12/05 21:49, 9F

12/05 22:01, 8年前 , 10F
看起來沒問題 有沒有完整一點的程式碼 我想看會一點點
12/05 22:01, 10F

12/05 22:01, 8年前 , 11F
增加的版本 有可能別的地方leak
12/05 22:01, 11F
https://ideone.com/SKWT5Q 這個是我把遇到的情況簡化過的,它的確會慢慢變大,for迴圈多跑個幾次就看的出來。 還是你是想看我的作業>///<,已經被我改成在main裡面free了 @w@ ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 22:14:17

12/05 22:20, 8年前 , 12F
我猜啦 你配置的記憶體很大 glibc會改用mmap/munmap
12/05 22:20, 12F

12/05 22:20, 8年前 , 13F
這會比小記憶體用的brk/sbrk方法慢上許多
12/05 22:20, 13F

12/05 22:21, 8年前 , 14F
你可以用malloc_stats() 觀察
12/05 22:21, 14F
用malloc_stats看了之後覺得很奇怪,每次in use bytes都增加1184 bytes,那是啥? 是說我試過配置較小的記憶體了,不過用量還是會慢慢變大... ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 22:41:25

12/05 22:46, 8年前 , 15F
小是多小? 預設是超過128*1024就會用mmap
12/05 22:46, 15F
8個byte~ ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 23:04:45

12/05 23:11, 8年前 , 16F
valgrind跑一次看看 這個應該抓得出來
12/05 23:11, 16F

12/05 23:19, 8年前 , 17F
同樓上 我用相似環境跑沒問題... 用valgrind跑吧
12/05 23:19, 17F

12/05 23:20, 8年前 , 18F
然後你所謂的"記憶體用量" 是從哪邊觀察的?
12/05 23:20, 18F
用top跟你說的malloc_stats看的,不然我明天用valgrind、換台電腦試試看好了。 (好像在哪邊看到說free不一定會馬上還給系統,不過應該不是這個問題。因為我free完用 malloc可以得到相同的位置,可是還是會越吃越多Q_Q) ※ 編輯: Lipraxde (223.136.241.143), 12/05/2017 23:25:29

12/06 10:46, 8年前 , 19F
都要跑 valgrind 了就直接用它測記憶體用量吧
12/06 10:46, 19F

12/06 10:47, 8年前 , 20F
google 一下 valgrind massif
12/06 10:47, 20F

12/06 10:56, 8年前 , 21F
XD 竟然能用top觀察到 這程式跑沒幾秒
12/06 10:56, 21F
改成無窮迴圈一直跑就能看到它越來越大隻了。 用valgrind看有時候有still reachable: 1,612 bytes in 4 blocks,有時候又沒有。 偶爾還底下還會出現:ERROR SUMMARY: 1 errors from 1 contexts。 ※ 編輯: Lipraxde (140.118.202.43), 12/06/2017 12:05:53

12/06 13:29, 8年前 , 22F
still reachable的那個別管他 pthread_create配置的空間
12/06 13:29, 22F

12/06 13:30, 8年前 , 23F
thread死掉不會歸還 為了效能 下次pthread_create會reuse
12/06 13:30, 23F

12/06 13:31, 8年前 , 24F
很多std library實作上都有類似操作 光malloc系列有一大堆
12/06 13:31, 24F

12/06 13:47, 8年前 , 25F
pthread會reuse的話應該不會一直無限膨脹阿。
12/06 13:47, 25F

12/06 13:47, 8年前 , 26F
如果是在main裡面用pthread_join把指標接回來free,過一
12/06 13:47, 26F

12/06 13:47, 8年前 , 27F
陣子自己就會變回遠本的大小了。(而且沒有still reachab
12/06 13:47, 27F

12/06 13:47, 8年前 , 28F
le)
12/06 13:47, 28F

12/06 13:47, 8年前 , 29F
我之後應該會避免這樣用吧,雖然變大的速度不快但是看起
12/06 13:47, 29F

12/06 13:47, 8年前 , 30F
來真的很不舒服。
12/06 13:47, 30F

12/06 14:00, 8年前 , 31F
我的意思是你從valgrind觀察到的still reachable是pthread
12/06 14:00, 31F

12/06 14:01, 8年前 , 32F
走detach的話沒辦法free pthread create的空間 但是下次
12/06 14:01, 32F

12/06 14:02, 8年前 , 33F
pthread create的時候會去reuse 若沒被reuse 整個程式結束
12/06 14:02, 33F

12/06 14:02, 8年前 , 34F
後 還是能正確的被OS回收 所以這種std library實作造成的
12/06 14:02, 34F

12/06 14:02, 8年前 , 35F
常見的still reachable 並不算是真正的memory leak
12/06 14:02, 35F

12/06 14:03, 8年前 , 36F
也不該是造成你程式記憶體不斷膨脹的主因
12/06 14:03, 36F

12/06 14:07, 8年前 , 37F
恩,瞭解了…那真正的問題是出在error發生的時候嗎?那
12/06 14:07, 37F

12/06 14:07, 8年前 , 38F
次的still reachable特別大。
12/06 14:07, 38F

12/06 14:23, 8年前 , 39F
下"--leak-check=full --show-leak-kinds=reachable"看看
12/06 14:23, 39F

12/06 14:24, 8年前 , 40F
看看特別大的那次是誰造成的 XD
12/06 14:24, 40F

12/06 14:25, 8年前 , 41F
你提了之後我才想到 你改成全部由malloc的thread來free之後
12/06 14:25, 41F

12/06 14:25, 8年前 , 42F
狀況就不存在 所以問題可能出在由不同thread來malloc和free
12/06 14:25, 42F

12/06 14:48, 8年前 , 43F
我剛剛想到之前用malloc_stats看的時候的確是有一直增加
12/06 14:48, 43F

12/06 14:48, 8年前 , 44F
記憶體用量(每做一次多佔用1184bytes),跟用valgrind得
12/06 14:48, 44F

12/06 14:48, 8年前 , 45F
到的log不太一樣。
12/06 14:48, 45F

12/06 14:48, 8年前 , 46F
那個error是偶然間跑出來的,目前只出現一次QQ
12/06 14:48, 46F
文章代碼(AID): #1Q9f6Sdk (C_and_CPP)