Python设置RLIMIT_DATA后启动新线程报错RuntimeError问题排查
首先明确:RLIMIT_DATA 限制的是进程数据段(包括堆、全局/静态变量等)的虚拟内存大小,而非实际物理内存占用(RSS)。你用mprofile检测到的68MiB是实际使用的物理内存,和虚拟内存限制不是同一概念。
触发RuntimeError: can't start new thread的核心原因和以下几点有关:
线程创建的虚拟内存依赖:Google Cloud Pub/Sub的Python客户端内部会使用线程池处理异步操作,创建新线程时需要为线程栈分配虚拟内存空间。虽然
RLIMIT_STACK控制单个线程栈的大小,但如果进程的RLIMIT_DATA软限制设置得过低,会压缩进程虚拟地址空间中可用于其他内存区域(包括线程栈)的空间,导致线程创建时无法分配足够的虚拟内存,进而触发错误。Python内存分配器的预申请行为:Python的内存分配器(如pymalloc)会预先向操作系统申请大块虚拟内存(即使实际未使用物理内存)。当
RLIMIT_DATA的软限制接近时,分配器可能无法申请到新的虚拟内存块,而线程创建过程中恰好需要这类内存分配,最终抛出线程创建失败的错误——哪怕实际物理内存还很充足。软限制的触发机制:
RLIMIT_DATA的软限制是进程会主动触发的阈值(达到后会返回ENOMEM错误),而硬限制是系统强制的上限。你提升硬限制没用,是因为问题出在软限制触发的内存分配阻塞,而非硬限制被打满;提升软限制后,分配器有足够的虚拟内存空间可以申请,线程创建所需的内存分配就能正常完成。
总结:你遇到的问题不是物理内存不足,而是RLIMIT_DATA软限制设置过低,导致进程虚拟内存空间分配受限,进而影响了线程创建时的内存申请流程。
内容的提问来源于stack exchange,提问作者karthik thotamgari

