帮 BentoML 和 @frostming 查社区一个内存泄漏的问题
https://github.com/bentoml/BentoML/issues/4760
基本上可以确定是 glibc malloc 的老问题。我懒得写更详细的 trace 脚本了,就直接聊聊这个经典的 Python 问题吧
这个问题的核心是 glibc malloc 的 free 不会直接将内存归还给系统,而是会试图 Merge 成一个 big chunk 归还,但是这里存在一个问题,如果分配的内存过于碎片化导致无法 merge 成一个连续的 big chunk ,那么内存虽然被 free 了但是依旧没有归还给系统。这就是内存泄漏
Python 自己封装了一套内存分配器来试图解决问题。解决方式是直接调用 munmap 来强制归还,FYI https://github.com/python/cpython/blob/main/Objects/obmalloc.c#L380-L395
而且 CPython 提供了自己封装的 allocator 接口给扩展用
但是问题在这,扩展不一定会用,也有很大概率是 malloc/free 直接调用,那么又回到了最开始的情况
解决方案常见的三种
1. let it crash,上 memory limit,挂了重拉(什么 cloud native
2. ctype binding glibc ,然后 malloc_trim 定时调用
3. 换用 tcmalloc 或者 jemalloc(我自己常用 tcmalloc (LD_PRELOAD 直接换
其余社区的一些反馈 https://github.com/protocolbuffers/protobuf/issues/10088#issuecomment-1587627538
https://github.com/bentoml/BentoML/issues/4760
基本上可以确定是 glibc malloc 的老问题。我懒得写更详细的 trace 脚本了,就直接聊聊这个经典的 Python 问题吧
这个问题的核心是 glibc malloc 的 free 不会直接将内存归还给系统,而是会试图 Merge 成一个 big chunk 归还,但是这里存在一个问题,如果分配的内存过于碎片化导致无法 merge 成一个连续的 big chunk ,那么内存虽然被 free 了但是依旧没有归还给系统。这就是内存泄漏
Python 自己封装了一套内存分配器来试图解决问题。解决方式是直接调用 munmap 来强制归还,FYI https://github.com/python/cpython/blob/main/Objects/obmalloc.c#L380-L395
而且 CPython 提供了自己封装的 allocator 接口给扩展用
但是问题在这,扩展不一定会用,也有很大概率是 malloc/free 直接调用,那么又回到了最开始的情况
解决方案常见的三种
1. let it crash,上 memory limit,挂了重拉(什么 cloud native
2. ctype binding glibc ,然后 malloc_trim 定时调用
3. 换用 tcmalloc 或者 jemalloc(我自己常用 tcmalloc (LD_PRELOAD 直接换
其余社区的一些反馈 https://github.com/protocolbuffers/protobuf/issues/10088#issuecomment-1587627538