Fora da memória: nos termos do leigo, significa que não há memória suficiente. Por exemplo, criar constantemente um objeto grande em um loop infinito em breve causará um estouro de memória.
Vazamento de memória: refere -se à liberação oportuna da memória após alocar a memória a um objeto quando o objeto não está mais em uso, resultando na ocupação da unidade de memória e a memória disponível real é reduzida, assim como um vazamento de memória.
Vazamento de memória causado pelo método de substring
Substring (int BeginIndex, int endNDex) é um método da classe String, mas esse método é implementado completamente diferentemente em JDK6 e JDK7 (embora ambos atinjam o mesmo efeito). Compreender os detalhes da implementação pode ajudá -lo a usá -los melhor, porque o uso inadequado da substring no JDK1.6 pode levar a sérios problemas de vazamento de memória.
1. O papel da substring
O método Substring (int BeginIndex, int endindex) retorna uma substring, a partir do começo da sequência pai e terminando no endindex-1. O subscrito da sequência pai começa em 0, e a substring contém BeginIndex e não EndIndex
String x = "abcdef"; x = str.substring (1,3); system.out.println (x);
A saída do programa acima é "BC"
2. Princípio da implementação
A classe String é imutável. Quando X é reatribuído na segunda frase acima, ele apontará para um novo objeto String. No entanto, não há descrição precisa ou representa a situação real que ocorre na pilha. O que realmente acontece quando a substring é chamada é a diferença entre os dois.
Implementação de substring no JDK6
O objeto String é armazenado como uma matriz de char. Existem 3 campos na classe String: Char [] Valor, Int Offset e Int Count, que são usados respectivamente para armazenar a matriz real de caracteres, a posição inicial da matriz e o número de caracteres da string. Essas 3 variáveis podem determinar uma string. Quando o método de substring for chamado, ele criará uma nova string, mas o valor da matriz de char acima ainda usará o valor da matriz pai original. A única diferença entre a matriz pai e filho é que os valores de contagem e deslocamento são diferentes.
Dê uma olhada no código -fonte de implementação de substring no JDK6:
public String substring (int BeginIndex, int endindex) {if (BeginIndex <0) {lança new StringIndexoutOfBoundSexception (BELKIndex); } if (endIndex> count) {lança new stringIndexoutOfBoundSexception (endIndex); } if (BeginIndex> endIndex) {lança new StringIndexoutOfBoundSexception (endIndex - BELKIndex); } return ((BeginIndex == 0) && (endIndex == count))? isto: new string (deslocamento + BeginIndex, endIndex - BeginIndex, valor); // é usado para usar o mesmo valor de matriz de char que a string pai} String (Int Offset, Int Count, Char Value []) {this.value = value; this.offset = deslocamento; this.count = count; }String str = "abcdefghijklmnopqrst"; string sub = str.substring (1, 3); str = null;
Este programa simples possui duas variáveis de string str e sub. A sub -string é obtida pela string pai STR. Se o programa acima for executado no JDK1.6, sabemos que a alocação de espaço de memória da matriz é realizada na pilha, o valor interno da matriz de char de sub -e STR é o mesmo, ou seja, a matriz de char acima composta por caracteres a ~ caractere t. A única diferença entre STR e Sub é a diferença entre a contagem de comprimentos de BeginIndex e personagem na matriz. Na terceira frase, tornamos a referência STR vazia, o que se destina a libertar o espaço ocupado por STR, mas, neste momento, o GC não pode reciclar essa grande matriz de char porque ainda está sendo referenciada dentro da Sub String, embora o sub intercepte apenas uma pequena parte dessa grande matriz. Quando o STR é uma corda muito grande, esse resíduo é muito óbvio e pode até trazer problemas de desempenho. Você pode resolver esse problema:
Ele usa a tecnologia de splicing de string, que criará uma nova string. Essa nova string usará uma nova matriz de char interna para armazenar os personagens de que realmente precisa, para que a matriz Char da matriz pai não seja mencionada por outras fontes. Deixe str = nulo, e todo o espaço ocupado por STR será reciclado na próxima vez que o GC for reciclado. Mas escrever assim obviamente não é bonito, portanto, no JDK7, a substring é reimplementada.
Implementação de substring no JDK7
A implementação aprimorada da substring no JDK7, que na verdade cria uma nova matriz de char na pilha para substringas interceptadas para manter caracteres para substringas.
Verifique o código -fonte da implementação do método de substring da classe String no JDK7:
public String substring (int BeginIndex, int endindex) {if (BeginIndex <0) {lança new StringIndexoutOfBoundSexception (BELKIndex); } if (endIndex> value.length) {tiro new stringIndexoutOfBoundSexception (endIndex); } int subblen = endIndex - BELKIndex; if (subblen <0) {lança new stringIndexoutOfBoundSexception (subblen); } return ((BeginIndex == 0) && (endIndex == value.length))? isto: new string (valor, BeginIndex, subblen); } public String (Char Value [], Int Offset, Int count) {if (deslocamento <0) {lança new stringIndexoutOfBoundSexception (deslocamento); } if (count <0) {lança new stringIndexoutOfBoundSexception (contagem); } // Nota: O deslocamento ou contagem pode estar perto -1 >>> 1. if (offset> value.length - count) {lança new stringIndexoutOfBoundSexception (deslocamento + contagem); } this.value = Arrays.copyOfRange (valor, deslocamento, deslocamento+contagem); }O método CopyOfRange da classe Matriz:
public static char [] copyofRange (char [] original, int, int para) {int newLength = para - de; if (newLength <0) lançar uma nova ilegalArgumentException (de + ">" + para); char [] cópia = novo char [newLength]; // é para criar um novo CHAR Array System.arraycopy (original, de, cópia, 0, math.min (original.length - de, newLength)); cópia de retorno; }Pode -se descobrir que uma nova matriz de char é criada para a substring armazenar os caracteres na substring. Dessa forma, não há conexão necessária entre a sequência infantil e a sequência pai. Quando a referência da sequência pai é inválida, o GC recicla oportunamente o espaço de memória ocupado pela sequência pai.
Resumir
O exposto acima é a explicação completa do vazamento de memória causado pelo método de substring em Java. Espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!