2009-09-20 8 views
5

BACKGROUND:Come implementare una mia creazione array di byte e lo smaltimento

In esecuzione mia app attraverso un profiler, sembra che i punti caldi sono tutti coinvolti nella assegnazione di un gran numero di temporanea new byte [] array.

In una sola esecuzione sotto CLR Profiler, alcuni brevi (3-5 secondi di tempo CPU al di fuori del profiler) hanno prodotto oltre un gigabyte di spazzatura, la maggior parte di tale allocazione di byte [], e questo ha attivato oltre 500 raccolte.

In alcuni casi, sembra che l'applicazione spenda al massimo del 10% del tempo di elaborazione della CPU.

Chiaramente una riscrittura è in ordine.

Quindi, sto pensando di sostituire le nuove allocazioni di byte [] con una classe di pool che potrebbe riutilizzare il buffer in un secondo momento.

qualcosa di simile ...

{ 
byte[] temp = Pool.AllocateBuffer(1024); 
... 
} 

DOMANDA:

Come posso forzare l'applicazione per chiamare il codice nella routine di Pool.deAllocate (temp), quando non è più necessario Temp.

Nel frammento di codice precedente, quando temp è un buffer di byte [] del pool, ma quando viene eliminato, viene eliminato. Non è un problema reale, ma non viene riutilizzato dal pool.

So che potrei sostituire "ritorno 0;" con "Pool.deAllocate (temp); restituisce 0", ma sto cercando di forzare il ripristino a verificarsi.

È anche possibile da remoto?

+0

Sono le allocazioni di array del proprio codice o sono causate dai metodi di .NET Framework? –

+0

Assegnazioni del mio array di codice – Noah

+0

+1 per la creazione di profili prima dell'ottimizzazione! :) – TrueWill

risposta

4

si potrebbe implementare una classe che implementa BufferIDisposable e restituisce il buffer al pool quando è smaltito. È quindi possibile concedere l'accesso all'array di byte sottostante e a condizione che tutti giochino piacevolmente a e che sia possibile sfruttare il riutilizzo.

Attenzione però:

  • vostri tamponi finiranno rapidamente in Gen 2, che non può essere l'ideale per altri motivi
  • Se un pezzo dannoso di codice mantiene un riferimento alla matrice di byte, essi potrebbe spiare i dati utilizzati da altro codice
  • È necessario ricordare di smaltire i buffer al momento giusto.

Io in realtà sono un po 'di codice in MiscUtil per fare questo - si veda CachingBufferManager, CachedBuffer ecc non posso dire che ho usato molto, intendiamoci ... e da quello che mi ricordo, ho fatto un po 'più complicato di quanto avevo proprio bisogno di ...

EDIT: per rispondere ai commenti ...

  • non puoi vigore il codice applicazione per liberare i buffer, n.Non c'è un meccanismo di rilascio automatico in C# - una dichiarazione using è la più vicina che abbiamo.
  • È possibile implementare una conversione implicita in byte[] nella classe buffer per consentire di chiamare metodi che hanno parametri di array di byte. Personalmente non sono molto fan delle conversioni implicite, ma è certamente disponibile come opzione.
+0

Il dispositivo usa e getta rende più ovvio che il programmatore deve fare qualcosa dopo l'uso (smaltire), ma il poster originale ha chiesto la possibilità di forzarlo. Non credo sia possibile. – froh42

+0

Stavo cercando di andare in giro usando una classe diversa, perché chiamo un gran numero di routine con byte [] nell'elenco dei parametri. Quando ho provato ad usare una classe u8Buffer, avrei ottenuto "Impossibile convertire in modo implicito il tipo 'byte []' in 'u8Buffer []'. C'è una soluzione facile? – Noah

+0

@Noah: potresti fornire una conversione implicita a' byte [] 'nella tua classe.Non sono sicuro di raccomandarlo, bada a te. –

Problemi correlati