Domanda

Il più delle volte tendiamo a seguito del già buone pratiche.

Dai un'occhiata alla vs StringBuilder

Ma StringBuilder potrebbe gettare OutOfMemoryException anche quando non v'è sufficiente memoria disponibile . Si getta eccezione OOM perché ha bisogno di "blocco continuo di memoria".

Alcuni link di riferimento StringBuilder OutOfMemoryException

e ci sono molti di più .....

Quanti di voi affrontato questo problema o consapevoli e che cosa hai fatto per risolvere il problema?

C'è qualcosa che mi manca?

P.S:. Non ero a conoscenza di questo

Ho riformulato la questione.

*** La stessa cosa ha lavorato con la concatenazione manuale (io verificare questo e aggiornare SO). L'altra cosa che mi ha causato preoccupazione era che ci sia abbastanza memoria del sistema. Questo è il motivo per cui ho sollevato la domanda qui per verificare se qualcuno ha affrontato questo problema o c'era qualcosa di sbagliato drasticamente con il codice.

È stato utile?

Soluzione

La stringa underyling si crea inoltre bisogno di un blocco contiguo di memoria perché è rappresentato come un array di caratteri (array richiedono memoria contigua). Se lo StringBuilder genera un'eccezione OOM si woludn't in grado di costruire il sottostante senza di essa.

Se la creazione di una stringa provoca un OOM, v'è probabilmente un problema più serio nella vostra applicazione.

Modifica in risposta a un chiarimento:

C'è un piccolo sottoinsieme di casi in cui la costruzione di una stringa con uno StringBuilder mancherà quando la concatenazione manuale riesce. concatenazione manuale userà la lunghezza esatta necessaria per combinare due stringhe mentre uno StringBuilder ha un algorithmn per allocare memoria. E 'più aggressivo e probabilmente allocare più memoria di quanto è effettivamente necessario per la stringa.

Utilizzando una StringBuilder comporterà anche un raddoppiamento temporaneo della memoria richiesta poiché la stringa sarà presente in forma System.String e StringBuilder simultaneamente per un breve periodo.

Ma se è un modo causando un OOM e l'altro non è, che punti ancora suscettibili di un problema più serio nel vostro programma.

Altri suggerimenti

Se StringBuilder sta per gettare un OutOfMemoryException nella vostra particolare situazione, quindi facendo manuale concatenazione di stringhe non è una soluzione migliore; è molto peggio. Questo è esattamente il caso (la creazione di una stringa estremamente, estremamente lunga) dove si suppone che StringBuilder per essere utilizzato. concatenamento manuale di una stringa di questo grande vorranno molti volte la memoria che la creazione di una stringa con StringBuilder avrebbe preso.

Detto questo, su un computer moderno, se la stringa è in esecuzione sul computer di memoria contigua il vostro disegno è profondamente, profondamente sbagliata. Non riesco a immaginare cosa si potrebbe fare che creerebbe una stringa di grandi dimensioni.

Quanta memoria stiamo parlando? Non sto parlando di memoria libera o totale del sistema, ma quanto tempo è la stringa che stai concatenazione?

Un'eccezione overflow di memoria è quasi sempre un brutto segno sul codice, anche se non riesce a lungo prima che la memoria si esaurisce in realtà, come hai vissuto a causa di memoria continua non essere disponibili.

A questo punto si dovrebbe davvero ristrutturare il codice.

Per esempio, qui ci sono vari modi per combattere il problema:

  1. Non tenere quanti più dati in memoria in una sola volta, ha messo su disco o qualcosa
  2. Break it up, tenere un elenco di stringa / stringbuilders e solo aggiungere a loro fino ad una certa lunghezza prima di passare a uno nuovo, mantiene il problema "continua memoria" a bada
  3. Ristrutturare l'algoritmo di non costruire gigabyte di dati in memoria a tutti

Se si esegue così vicino alla vostra memoria limiti che questo è ancora un problema, allora probabilmente si dovrebbe pensare a una diversa architettura o di avere una macchina beefier.

Se si guarda a come StringBuilder è implementata, vedrete che in realtà utilizza un String per contenere i dati (<=> ha metodi interni, che permetteranno <=> di modificare in atto).

vale a dire. entrambi utilizzano la stessa quantità di memoria. Tuttavia, poiché <=> si estenderà automaticamente la matrice sottostante e copia come necessario quando necessario (ma raddoppiando la capacità) che è più probabile che la causa del errore di memoria. Ma come altri hanno già sottolineato entrambi gli richiedono un blocco di memoria,

Bene, la questione in realtà è, perché avete bisogno di lavorare con le stringhe così a lungo? Se inciampare su questo problema, più che probabile che si dovrebbe modificare il vostro concetto.

Questa problemi colpisce anche il System.String di classe, così si dovrebbe piuttosto pezzo vostro input in List ed elaborare i dati in parallelo, che dovrebbero incremento complessivo prestazioni se scritto correttamente.

ho incontrato questa eccezione con grandi archi costruiti sucessively con diversi stringbuilders (che non dovrebbe aver causato un problema in quanto sono state dichiarate entro funzioni anonime), e, infine, risolto grazie al riutilizzo di un singolo StringBuilder, dichiarata al di fuori della funzione anonima.

Ho avuto un'esperienza molto simile dove stavo aggiungendo stringhe ma ho dimenticato di aggiungere lo String.Format. Così:

myStringBuilder.Append("1,""{0}""", someVeryLargeIntVariable)

avrebbe dovuto essere:

myStringBuilder.Append(String.Format("1,""{0}""", someVeryLargeIntVariable))

Si noti che questo è il mio codice vb.net che non è riuscita. Ho replicato un test simile in C # con:

myStringBuilder.Append('a', 1564544656);

vs.

myStringBuilder.Append(string.Format("1,\"{0}\"", 1564544656));

Ma nel mio caso, mi vb.net messo nei guai b / c delle conversioni implicite (non ho potuto parallelo esattamente stesso problema in C #).

Mi auguro che aiuta qualcuno.

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