Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
こんにちは、マルチメディアサポートチームです。今回は、PlaySound API を繰り返し呼び出した場合に、Audiodg.exe のメモリ使用量が増加し続ける現象についてご説明します。
なお、本現象につきましては、音声の再生時のパフォーマンスを重視する必要があり、メモリ解放が低優先度となる仕様に基づく動作となります。
事象発生までの流れ
PlaySound API は、Windows にて特定の音データを再生するために利用する代表的なAPI です。
PlaySound function
https://msdn.microsoft.com/en-us/library/windows/desktop/dd743680(v=vs.85).aspx
このAPI は基本的に指定された音データのみを一度 再生します。そのため、継続的に音を再生する場合や複数の音源を再生する場合など、利用目的によっては、PlaySound API を繰り返して呼ぶ利用方法が考えられます。
ただ、繰り返して呼び出す利用方法にて、API の呼び出し間隔が(1 秒未満など) 短い場合は、時間の経過とともにOS 内のモジュールAudiodg.exe のメモリ使用量が徐々に増加する事象が発生します。この事象は、PlaySound が呼び出されている間は継続して発生します。
増加量の度合いは呼び出しの頻度や音データのサイズに影響されますが、目安として、50~100 ミリ秒程度の間隔でPlaySound API を繰り返し呼び出した場合、30~40 時間程度でAudiodg.exe のメモリ使用量が1 GB 単位に至ります。
事象の発生要因について
この事象は、Audiodg.exe が再生側のパフォーマンスを重視した処理を行っている結果として、メモリの解放処理が遅延しているために発生します。音声の再生には、周波数に応じたサンプリングデータ生成が必要です。もし処理が間に合わない場合には、正しい音が再生できないこととなるため、音声再生のパフォーマンスを重視する仕様となっております。
PlaySound API を呼び出した際は、OS 内の処理として、Windows オーディオ サービス (Audiosrv) がAudiodg.exe に対し呼び出し(RPC ※1) をかけます。Audiodg.exe は、その呼び出しに応じて、音の再生など必要な処理を行います。この際に、音データなど処理に必要なデータは(C++) オブジェクトとしてOS よりメモリ内に割り当てられています。
ただ、その再生処理が完了した後でも、Audiodg.exe は、その同じRPC 処理の中で割り当てられたメモリの開放を即座に行いません。これは、「音の再生」という優先度の高い処理を滞りなく実行するための、パフォーマンスの維持を考慮した結果の動作となっています。
その代わりAudiodg.exe は、後にメモリの開放を行うための印として、処理に利用したオブジェクトに対して、「利用済み」であることを表すフラグをセットします。
Audiodg.exe は、実際にメモリの開放を行う処理を、このフラグの有無をベースに、専用のスレッドを通して一定の間隔で行います。ただ、解放処理を実行するには、まずスレッドが開始できる状態である必要があります。
今回の事象が発生するような、短い間隔での音再生が繰り返されるAPI の利用方法では、Audiodg.exe にて専用スレッドの開始を行うためのリソースがない状況が続きます。その結果、解放処理は開始されず、メモリの割り当てのみが繰り返し行われ、メモリ使用量の増加が継続して発生します。
もし解放専用のスレッドが実行できる程度のリソースをAudiodg.exe が確保できる場合は、解放処理が始まり、メモリの開放が行われます。そのため、PlaySound API を実行しているプログラムが終了した場合、メモリ使用量の低下が見込まれます。
なお、この事象はあくまで後負荷の処理に起因した「メモリ使用量の増加」であるため、メモリ リークは発生しておりません。Audiodg.exe にて発生するメモリー リークについては、以下の既知の問題がありますが、この事象との関連性はございません。
Handle leak occurs in the Audiodg.exe process in Windows 7 or in Windows Server 2008 R2
対処法について
上記の詳細の通り、この事象は、メモリの開放を行う動作が実行されることで解消します。そのため、対処法としては、以下の方法が考えられます。
· PlaySound API を繰り返し呼び出す間隔を(数秒程度に) 広げ、解放処理を実行できる程度のリソースをAudiodg.exe で控えられるようにする
· PlaySound API を一定期間呼ばない処理を加える
· 以下のコマンドなどで、Windows オーディオ サービス(Audiosrv) を一度 停止し、強制的に割り当てられたメモリを解放した後、サービスを再開させる
Net stop audiosrv
Net start audiosrv
補足
※ 1: Remote Procedure Call (RPC) の概要については、以下のドキュメントをご参照ください。
Remote Procedure Call https://msdn.microsoft.com/en-us/library/windows/desktop/aa378651(v=vs.85).aspx