causa C# funziona su garbage collection per safetiness di memoria, a differenza di C++, sono stati si sono tenuti a conoscere le capacità di gestione della memoria.
per esempio, dare un'occhiata al codice successivo:
public static void doAsync(){
var arr = stackalloc string[100];
arr[0] = "hi";
System.Threading.ThreadPool.QueueUserWorkItem(()=>{
Thread.Sleep(10000);
Console.Write(arr[0]);
});
}
Il programma andrà in crash facilmente. poiché arr
è allocato allo stack, l'oggetto + la sua memoria scomparirà non appena doAsync
è finito. la funzione lamda punta ancora a questo indirizzo di memoria non più valido, e questo è uno stato non valido.
se si passano i primitivi locali per riferimento, si verificherà lo stesso problema.
Lo schema è:
oggetti statici -> vite in tutto il tempo Applocation
locale oggetto -> vive fino a quando il Ambito che li ha creati è valida
oggetti heap-assegnati (creato con new
) - > esiste finché qualcuno ha un riferimento a loro.
Un altro problema è che la raccolta Garbage funziona in periodi. quando un oggetto è locale, dovrebbe essere finalizzato non appena la funzione è finita, perché dopo quel tempo - la memoria sarà sostituita da altre variabili. Il GC non può essere forzato a finalizzare l'oggetto, o non dovrebbe, comunque.
La cosa buona, però, è che il C# JIT a volte (non sempre) può determinare che un oggetto può essere assegnato in modo sicuro nello stack e ricorrere all'assegnazione dello stack, se possibile (di nuovo, a volte).
In C++ d'altra parte, è possibile dichiarare tutto enywhere, ma questo viene fornito con meno safetyness allora C# o Java, ma si può mettere a punto voi applicazione e raggiungere alte performance - a basso risorse applicazione
È possibile avere un puntatore a un tipo gestito in C#, non è incorporato nella lingua come con C++/CLI. https://msdn.microsoft.com/en-us/library/1246yz8f(v=vs.110).aspx - Usa GCHandleType.Pinned come secondo argomento, quindi chiama AddrOfPinnedObject() sul risultato. – Nuzzolilo
@Nuzzolilo Hai provato? Se ricordo bene riceverai un'eccezione se provi a 'GCHandleType.Pinned' un oggetto gestito. – xanatos
Ricordo di averlo fatto anni fa, ma è passato così tanto tempo che la mia memoria poteva essere sbagliata: P. Ci proverò di nuovo e vedrò cosa succede. – Nuzzolilo