启动start_communication后内存占用持续升高,疑与sio.emit有关
内存泄漏问题分析与解决
问题现象
启动start_communication后,内存占用从150MB持续攀升至600MB,其他含while循环的函数无此问题,怀疑由sio.emit导致。
代码中可能的问题点
- 冗余的音频数据转换:
代码里先把stream.read()获取的字节数据转成numpy数组,再转回字节,这一步完全多余,会频繁创建不必要的临时对象,增加GC回收压力。 - 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
相关产品推荐
相关产品推荐

