Limpar memória - java

2 respostas
java
R

Boa tarde pessoal!

Estou com algumas dúvidas sobre o coletor e como posso limpar memória no Java.

Tenho um programa que grava uma árvore binária de busca em um arquivo e fiz uma função que inseri o elemento e outro que remove o elemento, porém no método que remove eu coloco os elementos que removo em um espaço no arquivo que chamo de “blocos vazios” (que é uma pilha), na linguagem C tem um método que liberava a memória que era o free(), no Java tem o coletor de lixo que fica a critério do Java, como posso liberar a memória desses blocos no arquivo (elementos excluídos).

Tem uma forma de liberar a memória de um elemento em arquivo no Java ?

Método que remove

//Remover e reutilizar o bloco vazio, precisa ser privado.
	private void removeNo(int end) throws IOException {
		//Se o end. que quero remover  for da raiz, não precisa carregar ou seja Ler o end.
		No no = (end == endRaiz) ? raiz : leNo(end); 
		
		int endPai = no.pai;
		No pai = leNo(endPai);
		
		if(no.esq == NULL || no.dir == NULL) {
			//Se o endereço do no esquerdo for NULL ?(então) o filho único é o direito ou esquerdo.
			int endFilho = no.esq == NULL ? no.dir : no.esq;
			
			if(pai == null) {//Primeiro caso, caso seja a raiz.
				raiz = leNo(endFilho);//Precisa atualizar carregando na memória.
				gravaEndRaiz(endFilho);//Gravar a raiz na memória RAM.
			} else if(no.chave > pai.chave) {//Caso a chave não seja NULO.
				pai.dir = endFilho;
				gravaNo(pai, no.pai);
			} else { 
				pai.esq = endFilho;
				gravaNo(pai, no.pai);
			}
            //Atualizar o filho.
			if(endFilho != NULL) {
				No filho = leNo(endFilho);
				filho.pai = endPai;//Atualiza o endereço do pai.
				gravaNo(filho, endFilho);
			}
			
			empilhaBlocoVazio(end);//Coloco o endereço na pilha.
			System.out.println("-------------------Metodo remove-----------------");
			System.out.println("remove \t" + end);
		//Caso a chave tenha 2 filhos, coloca o antecessor para deixar a arvore correta.
		} else {
			int endAntecessor = no.esq;
			No antecessor = leNo(endAntecessor); 
			
			while(antecessor.dir != NULL) {
				endAntecessor = antecessor.dir;
				antecessor = leNo(endAntecessor);
			}
			
			no.chave = antecessor.chave;//Coloco a chave para manter a árvore.
			gravaNo(no, end);
			removeNo(endAntecessor);//Assim removo o antecessor.
		}
	}

Quando remove manda aqui nessa pilha

private void empilhaBlocoVazio(int end) throws IOException {
		
		RandomAccessFile arq = new RandomAccessFile(nomeArq, "rw");
		
		if(endTopoPilhaBlocosVazios == NULL) {
			arq.seek(END_CABECA_PILHA_BLOCOS_VAZIOS);
			arq.writeInt(end);
		} else {
			//arq.seek(endTopoPilhaBlocosVazios);
			arq.seek(END_CABECA_PILHA_BLOCOS_VAZIOS);
			int endProx = arq.readInt();
			arq.seek(end);
			arq.writeInt(endProx);
			arq.seek(END_CABECA_PILHA_BLOCOS_VAZIOS);
			arq.writeInt(end);
		}

		endTopoPilhaBlocosVazios = end;//Atualizar o endereço da pilha na memória RAM.
		System.out.println("-------------------Metodo empilhaBlocos-----------------");
		System.out.println("empilhaBlocoVazio \t" + endTopoPilhaBlocosVazios);
		//System.out.println("end \t" + end);
		arq.close();
		
		System.out.println("fechou \t" + endTopoPilhaBlocosVazios);
	}

2 Respostas

L

Os objetos não referenciados são excluídos pelo GC automaticamente, tanto no Java, como em Python e outras linguagens, mas se sabe que um elemento, a partir de um ponto, não será mais usado, por exemplo, em Python, poderia fazer del list[position], del variavel ou del object, em java, algo como variavel = null.
Veja este tópico, System.gc()

H

Calma lá, uma coisa é uma coisa, outra coisa é outra coisa :slight_smile:

Quando você cria um objeto no seu programa, ele está na memória. Por exemplo:

No pai = etc...

No caso, pai tem uma referência para uma instância de No (tem um objeto na memória, e pai aponta para ele).

Enquanto tiverem referências para aquele objeto, o GC não o coleta. “Só” isso. Você não controla quando isso acontece.

E não importa o que você faz com o objeto: se você escreveu o conteúdo dele em um arquivo, ou gravou no banco de dados, ou enviou em uma requisição HTTP, nada disso importa para o GC. O que importa é se ainda há referências para ele (se não tiver, ele é coletado).

Mas no seu caso, o que você grava no arquivo é um int (e não um No), então não entendi exatamente o que você quer saber. Mas basicamente, enquanto um No tiver alguém apontando para ele, não será coletado.

Criado 25 de abril de 2021
Ultima resposta 26 de abr. de 2021
Respostas 2
Participantes 3