Pergunta

Estou recebendo um OutOfMemoryError java quando eu chamar esse método - eu estou usando-o em um loop para analisar muitos arquivos grandes em sequência. meu palpite é que result.toString() não está recebendo lixo coletado corretamente durante o loop. em caso afirmativo, como eu deveria consertá-lo?

private String matchHelper(String buffer, String regex, String method){
    Pattern abbrev_p = Pattern.compile(regex);//norms U.S.A., B.S., PH.D, PH.D.
    Matcher abbrev_matcher = abbrev_p.matcher(buffer);
    StringBuffer result = new StringBuffer();
    while (abbrev_matcher.find()){
            abbrev_matcher.appendReplacement(result, abbrevHelper(abbrev_matcher));
    }
    abbrev_matcher.appendTail(result);
    String tempResult = result.toString(); //ERROR OCCURS HERE
  return tempResult;

}
Foi útil?

Solução

Escrito desta forma, você vai precisar de cerca de 6 bytes de memória para cada caractere no arquivo.

Cada personagem é de dois bytes. Você tem a entrada bruta, a saída substituído (no buffer), e você está pedindo uma terceira cópia quando você ficar sem memória.

Se o arquivo é codificado em algo como ASCII ou ISO-8859-1 (a codificação de caracteres de byte único), que significa que será seis vezes maior na memória do que no disco.

Você pode alocar mais memória para o processo, mas uma solução melhor poderia ser a de processar a entrada "streamwise" -Read, digitalização, e gravar os dados sem carregar tudo na memória ao mesmo tempo.

Outras dicas

Se os seus arquivos a serem processados ??são todos muito grande, dizem que mais de um MB algumas centenas, então você realmente deve ir com fluxo de processamento em vez desta maneira "carregar tudo na memória", assim como @erickson sugeriu.

Caso contrário, há algumas coisas que você poderia tentar, tudo para reduzir o uso de memória, tanto quanto possível:

  1. Tente adequadamente ampliar o tamanho da pilha ainda se não (quando aplicável).
  2. Dar StringBuffer um tamanho inicial igual ao comprimento do dado String buffer. Isso deve reduzir o uso de memória desnecessária, enquanto a expansão do StringBuffer no processo. Presumo que só está substituindo certas palavras da string original e deve ser mais ou menos o mesmo de comprimento.
  3. Se possível, talvez você possa retornar o objeto StringBuffer gerado em vez disso. Chamando seu toString() somente depois de se livrar do objeto String originais.

Eu acho o problema com StringBuilder.append(). Quando Matcher anexa seqüência de caracteres para o Construtor.

Conforme explicado no artigo sobre OutOfMemoryError com StringBuilder / StringBuffer , é um problema conhecido que de acréscimo () irá duplicar a capacidade de se chars tampão interno se a capacidade não é suficiente. Ir para fluxos como sugerido por Erickson.

Concordo com as outras respostas ... mas ... simplesmente porque a exceção ocorre lá não necessariamente significa que é o problema. Você pode muito bem estar vazamento de memória em outro lugar e que só acontece de ser o lugar que é revelado. Você deve executar um profiler para examinar o uso de memória e verificar exatamente o que os objetos não estão sendo coletados.

Sim! Não armazena na memória caso contrário você vai ficar sem ele, especialmente se você está indo mais de 2MB de I / O.

link Recomendado para fixação e anexar texto: http: // java.ittoolbox.com/documents/appending-data-to-a-file-18786

Você poderia tentar retornar um StringBuffer e defini-lo como null após o uso.

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