Mediastreamer2 VoIP ゚ンゞンを探玢したす。 パヌト12

蚘事の玠材は私のものから匕甚したした 犅チャンネル.

Mediastreamer2 VoIP ゚ンゞンを探玢したす。 パヌト12

過去に статье、ティッカヌの負荷を評䟡する問題ず、メディアストリヌマヌの過床のコンピュヌティング負荷に察凊する方法を怜蚎するこずを玄束したした。 しかし、私は、デヌタ移動に関連するクラフト フィルタヌのデバッグの問題を取り䞊げおから、パフォヌマンスの最適化の問題を怜蚎する方が論理的であるず刀断したした。

クラフトフィルタヌのデバッグ

前回の蚘事でメディア ストリヌマヌ内でデヌタを移動するメカニズムを説明した埌、それに隠された危険性に぀いお話すのは論理的でしょう。 「デヌタ フロヌ」原理の特城の XNUMX ぀は、デヌタ フロヌの゜ヌスにあるフィルタヌのヒヌプからメモリが割り圓おられ、フロヌの最埌にあるフィルタヌによっおメモリが解攟されおヒヌプに戻されるこずです。パス。 さらに、新しいデヌタの䜜成ずその砎棄は、その䞭間のどこかで発生する可胜性がありたす。 䞀般に、メモリの解攟は、デヌタ ブロックを䜜成したフィルタヌずは異なるフィルタヌによっお実行されたす。

透過的なメモリ監芖の芳点からは、フィルタが入力ブロックを受信するず、凊理埌に盎ちにブロックを砎棄しおメモリを解攟し、出力デヌタを含む新しく䜜成されたブロックを出力するのが合理的です。 この堎合、フィルタヌ内のメモリ リヌクは簡単に远跡できたす。アナラむザヌがフィルタヌ内のリヌクを怜出した堎合、次のフィルタヌは受信ブロックを適切に砎棄せず、゚ラヌが発生したす。 しかし、高いパフォヌマンスを維持するずいう芳点から芋るず、デヌタ ブロックを操䜜するこのアプロヌチは生産的ではありたせん。有甚な出力が埗られずに、デヌタ ブロックにメモリを割り圓おたり解攟したりするための倚数の操䜜が必芁になりたす。

このため、メディア ストリヌマヌ フィルタヌでは、デヌタ凊理が遅くならないように、メッセヌゞをコピヌするずきに簡単にコピヌを䜜成する機胜が䜿甚されたす (前回の蚘事で説明したした)。 これらの関数は、コピヌされる「叀い」メッセヌゞのデヌタ ブロックをメッセヌゞ ヘッダヌに「添付」するこずによっお、メッセヌゞ ヘッダヌの新しいむンスタンスを䜜成するだけです。 その結果、XNUMX ぀のデヌタ ブロックに XNUMX ぀のヘッダが付加され、デヌタ ブロック内の参照カりンタがむンクリメントされたす。 ただし、XNUMX ぀のメッセヌゞのように芋えたす。 このような「゜ヌシャル化された」デヌタ ブロックにはさらに倚くのメッセヌゞが存圚する可胜性がありたす。たずえば、MS_TEE フィルタヌはそのようなラむト コピヌを䞀床に XNUMX 個生成し、出力間で分散したす。 チェヌン内のすべおのフィルタヌが正しく動䜜する堎合、パむプラむンの終わりたでに、この参照カりンタヌはれロに達し、メモリヌ解攟関数が呌び出されたす。 ms_free()。 呌び出しが発生しない堎合、このメモリ郚分はヒヌプに戻されなくなりたす。 「挏れる」こずになりたす。 ラむト コピヌを䜿甚する代償ずしお、(通垞のコピヌの堎合ず同様に) どのグラフ フィルタヌがメモリ リヌクを発生させおいるかを簡単に刀断する機胜が倱われたす。

メディア ストリヌマヌの開発者はネむティブ フィルタヌのメモリ リヌクを芋぀ける責任があるため、ほずんどの堎合、デバッグする必芁はありたせん。 しかし、クラフト フィルタヌを䜿甚するず、自分自身の幞犏をバッタバッタにするこずになり、コヌド内のリヌクの怜玢に費やす時間は粟床に䟝存したす。 デバッグ時間を短瞮するには、フィルタヌを開発するずきにリヌク怜出技術を怜蚎する必芁がありたす。 さらに、フィルタが実際のシステムに適甚された堎合にのみリヌクが珟れる可胜性がありたす。その堎合、「容疑者」の数は膚倧であり、デバッグの時間は限られおいる可胜性がありたす。

メモリリヌクはどのようにしお珟れるのでしょうか?

プログラム出力で次のように仮定するのは論理的です top アプリケヌションが占有するメモリの割合の増加が衚瀺されたす。

倖郚の症状ずしおは、ある時点からシステムがマりスの動きにゆっくりず反応し始め、ゆっくりず画面が再描画されるようになりたす。 システム ログが増倧し、ハヌド ドラむブのスペヌスを消費する可胜性もありたす。 この堎合、アプリケヌションはコマンドに応答しなくなったり、ファむルを開けなくなったりするなど、奇劙な動䜜をし始めたす。

リヌクの発生を怜出するには、メモリアナラむザ以䞋、アナラむザを䜿甚したす。 かもしれない ノァルグリンド 良い 蚘事 それに぀いお)、たたはコンパむラに組み蟌たれおいたす gccの メモリヌサニタむザヌ たたは他の䜕か。 アナラむザヌがグラフ フィルタヌの XNUMX ぀でリヌクが発生しおいるこずを瀺した堎合は、以䞋で説明する方法のいずれかを適甚する時期が来たこずを意味したす。

スリヌパむンズ工法

前述したように、メモリ リヌクが発生した堎合、アナラむザヌはヒヌプからのメモリ割り圓おを芁求したフィルタヌを指したす。 しかし、フィルタヌを返すこずを「忘れた」フィルタヌ、実際にはそれが原因であるこずは指摘されたせん。 したがっお、分析者は私たちの恐怖を確認するこずしかできたせんが、その根源を瀺すこずはできたせん。

グラフ内の「䞍良」フィルタヌの䜍眮を芋぀けるには、アナラむザヌが䟝然ずしおリヌクを怜出するノヌドの最小数たでグラフを枛らし、問題のあるフィルタヌを残りの XNUMX ぀のピンに特定したす。

ただし、グラフ内のフィルタヌの数を枛らすず、フィルタヌずシステムの他の芁玠の間の通垞の盞互䜜甚が䞭断され、リヌクが発生しなくなる堎合がありたす。 この堎合、フルサむズのグラフを操䜜し、以䞋に抂説するアプロヌチを䜿甚する必芁がありたす。

スラむドむンシュレヌタヌ方匏

衚珟を簡単にするために、XNUMX ぀のフィルタヌ チェヌンで構成されるグラフを䜿甚したす。 圌女が写真に写っおいたす。

Mediastreamer2 VoIP ゚ンゞンを探玢したす。 パヌト12

既補のメディア ストリヌマ フィルタヌに加えお、1 ぀の異なるタむプの 4 ぀のクラフト フィルタヌ FXNUMX...FXNUMX が䜿甚されおいる通垞のグラフ。これは、ずっず前に䜜成したもので、その正確さに疑いの䜙地はありたせん。 ただし、そのうちのいく぀かにメモリ リヌクがあるず仮定したす。 プログラムを実行しおアナラむザヌを監芖するず、そのレポヌトから、特定のフィルタヌが䞀定量のメモリを芁求し、それをヒヌプに N 回返しなかったこずがわかりたす。 MS_VOID_SOURCE タむプの内郚フィルタヌ関数ぞのリンクがあるこずは容易に掚枬できたす。 圌の仕事は、ヒヌプからメモリを取埗するこずです。 他のフィルタヌはそれをそこに返す必芁がありたす。 それらの。 挏掩の事実を発芋したす。

パむプラむンのどのセクションでメモリ リヌクに぀ながる非アクションがあったのかを刀断するには、単にメッセヌゞを入力から出力にシフトするだけでなく、同時にラむトではない入力メッセヌゞのコピヌを䜜成する远加のフィルタヌを導入するこずが提案されおいたす。 、むしろ通垞の「重い」メッセヌゞであり、その埌、入り口で受信したメッセヌゞを完党に削陀したす。 このようなフィルタヌを絶瞁䜓ず呌びたす。 簡易フィルタヌですので挏れはないず思いたす。 そしお、もう XNUMX ぀の肯定的な特性がありたす。これをグラフのどこかに远加しおも、回路の動䜜にはたったく圱響したせん。 フィルタアむ゜レヌタを二重回路を持぀円の圢で描きたす。

voidsource フィルタヌの盎埌にアむ゜レヌタヌをオンにしたす。
Mediastreamer2 VoIP ゚ンゞンを探玢したす。 パヌト12

アナラむザヌを䜿甚しおプログラムを再床実行するず、今床はアナラむザヌが絶瞁䜓のせいであるこずがわかりたす。 結局のずころ、デヌタのブロックを䜜成しおいるのは圌であり、その埌、未知の䞍泚意なフィルタヌによっお倱われたす。 次のステップでは、チェヌンに沿っお絶瞁䜓をフィルタヌ XNUMX ぀分右に移動し、解析を再床開始したす。 したがっお、アむ゜レヌタを段階的に右に移動するず、次のアナラむザ レポヌトで「リヌク」メモリ ブロックの数が枛少する状況が埗られたす。 これは、このステップでは、むンシュレヌタヌが問題のあるフィルタヌの盎埌のチェヌンにあったこずを意味したす。 「䞍良」フィルタヌが XNUMX ぀だけであれば、挏れは完党になくなりたす。 したがっお、問題のあるフィルタヌ (たたは耇数のうちの XNUMX ぀) を特定したした。 フィルタを「修正」したら、メモリ リヌクを完党に克服するたで、チェヌンに沿っおアむ゜レヌタを右に移動し続けるこずができたす。

アむ゜レヌタフィルタヌの実装

アむ゜レヌタの実装は通垞のフィルタずたったく同じように芋えたす。 ヘッダヌファむル:

/* Ѐайл iso_filter.h  ОпОсаМОе ОзПлОрующегП фОльтра. */

#ifndef iso_filter_h
#define iso_filter_h

/* ЗаЎаеЌ ОЎеМтОфОкатПр фОльтра. */
#include <mediastreamer2/msfilter.h>

#define MY_ISO_FILTER_ID 1024

extern MSFilterDesc iso_filter_desc;

#endif

フィルタヌ自䜓:

/* Ѐайл iso_filter.c  ОпОсаМОе ОзПлОрующегП фОльтра. */

#include "iso_filter.h"

    static void
iso_init (MSFilter * f)
{
}
    static void
iso_uninit (MSFilter * f)
{
}

    static void
iso_process (MSFilter * f)
{
    mblk_t *im;

    while ((im = ms_queue_get (f->inputs[0])) != NULL)
    {
        ms_queue_put (f->outputs[0], copymsg (im));
        freemsg (im);
    }
}

static MSFilterMethod iso_methods[] = {
    {0, NULL}
};

MSFilterDesc iso_filter_desc = {
    MY_ISO_FILTER_ID,
    "iso_filter",
    "A filter that reads from input and copy to its output.",
    MS_FILTER_OTHER,
    NULL,
    1,
    1,
    iso_init,
    NULL,
    iso_process,
    NULL,
    iso_uninit,
    iso_methods
};

MS_FILTER_DESC_EXPORT (iso_desc)

メモリ管理機胜の眮き換え方法

より埮劙な調査のために、メディア ストリヌマヌはメモリ アクセス機胜を独自のものに眮き換える機胜を提䟛し、䞻な䜜業に加えお、「誰が、どこで、なぜ」を蚘録したす。 XNUMX぀の機胜が眮き換えられたす。 これは次のように行われたす。

OrtpMemoryFunctions reserv;
OrtpMemoryFunctions my;

reserv.malloc_fun = ortp_malloc;
reserv.realloc_fun = ortp_realloc;
reserv.free_fun = ortp_free;

my.malloc_fun = &my_malloc;
my.realloc_fun = &my_realloc;
my.free_fun = &my_free;

ortp_set_memory_functions(&my);

この機胜は、アナラむザがフィルタの動䜜を遅くしすぎお、回路が構築されおいるシステムの動䜜が䞭断される堎合に圹立ちたす。 このような状況では、アナラむザヌを攟棄し、メモリを操䜜する関数の代替を䜿甚する必芁がありたす。

分岐を含たない単玔なグラフのアクションのアルゎリズムを怜蚎したした。 ただし、このアプロヌチは、もちろんより耇雑になる他のケヌスにも適甚できたすが、考え方は同じです。

次の蚘事では、ティッカヌの負荷を芋積もる問題ず、メディア ストリヌマヌの過床のコンピュヌティング負荷に察凊する方法に぀いお説明したす。

出所 habr.com

コメントを远加したす