Pergunta

Nós principalmente tendem a seguir o exposto melhores práticas.

Tenha um olhar em vs StringBuilder

Mas StringBuilder poderia jogar OutOfMemoryException mesmo quando não há memória suficiente disponível . Ele lança exceção OOM porque ele precisa "bloco contínuo de memória".

Algumas ligações para referência StringBuilder OutOfMemoryException

e há muitos mais .....

Como muitos de vocês enfrentaram este problema ou consciente e o que você fez para resolvê-lo?

Existe algo que eu estou ausente?

P.S:. Eu não estava ciente desta

Eu reformulada a questão.

*** A mesma coisa trabalhou com concatenação manual (Eu vou verificar isso e atualização SO). A outra coisa que me causou preocupação foi a de que não há memória suficiente no sistema. Essa é a razão pela qual eu levantei essa questão aqui para verificar se alguém enfrentou este problema ou havia algo muito errado com o código.

Foi útil?

Solução

A seqüência de underyling você cria também vai precisar de um bloco contíguo de memória porque ele é representado como uma matriz de caracteres (matrizes requer memória contígua). Se o StringBuilder lança uma exceção OOM você woludn't ser capaz de construir o subjacente sem ele.

Se a criação de uma cadeia provoca um OOM, há provavelmente um problema mais sério na sua aplicação.

Editar em resposta ao esclarecimento:

Há um pequeno subconjunto de casos em que a construção de uma corda com um StringBuilder irá falhar quando concatenação manual do bem-sucedido. concatenação manual irá usar o comprimento exato necessário, a fim de combinar duas cordas enquanto um StringBuilder tem uma algorithmn diferente para alocação de memória. É mais agressivo e provavelmente vai alocar mais memória do que é realmente necessário para a cadeia.

Usando um StringBuilder também irá resultar em uma duplicação temporária da memória necessária uma vez que a corda vai estar presente em uma forma System.String e StringBuilder simultaneamente por um tempo curto.

Mas se é uma maneira de provocar um OOM eo outro é não, pontos ainda susceptíveis de um problema mais sério em seu programa.

Outras dicas

Se StringBuilder vai lançar um OutOfMemoryException em sua situação particular, em seguida, fazendo o manual concatenação não é uma solução melhor; é muito pior. Este é exatamente o caso (criando uma cadeia extremamente, extremamente longa), onde StringBuilder é suposto ser usado. concatenação manual de uma seqüência de este grande vai demorar muitas vezes a memória que a criação de uma cadeia com StringBuilder levaria.

Dito isso, em um computador moderno, se sua corda é executar o computador do memória contígua seu projeto está profundamente, profundamente falho. Eu não posso imaginar o que você poderia fazer isso criaria uma cadeia que grande.

Como a quantidade de memória que estamos falando? Eu não estou falando sobre a memória livre ou total no sistema, mas quanto tempo é a string estiver concatenando?

A exceção de estouro de memória é quase sempre um sinal muito ruim sobre o seu código, mesmo se ele falhar muito antes de a memória realmente acabar, como você já experimentou devido a memória contínua não estar disponível.

Nesse ponto você deve realmente reestruturar o código.

Por exemplo, aqui estão várias maneiras de combater o problema:

  1. Não mantenha o máximo de dados na memória de uma só vez, colocá-lo em disco ou algo
  2. Parem com isso, manter uma lista de Cordas / StringBuilders e só adicionar-lhes até um determinado período antes de mudar para um novo, mantém o problema "memória contínua" na baía
  3. Reestruturar o algoritmo para não construir gigabyte de dados na memória de todo

Se você estiver executando tão perto de seus limites de memória que esta é ainda uma preocupação, então você provavelmente deve pensar em uma arquitetura diferente ou ter uma máquina mais robusta.

Se você olhar como StringBuilder é implementado, você vai ver que ele realmente usa um String para armazenar os dados (String tem métodos internos, que permitirão StringBuilder modificar no lugar).

i. ambos usam a mesma quantidade de memória. No entanto, desde StringBuilder vai estender automaticamente a matriz subjacente e cópia conforme necessário, quando necessário (mas a duplicação da capacidade), que é a causa mais provável do erro de falta de memória. Mas, como outros já apontaram tanto do exigem um bloco contínuo de memória,

Bem, a questão realmente é, por que você precisa para trabalhar com cadeias de tanto tempo? Se você se depara com este problema, mais do que provável que você deve alterar o seu conceito.

Este problemas afeta até mesmo o System.String classe, para que você deveria pedaço sua entrada em List e processar os dados em paralelo, o que deverá aumentar geral desempenho se escrito corretamente.

Eu encontrei essa exceção com grandes cordas construídas sucessivamente com diferentes StringBuilders (que não deve ter causado um problema como eles foram declarados dentro de funções anônimas) e, finalmente, resolvido através da reutilização de um único StringBuilder, fora declarado da função anônima.

Eu tive uma experiência muito semelhante onde eu estava anexando cordas, mas se esqueceu de adicionar o String.Format. Assim:

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

deveria ter sido:

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

Note que este é o meu código vb.net que falhou. Eu replicado um teste semelhante em c # com:

myStringBuilder.Append('a', 1564544656);

vs.

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

Mas no meu caso, vb.net me ficou em apuros b / c das conversões implícitas (eu não poderia paralelo ao exata mesmo problema em c #).

Espero que ajude alguém.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top