本文主要是介绍【华为 Hicar 音频卡顿】gc 导致音频卡顿问题分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、问题描述:
180S MCE 车机,有线音频卡顿的问题分析如下:
可以看出,车机从手机接收数据时是正常接收的,并未出来延时。
卡顿出现在往StreamBuffer写第36257帧
数据时,触发了GC Alloc,该回收内存动作耗时40.910ms
,
接着在 GC 动作结束后,重新写第36257帧
数据,
导致播放第36257帧数据时出现卡顿。
log 分析如下;(附件中 logcat.log.04 )
// 从手机接收到第 36257 帧数据
07-31 10:27:18.803 4449 1742 D DMSDP_TRANSPORT_DATASESSION: RTPDataReceiver MSG_TYPE_ACCESSUNIT session=5*******6,timeUs=3737145700,len=335,seqnum=36257,usage=1,nowUs=1598464592// 从手机接收到第 36258 帧数据
07-31 10:27:18.825 4449 1742 D DMSDP_TRANSPORT_DATASESSION: RTPDataReceiver MSG_TYPE_ACCESSUNIT session=5*******6,timeUs=3737166755,len=366,seqnum=36258,usage=1,nowUs=1598487090// 从手机接收到第 36259 帧数据
07-31 10:27:18.849 4449 1742 D DMSDP_TRANSPORT_DATASESSION: RTPDataReceiver MSG_TYPE_ACCESSUNIT session=5*******6,timeUs=3737188088,len=344,seqnum=36259,usage=1,nowUs=1598510692
07-31 10:27:18.864 4449 1742 D DMSDP_TRANSPORT_DATASESSION: RTPDataReceiver MSG_TYPE_ACCESSUNIT session=5*******6,timeUs=3737209633,len=350,seqnum=36260,usage=1,nowUs=1598526215// 播放音乐,写入streamBuffer,开始写第 36257 帧数据 ,触发 GC Alloc 《======================
07-31 10:27:19.063 4449 2106 D DMSDP_TRANSPORT_DATASESSION: AudioPlay audioSdk session=5*******6,type=3,Length=4096,timeUs=3737145700,usage=1 // 《====写第 36257 帧数据=======
07-31 10:27:19.063 4449 2106 D VirtualAudio: WriteStreamBuffer:start WriteStreamBuffer07-31 10:27:19.064 4449 2106 I zygote : Starting a blocking GC Alloc
07-31 10:27:19.064 4449 2106 I zygote : Starting a blocking GC Alloc
07-31 10:27:19.070 4449 1734 I zygote : Waiting for a blocking GC Alloc// 从手机接收到第 36270 帧数据
07-31 10:27:19.075 4449 1742 D DMSDP_TRANSPORT_DATASESSION: RTPDataReceiver MSG_TYPE_ACCESSUNIT session=5*******6,timeUs=3737421944,len=360,seqnum=36270,usage=1,nowUs=1598737115// 从手机接收到第 36271 帧数据
07-31 10:27:19.097 4449 1742 D DMSDP_TRANSPORT_DATASESSION: RTPDataReceiver MSG_TYPE_ACCESSUNIT session=5*******6,timeUs=3737444166,len=337,seqnum=36271,usage=1,nowUs=1598758453// 写第 36257 帧数据时 ,触发的 GC Alloc 动作如下,耗时 40.910ms
07-31 10:27:19.105 4449 2106 I zygote : Alloc concurrent copying GC freed 36392(15MB) AllocSpace objects, 0(0B) LOS objects, 93% free, 1274KB/19MB, paused 152us total 40.910ms
07-31 10:27:19.105 4449 1734 I zygote : WaitForGcToComplete blocked Alloc on HeapTrim for 35.768ms
07-31 10:27:19.105 4449 1734 I zygote : Starting a blocking GC Alloc
07-31 10:27:19.106 4449 2106 D DMSDP : VirtualAudioProxy:write cost:0,play positon is:37116928
07-31 10:27:19.106 4449 2106 D DMSDP : VirtualAudioProxy:writeAvSyncData cost:1,Acts is:3737145700,Apts is:1598767000 //《====重写第 36257 帧数据=======07-31 10:27:19.106 4449 2106 I VirtualAudioJni: WriteStreamToJni:size is:4096
07-31 10:27:19.107 4449 2106 I VirtualAudioJni: WriteStreamBuffer:byteSize is:4096// 播放音乐,写入streamBuffer,开始写第 36258 帧数据 ,正常播放 《======================
07-31 10:27:19.108 4449 2106 D DMSDP_TRANSPORT_DATASESSION: AudioPlay audioSdk session=5*******6,type=3,Length=4096,timeUs=3737166755,usage=1
07-31 10:27:19.108 4449 2106 I VirtualAudio: GetInstance:GetInstance
07-31 10:27:19.108 4449 2106 D VirtualAudio: WriteStreamBuffer:start WriteStreamBuffer
07-31 10:27:19.109 4449 2106 D DMSDP : VirtualAudioProxy:write cost:0,play positon is:37117120
07-31 10:27:19.110 4449 2106 D DMSDP : VirtualAudioProxy:writeAvSyncData cost:1,Acts is:3737166755,Apts is:1598770000
07-31 10:27:19.110 4449 2106 I VirtualAudioJni: WriteStreamToJni:size is:4096
07-31 10:27:19.110 4449 2106 I VirtualAudioJni: WriteStreamBuffer:byteSize is:4096// 播放音乐,写入streamBuffer,开始写第 36259 帧数据 ,正常播放 《======================
07-31 10:27:19.111 4449 2106 D DMSDP_TRANSPORT_DATASESSION: AudioPlay audioSdk session=5*******6,type=3,Length=4096,timeUs=3737188088,usage=1
07-31 10:27:19.112 4449 2106 I VirtualAudio: GetInstance:GetInstance
07-31 10:27:19.112 4449 2106 D VirtualAudio: WriteStreamBuffer:start WriteStreamBuffer// 从手机接收到第 36272 帧数据
07-31 10:27:19.119 4449 1742 D DMSDP_TRANSPORT_DATASESSION: RTPDataReceiver MSG_TYPE_ACCESSUNIT session=5*******6,timeUs=3737464844,len=353,seqnum=36272,usage=1,nowUs=1598781401
从问题分析看起来是,HEAP 内存分配失败,但系统明明还有19MB内存,但就是分配不了。
二、分析过程
刚开始疑会不会是内存泄漏,经过分析和内存泄漏无关,
这里记录下使用过的命令:
- 查看系统单个进程内存上限:
C:\Users\ciellee>adb shell
msm8937_32go:/ # getprop|grep heapgrowthlimit
[dalvik.vm.heapgrowthlimit]: [128m]
msm8937_32go:/ #
- top 命令查看当前系统进程信息
Tasks: 481 total, 7 running, 470 sleeping, 0 stopped, 0 zombie
Mem: 1928552k total, 1723024k used, 205528k free, 32672k buffers
Swap: 0k total, 0k used, 0k free, 663028k cached
800%cpu 85%user 21%nice 69%sys 615%idle 0%iow 0%irq 9%sirq 0%hostPID USER PR NI VIRT RES SHR S[%CPU] %MEM TIME+ ARGS2820 system 10 -10 1.0G 70M 30M S 33.3 3.7 10:19.02 com.huawei.dmsdpdevice388 logd 30 10 22M 7.9M 1.3M S 30.6 0.4 3:29.10 logd2886 u0_a12 10 -10 1.1G 52M 24M S 17.0 2.7 1:03.82 com.huawei.hisight2347 system 20 0 1.1G 79M 30M S 15.3 4.1 39:07.83 com.qinggan.speechservice597 system 20 0 44M 12M 6.3M S 9.0 0.6 4:08.99 hal-server2081 root 30 10 5.1M 1.6M 1.2M S 8.0 0.0 1:08.82 logcat -b main -b system -b crash -b radio -f /private/+
- 查看 com.huawei.dmsdpdevice 进程的内存信息
msm8937_32go:/ # dumpsys meminfo com.huawei.dmsdpdevice
Applications Memory Usage (in Kilobytes):
Uptime: 16231918 Realtime: 16231918** MEMINFO in pid 2820 [com.huawei.dmsdpdevice] **Pss Private Private SwapPss Heap Heap HeapTotal Dirty Clean Dirty Size Alloc Free------ ------ ------ ------ ------ ------ ------Native Heap 4177 4156 0 0 12160 10166 1993Dalvik Heap 702 684 0 0 19750 1318 18432Dalvik Other 585 584 0 0Stack 296 296 0 0Ashmem 10 0 0 0Other dev 5 0 4 0.so mmap 484 112 32 0.jar mmap 20 20 0 0.apk mmap 2702 112 2492 0.dex mmap 2996 4 2668 0.oat mmap 241 0 56 0.art mmap 1009 628 184 0Other mmap 132 4 72 0Unknown 353 352 0 0TOTAL 13712 6952 5508 0 31910 11484 20425App SummaryPss(KB)------Java Heap: 1496Native Heap: 4156Code: 5496Stack: 296Graphics: 0Private Other: 1016System: 1252TOTAL: 13712 TOTAL SWAP PSS: 0ObjectsViews: 0 ViewRootImpl: 0AppContexts: 3 Activities: 0Assets: 2 AssetManagers: 2Local Binders: 40 Proxy Binders: 25Parcel memory: 8 Parcel count: 34Death Recipients: 9 OpenSSL Sockets: 0WebViews: 0SQLMEMORY_USED: 0PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0msm8937_32go:/ #
- 抓取 hprof 文件
C:\Users\ciellee>adb shell am dumpheap 2820 /data/2820_on.hprof
C:\Users\ciellee>adb shell am dumpheap 2820 /data/2820_off.hprof
C:\Users\ciellee>adb shell
msm8937_32go:/ # ls -al data/2820*
-rwxrwx--- 1 root root 27170341 2020-08-03 14:22 data/2820_off.hprof // 停止放歌时
-rwxrwx--- 1 root root 23286925 2020-08-03 14:22 data/2820_on.hprof // 正在放歌时
msm8937_32go:/ #//转换 hprof 文件,这样 MemoryAnalyzer 才能打开
C:\Users\ciellee\Desktop\hprof>hprof-conv 2820_off.hprof 2820_off_1.hprof
C:\Users\ciellee\Desktop\hprof>hprof-conv 2820_on.hprof 2820_on_1.hprof
内存分析工具下载地址: http://ftp.yz.yamagata-u.ac.jp/pub/eclipse/mat/1.10.0/rcp/MemoryAnalyzer-1.10.0.20200225-win32.win32.x86_64.zip
需要JDK 环境,下载地址:https://www.oracle.com/java/technologies/javase-jdk14-downloads.html
三、解决方法
经过上面一系列的分析,看起来都没有问题,APK也没有内存泄漏的问题,
问题就是 heap 明明有内存,但就是不让分配。
因为我们车机同时做 8937 和 8950平台,了解到 8950 上没有这样的问题,
最终通过 adb shell getprop > prop.txt 分别获取到 8937 和 8950 平台的 prop 属性。
对比属性发现了如下差异:(左8950, 右8937)
可以看出,8937 的堆内存配置256M, 这个是按 1 G RAM 的配置来走的,
而 8950平台 的512M 才是按 2G RAM 来配置的。
我们8937的车机Flash 是 16+2 的,需要按 2G RAM 来配置,修改如下:
导入修改,编译版本后,复测没有GC问题了,也没有卡顿的问题了。
有关heap 的知识我也不怎么懂,有兴趣可以参考下面两篇文章,写得很好
参考:
《关于build.prop原始Dalvik虚拟机设定与调整》
《虚拟内存修改方案dalvik.vm.heapsize 》
这篇关于【华为 Hicar 音频卡顿】gc 导致音频卡顿问题分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!