You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中str.lower()方法引发内存泄漏的原因及解决办法

问题:str.lower()处理大量字符串时内存占用飙升的原因与解决方法

处理大型DataFrame时发现:对字符串特征应用str.lower()方法后,内存占用直接飙升至10GB。为排查问题,我做了以下简化测试:

测试步骤

  1. 查看进程初始内存占用
import sys
import psutil
from guppy import hpy
import gc

def print_in_mb(n):
    print(n // (1024 * 1024), 'Mb')

def print_object_size(obj):
    print_in_mb(sys.getsizeof(obj))

print_in_mb(psutil.Process().memory_info().rss)
# 输出:64 Mb
  1. 创建包含大量重复字符串的元组
a = tuple('HeLlO, WoRlD' for _ in range(10_000_000))
print_object_size(a)
# 输出:76 Mb

print_in_mb(psutil.Process().memory_info().rss)
# 输出:142 Mb
  1. 对元组中每个字符串调用lower()方法
a = tuple(x.lower() for x in a)
print_object_size(a)
# 输出:76 Mb

print_in_mb(psutil.Process().memory_info().rss)
# 输出:764 Mb

调用lower()后,程序内存占用骤升至764Mb,远超存储对象所需的内存,且调用gc.collect()也无法释放这部分内存。

疑问

为什么调用str.lower()/str.upper()处理大量字符串时会占用这么多额外内存?有没有办法避免此类不必要的内存分配?

补充说明

这个问题仅在处理大量独立字符串时出现,直接对单个大字符串调用lower()则不会有额外内存占用:

x = 'Aa' * 100_000_000
print_object_size(x) 
# 输出:190 Mb

print_in_mb(psutil.Process().memory_info().rss)
# 输出:955 Mb

y = x.lower()
print_object_size(x)
# 输出:190 Mb

print_in_mb(psutil.Process().memory_info().rss)
# 输出:1145 Mb - 符合预期!

原因分析

  1. 字符串驻留机制失效:Python默认会对短字面量字符串做字符串驻留,也就是相同内容的字符串共享同一个内存对象。你创建元组时用的是字面量'HeLlO, WoRlD',所以1000万个元素其实指向同一个字符串对象,内存占用极低。但调用x.lower()后生成的'hello, world'是动态生成的字符串,Python不会自动对这类动态字符串做驻留,导致1000万个独立的字符串对象被创建——每个对象除了字符数据外,还有对象头、长度等元数据开销,累加起来就是内存暴增的核心原因。
  2. 内存碎片与GC回收限制:大量小字符串对象会造成内存碎片,即使调用gc.collect(),CPython的内存分配器也可能无法及时回收碎片化内存,导致常驻内存(RSS)居高不下。

解决方法

  1. 手动启用字符串驻留:用sys.intern()对生成的小写字符串做驻留,让相同内容的字符串共享内存:
import sys
a = tuple(sys.intern(x.lower()) for x in a)

处理后所有'hello, world'会指向同一个内存对象,内存占用会回到接近初始创建元组时的水平。

  1. 利用Pandas的优化特性:如果是处理DataFrame,直接用df['col'].str.lower(),底层会做批量优化;如果字符串重复率高,后续可以加上astype('category')做字典编码,进一步压缩内存。

  2. 使用高效字符串存储类型:对于大量重复字符串场景,用Pandas的StringDtype(1.0+版本支持)或numpy的字符串数组,这类存储会自动对重复字符串做编码,大幅降低内存开销。


内容的提问来源于stack exchange,提问作者mz2300

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:08:07