Domanda

Diciamo che si desidera scrivere un metodo ad alte prestazioni che elabora un grande insieme di dati. Perché gli sviluppatori non dovrebbero avere la capacità di trasformare in gestione manuale della memoria invece di essere costretti a trasferirsi in C o C ++?

void Process()
{
    unmanaged
    {
        Byte[] buffer;
        while (true)
        {
            buffer = new Byte[1024000000];

            // process

            delete buffer;
        } 
    }   
}
È stato utile?

Soluzione

A causa che consente di eliminare manualmente un blocco di memoria mentre ci possono essere ancora riferimenti ad esso (e il runtime non ha alcun modo di sapere che senza fare un ciclo di GC) in grado di produrre puntatori penzolanti, e quindi rompere la sicurezza di memoria . lingue GC sono generalmente di memoria di sicurezza in base alla progettazione.

Detto questo, in C #, in particolare, si può fare ciò che si vuole già:

void Process()
{
    unsafe
    {
        byte* buffer;
        while (true)
        {
            buffer = Marshal.AllocHGlobal(1024000000);

            // process

            Marshal.FreeHGlobal(buffer);
        } 
    }   
}

Si noti che, come in C / C ++, si ha pieno l'aritmetica dei puntatori per i tipi di puntatore prime in C # -. Così buffer[i] o buffer+i sono espressioni valide

Altri suggerimenti

Se avete bisogno di alte prestazioni e un controllo dettagliato, forse si dovrebbe scrivere quello che stai facendo in C o C ++. Non tutte le lingue sono buoni per tutte le cose.

A cura di aggiungere: una sola lingua non sta per essere buono per tutte le cose. Se si sommano tutte le caratteristiche utili in tutte le buone linguaggi di programmazione, si sta andando ad ottenere davvero un gran casino, molto peggio di C ++, anche se si può evitare incoerenza.

Caratteristiche non sono liberi. Se una lingua ha una caratteristica, le persone tendono a usarlo. Non sarà in grado di imparare C # abbastanza bene senza imparare le nuove routine C # gestione manuale della memoria. squadre compilatore stanno andando per la sua attuazione, a costo di altre caratteristiche del compilatore che sono utili. Il linguaggio è destinato a diventare difficile da analizzare, come C o C ++, e che porta a rallentare la compilazione. (Come un ragazzo C ++, sono sempre stupito quando ho compilare uno dei nostri progetti C #. Compilazione sembra quasi istantanea.)

Caratteristiche conflitto tra loro, a volte in modi inaspettati. C90 non può fare così come Fortran a calcoli di matrice, poiché la possibilità che C puntatori sono alias impedisce alcune ottimizzazioni. Se si consente l'aritmetica dei puntatori in una lingua, si deve accettare le conseguenze.

Si sta suggerendo un # un'estensione C per consentire la gestione manuale della memoria, e in alcuni casi che sarebbe utile. Ciò significherebbe che la memoria dovrebbe essere allocata in modi diversi, e non ci sarebbe dovuto essere un modo per dire a memoria gestita manualmente dalla memoria gestita automaticamente. Improvvisamente, hai la gestione della memoria complicato, ci sono più possibilità per un programmatore per avvitare in su, e il gestore della memoria è di per sé più complicato. Si sta guadagnando un po 'di prestazioni che conta in alcuni casi in cambio di ulteriori complicazioni e la gestione della memoria più lento in tutti i casi.

E 'possibile che a un certo momento avremo un linguaggio di programmazione che va bene per quasi tutti gli scopi, da script per sgranocchiare di numero, ma non c'è niente popolare che è abbastanza vicino a quello. Nel frattempo, dobbiamo essere disposti ad accettare le limitazioni di utilizzo una sola lingua, o la sfida di imparare diversi e di passare.

Nell'esempio che hai postato, perché non basta cancellare il buffer e riutilizzarlo?

Il collettore NET garbage è molto molto bravo a lavorare quali oggetti non si fa riferimento più e liberare la memoria associata in modo tempestivo. Infatti, il garbage collector ha un mucchio speciale (l'oggetto grande mucchio) in cui mette grandi oggetti simili, che è ottimizzato per trattare con loro.

In cima a questo, non permettendo riferimenti a essere esplicitamente liberati semplicemente rimuove tutta una serie di bug con perdite di memoria e puntatori penzolanti, che porta a codice molto più sicuro.

Come liberare ogni blocco inutilizzato singolarmente come fatto in una lingua con la gestione della memoria esplicita può essere più costoso di lasciare un garbage collector farlo, perché il GC ha la possibilità di utilizzare sistemi di copiatura di trascorrere un tempo lineare per il numero di blocchi di sinistra vivo (o il numero di blocchi recenti lasciato vivo) invece di dover gestire ogni blocco morto.

Lo stesso motivo maggior parte dei kernel non ti consente di programmare le proprie discussioni. A causa 99,99 +% di tempo che in realtà non hanno bisogno di, ed esponendo tale funzionalità il resto del tempo sarà solo tentare di fare qualcosa di stupido potenzialmente / pericoloso.

Se si ha realmente bisogno di controllo della memoria a grana fine, scrivono che sezione di codice in qualcosa d'altro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top