ASR项目实战-交付过程中遇到的疑似内存泄漏问题

这篇具有很好参考价值的文章主要介绍了ASR项目实战-交付过程中遇到的疑似内存泄漏问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Kaldi实现语音识别时,需要引入一款名为OpenFST的开源软件,本文中提到的内存问题,即和这款软件相关。
考虑到过程比较曲折,内容相对比较长,因此先说结论。

在做长时间的语音识别时,集成了Kaldi和OpenFST的进程将会占用远超出预期的内存,这个现象可能和OpenFST、glibc的实现相关,未必是内存泄漏。

进程占用超出大量内存的原因,简单说一下:

  • OpenFST在工作过程中,申请了很多内存,同时产生了很多内存碎片。
  • 语音识别进程默认使用的glibc无法合并相关的碎片,因而即便相关的内存已经被释放,但glibc仍然无法向操作系统释放内存。
  • 因此,在使用top观察进程的虚拟内存时,发现进程占用的内存会时间增长而一直增长,进而会被判定为疑似内存泄漏。

当然了,经过分析后,现在可以确认前述现象为非问题,只需要调整机器规格即可解决问题,但如前所述,整个过程比较曲折,这里记录下来,以备后察。

测试同事反馈,在性能环境上,执行压测过程中,算法服务出现了重启的现象。这是一个大问题,于是在第一时间联系我进行定位。

观察测试同事的压测环境,发现确实如测试同事所说,压测开始后,算法服务占用的虚拟内存以肉眼可见的速度缓慢增长。通过操作系统的硬件资源监控平台,观察进程一段时间内虚拟内存的占用趋势,发现没有进入平稳状态的迹象。最终观察的结果是算法服务占用的虚拟内存一直在增长,最终随着进程异常退出而结束。

我们的算法服务由业务代码、算法推断代码和机器学习模型组成。

  • 业务代码使用Java开发,编译、构建成jar文件,运行时由JVM加载并运行。
  • 算法推断代码使用C++开发,基于JNA规范,Java代码暴露接口,编译、构建成动态库,运行时由JVM加载。
  • 机器学习模型,其实是几个数据文件,运行时由算法推断代码读取并使用。

考虑到当前版本中,算法推断代码和数据模型并没有引入新的变动点,因此重启现象的定位工作从算法服务的业务代码入手。

检查业务流程

首先分析业务流程。
本版本引入了长语音文件转写的特性,因此业务代码有比较大的变动。前期在实现时,为了简化实现方案,在文件转写的过程中,内存里缓存了很多数据。通过分析这部分实现,没有发现对象生命周期超长的现象,但仍然做了改进,将内存中缓存的数据交给数据库来缓存。
这时在开发环境中复现操作,观察内存增长的曲线,发现增长趋势有所减缓,但算法服务占用的虚拟内存,仍然在涨,没有收敛的迹象,因此仍然需要继续分析。

检查JVM配置

算法服务使用的Java堆的参数中,堆的最大值,比较大。本质上讲,经过上一环节的优化后,算法服务的业务代码中不涉及大量Java对象的生成,因此运行时,Java堆可以使用较少的内存。
修改算法服务Java堆的参数后,在开发环境中复现操作,基本功能正常。此外,使用jstat -gcutil <pid> 1000 1000观察,确认JVM的GC操作运行正常,未发现异常现象。
长时间观察内存增长的曲线,发现没有明显改进,算法服务占用的虚拟内存,仍然在涨,没有收敛的迹象,因此仍然需要继续分析。

分析Java堆内存

内存问题分析到现在, 光靠看代码已经不解决问题,是时候召唤专业工具上场了。
对于Java应用的内存,jmap和MAT是一对完美的组合。
执行如下命令,导出Java应用进程的堆。

jmap -dump:live,format=b,file=dump001.bin <pid>

为了方便对比分析,一般至少需要导出四次堆。

  • Java应用进程启动完毕。导出的堆文件命名为dump001.bin
  • 压力测试持续一段时间之后。假如可以准确的控制执行的压力测试的用例数量,则可以使用用例数量来衡量。导出的堆文件命名为dump002.bin
  • 在上次导出操作后,压力测试的TPS保持稳定,继续持续一段时间或者执行完毕一部分用例之后,再提取一次堆。导出的堆文件命名为dump003.bin
  • 停止压力测试,等待一段时间,此时再提取一次堆。导出的堆文件命名为dump004.bin

将上述导出的三个文件,dump001.bindump002.bindump003.bin一起导入至MAT。MAT基于eclipse开发,在配置文件中指定了Java堆的最小值和最大值,可以视堆文件的大小,酌情修改MAT的JVM参数。
使用MAT的histogram功能,对这三个文件进行对比。

  • 对比dump001.bindump002.bin,可以确认业务启动后,堆中出现的Java对象的类型和数量。结合业务用例和代码,可以确认对象的类型和数量,是否符合预期。
  • 对比dump002.bindump003.bin,可以确认业务运行平稳后,堆中出现的Java对象的类型和数量,是否稳定。假如压力测试的TPS保持稳定,则从理论上讲,Java堆中出现、湮灭的对象的数量应当是稳定的,对象的数量不会有太大的变化。
  • 对比dump003.bindump004.bin,确认Java堆中业务相关的对象的类型和数量,是否有较大的下降。一般而言,运行过程中的Java对象,应当在压力测试结束后,在JVM的垃圾回收操作中被回收掉,不应存在大量的残留。
  • 对比dump001.bindump004.bin,由于压力测试已经结束,Java堆中对象的类型和数量,二者之间的差异应当比较小。

使用jmap命令,导出堆,使用MAT分析。
反复拨测业务,使用jstat命令观察GC情况。
修改代码的实现,降低内存占用。

问题仍然存在。
算法同事参与分析,使用valgrind分析,memcheck和massif,未发现内存泄漏点。
使用pmap观察,Java进程的内存空间,发现很多64MB的块。在网上找到很多文章。

缩小变量的值
关闭线程分配器,均无效

使用tcmalloc分配器,内存仍然会涨,并且偶发性的进程异常退出,因此本方案不能在生产环境使用。

最终,定期调用malloc_trim,定期向操作系统释放内存。

总结

无法更新GPU驱动的版本,流程操作比较复杂,时间和技术上均不允许。文章来源地址https://www.toymoban.com/news/detail-773776.html

参考资料

Kaldi

  • Kaldi
  • Kaldi内存泄漏问题排查
  • OpenFst Library
  • openfst 介绍
  • openfst 学习笔记(一)
  • 什么是 openFST,如何应用于语音识别?

glibc

  • Java所占内存中神奇的64MB
  • glibc内存管理那些事儿
  • linux c、c++高并发服务内存泄露追踪分析

JVM

  • JAVA堆外内存的简介和使用
  • JAVA堆外内存
  • Java堆外内存之突破JVM枷锁

valgrind

  • valgrind massif内存分析
  • 通过Valgrind的Massif工具进行C++内存使用分析
  • valgrind-memcheck功能的使用和分析
  • 施昌权--淘宝卫霍
  • 如何使用Valgrind memcheck工具进行C/C++的内存泄漏检测
  • How to Detect Memory Leaks Using Valgrind memcheck Tool for C / C++

malloc

  • TCMalloc原理
  • 图解 TCMalloc
  • 内存优化总结:ptmalloc、tcmalloc和jemalloc
  • glibc内存管理ptmalloc底层实现
  • ptmalloc总结
  • 使用 malloc_trim()
  • malloc_trim
  • 几个有用的 malloc 环境变量
  • Malloc Tunable Parameters

pmap

  • Linux进程内存分析pmap命令
  • pmap用法小计

到了这里,关于ASR项目实战-交付过程中遇到的疑似内存泄漏问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 开源WebRTC库放大器模式在采集桌面图像时遇到的DPI缩放与内存泄漏问题排查

    目录 1、在非100%的显示比例下放大器采集到的桌面图像不全问题 1.1、通过manifest文件禁止系统对软件进行缩放

    2024年02月08日
    浏览(43)
  • 记一次项目内存优化--内存泄漏

    主要是与某个版本作基准进行对比(一般是最新版本的前一个版本作原数据),优化后,PSS有所下降,线上OOM率减少(Bugly版本对比),泄漏点减少(从捉取一些线上上传回来的内存堆栈信息分析,或本地测试后dump下hprof文件分析)。 了解什么是内存泄漏 了解虚拟机中的对象

    2024年02月12日
    浏览(77)
  • ASR项目实战-语音识别

    本文深入探讨语音识别处理环节。 本阶段的重点特性为语音识别、VAD、热词、文本的时间偏移、讲话人的识别等。 业界流派众多,比如Kaldi、端到端等,具体选择哪一种,需要综合考虑人员能力、训练数据量和质量、硬件设施、交付周期等,作出相对合理的交付规划。 基于

    2024年02月04日
    浏览(49)
  • ASR项目实战-产品分析

    分析Google、讯飞、百度、阿里、QQ、搜狗等大厂的ASR服务,可以罗列出一款ASR服务所需要具备的能力。 ASR云服务产品,从用户体验、时效性、音频时长,可以划分为如下几类: 实时短音频转写,可以用于支撑输入法、搜索、导航等场景。 实时长音频转写,可以用于支撑视频

    2024年02月04日
    浏览(47)
  • ASR项目实战-数据

    使用机器学习方法来训练模型,使用训练得到的模型来预测语音数据,进而得到识别的结果文本,这是实现语音识别产品的一般思路。 本文着重介绍通用语音识别产品对于数据的诉求。 相关要求,如下: 地域,需要覆盖使用人群所在的地域,且数据的比例适中。 口音,需要

    2024年02月04日
    浏览(42)
  • ASR项目实战-决策点

    针对语音识别的产品,分别记录设计、开发过程中的决策点。 对于实时语音识别来说,客户端和服务端之间实时交换语音数据和识别的结果。 客户端在启动识别时,即开始发送语音数据,期望在等待较短的时间后,即收到最初的识别结果。第一段语音数据和第一个识别结果

    2024年02月04日
    浏览(53)
  • ASR项目实战-架构设计

    一般而言,业务诉求作为架构设计的输入。 对于语音识别产品而言,需满足的需求,举例如下: 功能需求 文件转写。 长文件转写,时长大于60秒,小于X小时,X可以指定为5。 短文件转写,时长小于60秒。 实时语音识别。 长语音识别,时长大于60秒,小于Y小时,Y可以指定为

    2024年02月04日
    浏览(44)
  • ASR项目实战-后处理

    本文深入探讨后处理环节。 在本环节要处理的重要特性有分词、断句、标点符号、大小写、数字等的格式归一等。 和NLP、搜索等场景下的分词含义不同。对于拼音类的语言,比如英语、法语等,句子由多个单词组成,语音输出的结果,需要按需在各个单词之间补充或者去掉

    2024年02月04日
    浏览(38)
  • 项目性能优化-内存泄漏检测与修改

    最近终于有空优化一波项目的性能了,第一波借助Android Studio自带的Profiler工具检测内存泄漏。 右侧带有绿色原点的就是此时运行的Profiler的SESSION,点击右侧MEMORY进入内存监控的详情模块 第三步中抓取一段时间后,会自动停止,并打开Heap Dump文件 可以看到抓取到2个会导致内存

    2024年02月11日
    浏览(55)
  • ASR项目实战-前处理

    本文深入探讨前处理环节。 首先介绍一些基本的名词,比如 文件名后缀 文件格式 音频格式 采样率和位深 常见的音频文件,比如 .wav 、 .mp3 、 .m4a 、 .wma 等,这些都代表什么? 仅仅是这类音频文件的后缀而已,不一定和音频文件的编码、音频数据的编码相关。 举例说明:

    2024年02月04日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包