from:http://wangneng-168.iteye.com/blog/2100379
redis使用tcmalloc管理內存,當刪除了redis的key后,通過redis的info命令查看內存使用情況,發現內存並沒有釋放,但是采用默認的jemalloc就不會有這個問題
以下是采用tcmalloc后刪除key前和刪除key后通過info看到的內存情況:
刪除key前:
used_memory:13051400
used_memory_human:12.45M
used_memory_rss:16326656
used_memory_peak:13051400
used_memory_peak_human:12.45M
used_memory_lua:33792
mem_fragmentation_ratio:1.25
mem_allocator:tcmalloc-2.0
刪除key后
used_memory:835080
used_memory_human:815.51K
used_memory_rss:16392192
used_memory_peak:13051400
used_memory_peak_human:12.45M
used_memory_lua:33792
mem_fragmentation_ratio:19.63
mem_allocator:tcmalloc-2.0
以下是采用jemalloc后刪除key前和刪除key后通過info看到的內存情況:
刪除key前:
used_memory:13047176
used_memory_human:12.44M
used_memory_rss:14704640
used_memory_peak:13047176
used_memory_peak_human:12.44M
used_memory_lua:33792
mem_fragmentation_ratio:1.13
mem_allocator:jemalloc-3.6.0
刪除key后
used_memory:830696
used_memory_human:811.23K
used_memory_rss:2318336
used_memory_peak:13047176
used_memory_peak_human:12.44M
used_memory_lua:33792
mem_fragmentation_ratio:2.79
mem_allocator:jemalloc-3.6.0
從結果看,刪除大量的key后,采用jemalloc的redis分配的內存縮減為大約2M,而tcmalloc沒有變化
TcMalloc的原理參看:
其中提到:目前的tcmalloc版本不會把任何內存返還給操作系統,可見采用tcmalloc時redis實例占用的內存與redis使用內存的峰值有關
JeMalloc的原理可以參看:
http://club.alibabatech.org/article_detail.htm?articleId=36
其中提到:
回收流程大體和分配流程類似,有tcache機制的會將回收的塊進行緩存,沒有tcache機制的直接回收(不大於chunk的將對應的page狀態進行修改,回收對應的run;大於chunk的直接munmap)。需要關注的是jemalloc何時會將內存還給操作系統,因為ptmalloc中存在因為使用top_chunk機制(詳見華庭的文章)而使得內存無法還給操作系統的問題。目前看來,除了大內存直接munmap,jemalloc還有兩種機制可以釋放內存:
1. 當釋放時發現某個chunk的所有內存都已經為臟(即分配后又回收)就把整個chunk釋放;
2. 當arena中的page分配情況滿足一個閾值時對dirty page進行purge(通過調用madvise來進行)。這個閾值的具體含義是該arena中的dirty page大小已經達到一個chunk的大小且占到了active page的1/opt_lg_dirty_mult(默認為1/32)。active page的意思是已經正在使用中的run的page,而dirty page就是其中已經分配后又回收的page。
上述兩種機制保證了jemalloc不會出現類似ptmalloc中的內存無法交還給操作系統的問題
結論:慎用tcmalloc,采用jemalloc就好。