Come posso eseguire il debug di una perdita di memoria in un servizio [chiuso]

4

Ho un programma di servizio Windows in esecuzione su uno dei nostri server. Ha una perdita di memoria di qualche tipo all'interno del programma. Quando inizia a funzionare, utilizza memoria da 20.000 k. Entro pochi giorni arriva a 400.000k di memoria. È un programma abbastanza semplice che tiene traccia dei processi in esecuzione e scrive le informazioni in un database.

Non sono sicuro su come posso eseguire il debug di un programma in esecuzione su una macchina remota per scoprire da dove proviene la perdita di memoria. Quali metodi suggeriresti di utilizzare per provare a rintracciare questo elemento?

Aggiornamento
Il programma ha già un sacco di gestione delle eccezioni in atto. Tuttavia, non ha alcuna registrazione. Quali informazioni devo registrare per rintracciare la perdita di memoria?

    
posta briddums 21.02.2012 - 15:49
fonte

4 risposte

7

Ci sono diversi modi che ti vengono in mente:

  • Esegui il servizio localmente, ma non come servizio. Crea il tuo ambiente host leggero come una semplice app per console. Ora puoi allegare strumenti di profilazione della memoria (quello integrato in determinate versioni di Visual Studio, ecc.)
  • Puoi fare core dump quando la memoria è grande. Questo non è banale e avrai bisogno di alcuni strumenti da Windows SDK.
  • Hai qualche accesso? In tal caso, è possibile confrontare ciò che accade nei registri con alcuni dati PerfMon.
risposta data 21.02.2012 - 15:55
fonte
1

I servizi che eseguono 24x7 sono molto difficili da debug per perdite di memoria (e anche per danneggiamento della memoria).

Ci sono due linee di attacco per ottenere servizi senza perdite di memoria:

A. Debug per combatterlo

  1. Alcuni strumenti che possono facilmente fornire informazioni in merito Valgraind , IBM Rational Purify , memwatch e ci sono molti altri così via. Ecco un buon articolo che parla di questi strumenti: link

  2. Esegui singoli moduli a lungo termine; questo è un tipo di unit test ma non metodi fittizi. Esegui un'applicazione piuttosto significativa che utilizza prima le unità minime, una volta stabilito che il componente A non ha perdite, aggiungi l'applicazione B e poi C e così via. Ciò consentirà l'isolamento

  3. Esegui diversi tipi di carichi: prima senza alcun significato pieno di lavoro, quindi altri tipi specifici di transazioni / elementi di lavoro e così via. Praticamente cerca di identificare un diverso potenziale percorso - in pratica isola le diverse linee di copertura del codice che identificano

  4. registra tutte le allocazioni di memoria (è difficile da analizzare) se è dovuto a allocazioni non necessarie o cancellazioni dimenticate.

  5. Concentrati su dati in esecuzione - ad esempio pacchetti nello stack di rete o, elementi generati per transazioni, articoli generati (o dimenticati di eliminare) per unità di lavoro. Quello che dovresti fare è identificare l'esatto utilizzo della memoria e tracciarlo per transazione per transazione. E puoi controllare di nuovo se un certo tipo di lavoro produce perdite evidenti contro il contrario.

  6. Tieni traccia di tutte le strutture piccole , stringa attentamente; per lo più tali perdite sono meglio catturate dalle revisioni del codice rispetto al monitoraggio dell'utilizzo della memoria perché sono una specie di perdite molto minori.

B. Progettare per prevenire il sistema

  1. Usa la memoria locale il più possibile (in pratica non cercare di tenere le cose in ordine - ma non se c'è una penalità di esecuzione).

  2. Definire una chiara allocazione e responsabilità di deallocazione. Come regola generale, l'applicazione deve allocare e conseguentemente de-allocare e la libreria non ha alcuna responsabilità in alcuni casi.

  3. classificare eseguendo strutture dati rispetto a infra. Per esempio, oggetti di base che dovrebbero attraversare l'intero ciclo di vita rispetto agli oggetti che vengono generati e muoiono con ogni transazione / operazione ecc. La prima classe (infra) deve essere allocata prima dell'avvio dell'operazione pratica e durante il periodo di esecuzione, solo strutture di dati specifiche del lavoro assegnate; so che non è sempre possibile o necessario - ma aiuta a vedere che una volta allocato tutto l'elemento infra, la memoria dovrebbe essere stabile

  4. Crea il design del sistema il più modulare possibile. Ogni modulo dovrebbe avere un semplice riassunto dello scambio di dati e / o della cancellazione di oggetti creati

  5. Pulisci memoria su eccezione. Non rimuovere la memoria su allocazioni o creator falliti è una delle cose difficili da combattere, perché tutto funziona per il 99% del tempo, ma dopo 5 giorni si vedono alcune perdite che non hanno alcuna spiegazione!

  6. Piscine di vita - una delle bellezze del server Web Apache è che non fai niente gratis! Quello che fa è che tutti gli oggetti infra (come oggetti di base, plug-in ecc.) Vengono creati in precedenza. Se c'è una perdita in ogni transazione, nel tempo ucciderà la memoria. Che cosa fa Apache, è che crea diversi pool di vita - per pool di transazioni, a medio e lungo termine. Il punto cruciale è, per il pool di transazioni per cui è possibile continuare a stazionare. Una volta terminata la transazione, l'intero gruppo viene liberato in una sola volta. Leggi questo riferimento che ti fornisce dettagli su come funziona. link

  7. Allo stesso modo puoi anche progettare sistemi (o parti) con pool statici. Tuttavia, questo potrebbe essere difficile per molti sistemi. Ma una cosa del genere è abbastanza comune nei sistemi embedded. vedi qui per i dettagli: link

Infine, ricorda che niente è 100% privo di perdite!

    
risposta data 21.02.2012 - 16:37
fonte
0

Il modo in cui mi sono avvicinato a questo problema è stato cercare i thread e gli oggetti che non erano stati correttamente disposti / rilasciati. Ciò potrebbe essere dovuto a errori di programmazione dispari o dati imprevisti che causano il blocco dei processi, problemi con i dispositivi di rete e così via. Il problema è che a volte possono essere difficili da rilevare o duplicare quando si esegue all'esterno dell'ambiente di produzione.

Per aiutarti a rintracciare questi problemi, se i casi di test e / o la profilazione della memoria nei tuoi sistemi di sviluppo non vengono rivelati immediatamente, devi disporre di una buona registrazione e gestione delle eccezioni. Guarda soprattutto le situazioni in cui un filo / oggetto si attacca più a lungo di quanto dovrebbe.

    
risposta data 21.02.2012 - 16:33
fonte
0

È difficile eseguire il debug in produzione, provare a eseguire localmente. Io uso Debug Viewer in congiunzione con un profiler.

Vorrei raccomandare ANTS , non sono sicuro che sia gratuito in questo momento . Ho usato una versione demo di 30 giorni e fornirà un'analisi dettagliata quando si esegue l'applicazione con l'elenco delle parti suscettibili che è possibile abbattere per scoprire la causa specifica. Penso che ci siano anche molti profiler gratuiti. Ho trovato molto difficile eseguire il debug delle perdite WPF rispetto alle perdite di winform convenzionali.

Spero che non sia un WPF. Buona fortuna però.

    
risposta data 21.02.2012 - 18:33
fonte

Leggi altre domande sui tag