U materiale di l'articulu hè pigliatu da u mo
In l'ultimu
Debugging di filtri artigianali
Dopu avemu vistu u mecanismu per u muvimentu di dati in un media streamer in l'articulu precedente, saria logicu di parlà di i periculi ammucciati in questu. Una di e caratteristiche di u principiu di u "flussu di dati" hè chì a memoria hè attribuita da u munzeddu in filtri chì si trovanu à a surgente di u flussu di dati, è a memoria hè liberata è tornata à u munzeddu da i filtri situati à a fine di u flussu. caminu. Inoltre, a creazione di novi dati è a so distruzzione pò esse in un locu trà. In generale, a liberazione di memoria hè realizata da un filtru sfarente di quellu chì hà creatu u bloccu di dati.
Da u puntu di vista di u monitoraghju di memoria trasparente, saria ragiunate per u filtru, dopu avè ricivutu un bloccu di input, per distrughje immediatamente dopu a trasfurmazioni, liberendu a memoria, è per pruduce un bloccu novu creatu cù dati di output. In questu casu, una fuga di memoria in u filtru seria facilmente tracciata - se l'analizzatore hà rilevatu una fuga in u filtru, u prossimu filtru ùn distrugge micca bè i blocchi entranti è ci hè un errore in questu. Ma da u puntu di vista di mantene un altu rendiment, questu approcciu di travaglià cù blocchi di dati ùn hè micca produtivu - porta à un gran numaru d'operazioni per assignà / memoria libera per blocchi di dati senza alcuna produzzione utile.
Per quessa, i filtri media streamer, per ùn rallentà u processu di dati, utilizanu funzioni chì creanu copie faciuli quandu copianu i missaghji (avemu parlatu di elli in l'articulu precedente). Queste funzioni creanu solu una nova istanza di l'intestazione di u messagiu "attachendu" à questu un bloccu di dati da u "vechju" missaghju copiatu. In u risultatu, dui intestazioni sò attaccati à un bloccu di dati è u contatore di riferimentu in u bloccu di dati hè incrementatu. Ma parerà dui missaghji. Ci ponu esse più missaghji cù un tali bloccu di dati "socializatu", per esempiu, u filtru MS_TEE genera una decina di tali copie di luce à una volta, distribuzendu trà i so outputs. Se tutti i filtri in a catena operanu currettamente, à a fine di u pipeline, stu contatore di riferimentu deve ghjunghje à zero è a funzione di liberazione di memoria serà chjamata: ms_free (). Se a chjama ùn hè micca accaduta, allora stu pezzu di memoria ùn serà più tornatu à u munzeddu, i.e. sarà "fuga". U prezzu per l'usu di copie di luce hè a perdita di l'abilità di determinà facilmente (cum'è seria u casu cù e copie regulare) quale filtru di gràficu perde a memoria.
Siccomu i sviluppatori di media streamer sò rispunsevuli di truvà fughe di memoria in filtri nativi, probabilmente ùn avete micca bisognu di debug. Ma cù u vostru filtru artigianale, site u grasshopper di a vostra propria felicità, è u tempu chì passate à circà perdite in u vostru codice dependerà di a vostra precisione. Per riduce u vostru tempu di debugging, avemu bisognu di guardà e tecniche di rilevazione di fughe quandu u sviluppu di filtri. Inoltre, pò accade chì a fuga si manifesta solu quandu u filtru hè appiicatu in un sistema veru, induve u numeru di "suspettati" pò esse enormi è u tempu di debugging limitatu.
Cumu si manifesta una fuga di memoria?
Hè logicu per assumisce chì in a pruduzzioni di u prugramma cima mostrarà a percentuale crescente di memoria occupata da a vostra applicazione.
A manifestazione esterna serà chì in un certu puntu u sistema hà da cumincià à risponde à pocu à pocu à u muvimentu di u mouse è à pocu à pocu ridisegna u screnu. Hè ancu pussibule chì u logu di u sistema cresce, manghjendu spaziu nantu à u vostru hard drive. In questu casu, a vostra applicazione hà da cumincià à cumportà stranu, ùn risponde micca à i cumandamenti, ùn pò micca apre un schedariu, etc.
Per detectà l'occurrence di una fuga, useremu un analizatore di memoria (in seguitu chjamatu l'analizzatore). Puderia esse valgrind (bene
Metudu di trè pini
Cumu l'esitatu sopra, s'ellu ci hè una perdita di memoria, l'analizzatore indicà à u filtru chì hà dumandatu l'allocazione di memoria da u munzeddu. Ma ùn indicà micca u filtru chì "scurdatu" di rinvià, chì, in fattu, hè u culprit. Cusì, l'analizzatore pò solu cunfirmà e nostre paure, ma micca indicà a so radica.
Per sapè u locu di u filtru "malu" in u graficu, pudete andà per riducendu u graficu à u minimu numeru di nodi in quale l'analizzatore detecta sempre una fuga è localize u filtru problematicu in i trè pini rimanenti.
Ma pò accade chì riducendu u numeru di filtri in u graficu, disturberate u cursu normale di l'interazzione trà i filtri è l'altri elementi di u vostru sistema è a fuga ùn apparisce più. In questu casu, avete da travaglià cù un gràficu full-size è aduprà l'approcciu delineatu quì sottu.
Metudu d'insulatore scorrevule
Per simplicità di presentazione, useremu un graficu chì hè custituitu da una catena di filtri. Hè mostrata in a stampa.
Un graficu regulare in quale, inseme à i filtri media streamer pronti, sò usati quattru filtri artighjanali F1...F4, di quattru tipi diffirenti, chì avete fattu assai tempu fà è ùn avete micca dubbitu di a so correttezza. Tuttavia, supponemu chì parechji di elli anu perdite di memoria. Eseguisce u nostru prugramma per monitorà l'analizzatore, amparemu da u so rapportu chì un certu filtru hà dumandatu una certa quantità di memoria è ùn l'hà micca tornatu à u munzeddu N numeru di volte. Pudete facilmente intuisce chì ci sarà un ligame à e funzioni di filtru internu di tipu MS_VOID_SOURCE. U so compitu hè di piglià a memoria da u munzeddu. Altri filtri duveranu rinvià quì. Quelli. avemu da detect u fattu di a fuga.
Per determinà in quale sezione di u pipeline ci hè stata inazzione chì porta à una fuga di memoria, hè prupostu di intruduce un filtru supplementu chì cambia solu i missaghji da input à output, ma à u stessu tempu crea una copia di u messagiu di input chì ùn hè micca ligeru. , ma piuttostu un nurmale "pesante", poi sguassate cumplettamente u messagiu ricevutu à l'entrata. Chjamaremu un tali filtru un insulator. Cridemu chì, postu chì u filtru hè simplice, ùn ci hè micca fuga in questu. È una pruprietà più pusitiva - se l'aghjunghjenu in ogni locu in u nostru graficu, questu ùn affetterà micca u funziunamentu di u circuitu in ogni modu. Descriveremu u filtru-isolatore in a forma di un cercolu cù un circuitu doppiu.
Accendemu l'isolatore immediatamente dopu à u filtru Vodsource:
Eseguimu u prugramma cù l'analizzatore di novu, è vedemu chì sta volta l'analizzatore culpisce l'insulator. Dopu tuttu, hè quellu chì avà crea blocchi di dati, chì sò tandu persu da un filtru (o filtri) trascuratu scunnisciutu. U prossimu passu hè di spustà l'insulator longu a catena à a diritta, da un filtru, è principià l'analisi di novu. Allora, passu à passu movendu l'isolatore à a diritta, averemu una situazione induve in u prossimu rapportu di l'analizzatore u numeru di blocchi di memoria "filtrati" diminuirà. Questu significa chì in questu passu l'insulator era in a catena immediatamente dopu à u filtru prublema. S'ellu ci era solu un filtru "cattivu", allora a fuga sparirà in tuttu. Cusì, avemu localizatu u filtru problematicu (o unu di parechji). Dopu avè "fissatu" u filtru, pudemu cuntinuà à spustà l'isolatore à a diritta longu à a catena finu à scunfighjà cumplettamente e fughe di memoria.
Implementazione di un filtru isolante
L'implementazione di l'isolatore s'assumiglia à un filtru regulare. File d'intestazione:
/* Файл 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
U filtru stessu:
/* Файл 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)
Metudu per rimpiazzà e funzioni di gestione di memoria
Per una ricerca più sottile, u media streamer furnisce l'abilità di rimpiazzà e funzioni d'accessu à a memoria cù u vostru propiu, chì, in più di u travagliu principale, registrà "Quale, induve è perchè". Trè funzioni sò rimpiazzati. Questu hè fattu cusì:
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);
Questa funzione aiuta in i casi induve l'analizzatore rallenta u funziunamentu di i filtri tantu chì u funziunamentu di u sistema in quale hè custruitu u nostru circuitu hè disturbatu. In una tale situazione, avete da abbandunà l'analizzatore è aduprà a sustituzzioni di funzioni per travaglià cù memoria.
Avemu cunsideratu un algoritmu d'azzioni per un gràficu simplice chì ùn cuntene rami. Ma stu approcciu pò esse appiicatu à altri casi, sicuru cù più cumplessità, ma l'idea ferma a stessa.
In u prossimu articulu, guardemu u prublema di stima di a carica nantu à un ticker è e manere di cummattiri a carica eccessiva di l'informatica in un streamer media.
Source: www.habr.com