Windows下KMeans的内存泄漏是Intell 由于MKL线程池释放不当,RSS在循环调用过程中持续上升,GC无效;确认方法为NP.__config__.show()含mkl_)rt,该解决方案包括禁用MKL多线程(OMP_NUM_THREADS=1)、替换OpenBLAS或MiniBatchKMeans。KMeans在Windows上反复调用,导致内存持续上升
这不是代码写错了,而是Intel Windows下线程池中MKL未正确释放导致资源滞留。只要您在Windows上使用它sklearn.cluster.KMeans做循环训练(如批量聚类、Jupyter反复运行、Flask服务中高频调用),内存只会增加,即使是显式del kmeans或调用gc.collect()也无效。
- 先确认是否中招:
import numpy as np; np.__config__.show()输出含mkl_rt或intel是MKL后端 - 监控验证:使用
psutil.Process().memory_info().rss循环前后打点,可以看到 RSS 持续爬升 - 不是Python对象泄漏,
objgraph.show_growth()几乎看不到异常类型的增长
基本解决办法是让底层数学库不走MKL的并行路径。两种实用路径效果明确:
- NumPy安装OpenBLAS版:卸载当前numpy,使用
pip install numpy --no-binary=numpy强制编译,或直接安装openblas-numpy包(Python版本需要匹配) - 运行前禁用MKL多线程:
import os; os.environ['OMP_NUM_THREADS'] = '1'; os.environ['MKL_NUM_THREADS'] = '1',必须在import numpy之前设 - 注:设置环境变量后,需要重启Python进程才能生效,Jupyter需要重启kernel
MiniBatchKMeans 内存本身更友好,更依赖MKL——它根据批次更新纹理,不一次加载所有数据参与距离计算,自然缓解线程池压力。
Python 3.14.2
Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。
下载- 把
KMeans(n_init=10)换成MiniBatchKMeans(n_init=3, batch_size=1000),内存峰值通常下降40%以上 - 避免设
max_iter过大(默认100),建议压到20–50,配合reassignment_ratio=0.01防止无效迭代 - 训练结束后,记得清空内部缓存:
mbk._centers = None; mbk._n_threads = None(私有属性,慎用但有效)
如果你在ARM或旧版Glibc的Linux上看到的话 libgomp-*.so: cannot allocate memory in static TLS block,这不是scikit-learn的问题,而是OpenMP运行时与系统TLS机制发生冲突。
立即学习“Python免费学习笔记(深入);
- 临时修复:启动前添加
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libgomp.so.1(路径按实际调整) - 长期解决方案:将glibc升级到2.32+,或改用
threadpoolctl统一管控:from threadpoolctl import threadpool_limits; with threadpool_limits(limits=1, user_api='openmp'): - 别碰
export OMP_WAIT_POLICY=PASSIVE这种参数,治标不治本,可能会减速