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

启动start_communication后内存占用持续升高,疑与sio.emit有关

内存泄漏问题分析与解决

问题现象

启动start_communication后,内存占用从150MB持续攀升至600MB,其他含while循环的函数无此问题,怀疑由sio.emit导致。

代码中可能的问题点

  1. 冗余的音频数据转换:
    代码里先把stream.read()获取的字节数据转成numpy数组,再转回字节,这一步完全多余,会频繁创建不必要的临时对象,增加GC回收压力。
  2. Socket.IO消息堆积:
    sio.emit默认异步发送,如果网络延迟或服务器处理不及时,未成功发送的消息会被客户端缓存,随着时间推移,缓存的消息越积越多,直接导致内存上涨——这是此类场景下内存泄漏的常见原因。

解决方案

1. 优化音频数据处理

直接使用stream.read()返回的原始字节数据,去掉冗余的numpy转换步骤:

def send_audio_e(self):
    p = pyaudio.PyAudio()
    stream = p.open(
        format=pyaudio.paInt16,
        channels=self.CHANNELS,
        rate=44100,
        input=True,
        frames_per_buffer=self.CHUNK,
    )

    try:
        while True:
            if self.is_running:
                # 直接使用原始字节数据,无需转换
                audio_data = stream.read(self.CHUNK)
                try:
                    sio.emit("audio_data", {"audio_data": audio_data})  
                except Exception as e:
                    print(e)
    except Exception as e:
        print("hata", e)
    finally:
        print("CLOSED")
        stream.stop_stream()
        stream.close()
        p.terminate()

2. 解决Socket.IO消息堆积问题

  • 添加发送回调与超时:
    给emit方法添加回调确认消息已被服务器接收,同时设置超时,避免无限制缓存未发送消息:
    # 消息发送成功后的回调(可留空)
    def on_audio_sent(*args):
        pass
    
    # 设置5秒超时,超时则丢弃当前消息
    sio.emit("audio_data", {"audio_data": audio_data}, callback=on_audio_sent, timeout=5)
    
  • 调整Socket.IO客户端配置:
    初始化sio时限制消息缓存大小,或禁用自动重连时的消息缓存:
    # 示例:初始化时设置最大缓存消息数为100条
    sio = socketio.Client(reconnection=True, max_buffer_size=100)
    
  • 控制发送频率:
    如果音频采样率过高,可合并多帧数据后再发送,减少emit调用次数,降低消息堆积概率。

3. 确保线程能正确退出

检查self.is_running的赋值逻辑,确保停止通信时能将其设为False,让while循环正常终止,避免线程长期运行占用资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:20:16