3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant 聚宽平台中,频繁调用 get_ticks 导致内存占用过大并被系统强制杀掉进程(通常平台限制内存为 3G),是一个非常常见的问题。这通常并不是 get_ticks 本身存在恶意的内存泄漏,而是由 Python 的内存管理机制以及平台的底层缓存机制共同导致的。
del 之后内存依然没有释放?get_ticks 时,底层可能会将这些庞大的 tick 数据缓存起来,导致即使你在应用层 del 了变量,底层缓存依然持有对这些数据的引用,内存无法释放。del ticks 仅仅是删除了变量名对对象的引用,如果存在循环引用或底层缓存引用,对象不会被销毁。此外,Python 的垃圾回收并不总是实时的,在密集循环中可能来不及回收就触发了平台的内存上限。要彻底解决这个问题,建议结合以下几种方法对代码进行优化:
在策略的 initialize 函数中调用 disable_cache()。这会关闭系统的默认缓存机制,防止底层悄悄囤积数据。注意:关闭缓存可能会导致策略整体运行速度有所下降,但能有效控制内存。
def initialize(context):
# 关闭缓存,防止底层缓存大量 tick 数据导致内存超限
disable_cache()
# 其他初始化代码...
在循环获取每只股票的 tick 数据并在处理完毕后,除了使用 del,还可以引入 gc 模块,手动强制进行垃圾回收。
import gc
def handle_data(context, data):
stocks = get_index_stocks('000300.XSHG')
for stock in stocks:
# 获取 tick 数据
ticks = get_ticks(stock, end_dt=context.current_dt, count=100)
# ... 进行你的数据处理逻辑 ...
# 处理完毕后,删除变量并强制回收内存
del ticks
gc.collect()
get_ticks 的参数df=False:默认情况下 df=False 返回的是 numpy.ndarray,这比 pandas.DataFrame (df=True) 的内存占用要小得多。如果不需要 DataFrame 的高级特性,尽量使用 numpy 数组。fields):默认会返回很多字段(如买五卖五等)。如果你只需要最新价和成交量,可以通过 fields 参数限制返回的数据列,大幅减少内存开销。# 仅获取时间和最新价,且返回 numpy 数组
ticks = get_ticks(stock, end_dt=context.current_dt, count=100, fields=['time', 'current'], df=False)
尽量避免一次性获取过长时间跨度的 tick 数据。如果必须处理大量数据,考虑将大时间段拆分为多个小时间段,分批获取、分批处理、分批释放。
在处理 Tick 级别的高频数据时,内存管理尤为重要。通过 disable_cache() + gc.collect() + 优化返回数据结构 的组合拳,基本可以彻底解决 get_ticks 导致的内存超限被杀进程的问题。