Existe uma maneira de liberar memória em Java, semelhante à free()
função de C ? Ou definir o objeto como nulo e confiar na GC é a única opção?
java
garbage-collection
Felix
fonte
fonte
Respostas:
Java usa memória gerenciada; portanto, a única maneira de alocar memória é usando o
new
operador, e a única maneira de desalocar memória é contando com o coletor de lixo.Este white paper de gerenciamento de memória (PDF) pode ajudar a explicar o que está acontecendo.
Você também pode ligar
System.gc()
para sugerir que o coletor de lixo seja executado imediatamente. No entanto, o Java Runtime toma a decisão final, não o seu código.De acordo com a documentação Java ,
fonte
System.gc()
completamente.Parece que ninguém mencionou a definição explícita de referências a objetos
null
, que é uma técnica legítima para "liberar" a memória que você pode querer considerar.Por exemplo, digamos que você tenha declarado um
List<String>
no início de um método que cresceu em tamanho para ser muito grande, mas só foi necessário até a metade do método. Nesse ponto, você pode definir a referência de listanull
para permitir que o coletor de lixo potencialmente recupere esse objeto antes que o método seja concluído (e a referência fica fora do escopo de qualquer maneira).Observe que raramente uso essa técnica na realidade, mas vale a pena considerar ao lidar com estruturas de dados muito grandes.
fonte
Não recomendado.
Edit: eu escrevi a resposta original em 2009. Agora é 2015.
Os coletores de lixo ficaram cada vez melhores nos ~ 20 anos que o Java existe. Neste ponto, se você estiver chamando manualmente o coletor de lixo, convém considerar outras abordagens:
fonte
* "Pessoalmente, confio nas variáveis de nulidade como espaço reservado para futura exclusão adequada. Por exemplo, dedico um tempo para anular todos os elementos de uma matriz antes de excluir (tornar nula) a própria matriz."
Isso é desnecessário. A maneira como o Java GC funciona é encontrar objetos que não têm referência a eles; portanto, se eu tiver um Objeto x com uma referência (= variável) a que aponte para ele, o GC não o excluirá, porque há uma referência para esse objeto:
Se você nulo a, isso acontece:
Portanto, agora x não tem uma referência apontando para ele e será excluído. O mesmo acontece quando você define a para fazer referência a um objeto diferente de x.
Portanto, se você tem um arr arr que faz referência aos objetos x, ye z e uma variável a que faz referência ao array, fica assim:
Se você nulo a, isso acontece:
Portanto, o GC considera arr como não tendo nenhuma referência definida e a exclui, o que fornece essa estrutura:
Agora o GC encontra x, ye z e os exclui também. Anular cada referência na matriz não melhorará nada, apenas consumirá o tempo e o espaço da CPU no código (dito isso, não será prejudicial além disso. O GC ainda poderá executar da maneira que deve )
fonte
Um motivo válido para querer liberar memória de qualquer programa (java ou não) é disponibilizar mais memória para outros programas no nível do sistema operacional. Se meu aplicativo java estiver usando 250 MB, convém forçá-lo a 1 MB e disponibilizar os 249 MB para outros aplicativos.
fonte
Para estender a resposta e o comentário de Yiannis Xanthopoulos e Hot Licks (desculpe, ainda não posso comentar!), Você pode definir opções de VM como este exemplo:
No meu jdk 7, isso liberará memória não utilizada da VM se mais de 30% do heap ficar livre após o GC quando a VM estiver ociosa. Você provavelmente precisará ajustar esses parâmetros.
Embora eu não tenha visto isso enfatizado no link abaixo, observe que alguns coletores de lixo podem não obedecer a esses parâmetros e, por padrão, o java pode escolher um deles para você, caso você tenha mais de um núcleo (daí o argumento UseG1GC acima )
Argumentos da VM
Atualização: Para o java 1.8.0_73, vi a JVM ocasionalmente liberar pequenas quantidades com as configurações padrão. Parece fazê-lo apenas se ~ 70% da pilha não for usada .. não sei se seria mais agressivo se o sistema operacional estivesse com pouca memória física.
fonte
Eu fiz experiências sobre isso.
É verdade que
System.gc();
apenas sugere executar o Garbage Collector.Mas chamar
System.gc();
depois de definir todas as referências paranull
, melhorará o desempenho e a ocupação da memória.fonte
Se você realmente deseja alocar e liberar um bloco de memória, pode fazer isso com ByteBuffers diretos. Existe até uma maneira não portátil de liberar a memória.
No entanto, como foi sugerido, apenas porque você precisa liberar memória em C, não significa que seja uma boa ideia fazer isso.
Se você acha que realmente tem um bom caso de uso gratuito (), inclua-o na pergunta para que possamos ver o que você está tentando fazer, é bem provável que exista uma maneira melhor.
fonte
Inteiramente de javacoffeebreak.com/faq/faq0012.html
fonte
No meu caso, como meu código Java deve ser portado para outras linguagens em um futuro próximo (principalmente C ++), eu pelo menos quero prestar um bom serviço para liberar memória adequadamente, para ajudar no processo de portabilidade posteriormente.
Pessoalmente, confio nas variáveis de nulidade como espaço reservado para futura exclusão adequada. Por exemplo, dedico um tempo para anular todos os elementos de uma matriz antes de realmente excluir (tornar nulo) a própria matriz.
Mas meu caso é muito particular e sei que estou recebendo resultados de desempenho ao fazer isso.
fonte
* "Por exemplo, digamos que você tenha declarado uma lista no início de um método que cresceu em tamanho para ser muito grande, mas só era necessária até a metade do método. Nesse momento, era possível definir a referência da lista como nula para permitir que o coletor de lixo potencialmente recupere esse objeto antes que o método seja concluído (e a referência fica fora do escopo de qualquer maneira). " *
Isso está correto, mas esta solução pode não ser generalizável. Ao definir uma referência de objeto de lista como nula - disponibilizará memória para coleta de lixo, isso é válido apenas para um objeto de lista de tipos primitivos. Se, em vez disso, o objeto List contiver tipos de referência, a configuração do objeto List = null não desreferirá - qualquer um dos tipos de referência contidos - na lista. Nesse caso, definir o objeto List = null tornará órfão os tipos de referência contidos cujos objetos não estarão disponíveis para coleta de lixo, a menos que o algoritmo de coleta de lixo seja inteligente o suficiente para determinar que os objetos foram órfãos.
fonte
Por meio do java, fornece coleta de lixo automática às vezes, você deseja saber o tamanho do objeto e a quantidade restante. Memória livre usando programaticamente
import java.lang;
eRuntime r=Runtime.getRuntime();
obter valores de memória usandomem1=r.freeMemory();
a memória livre para chamar or.gc();
método e a chamadafreeMemory()
fonte
A recomendação do JAVA é atribuir a null
De https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html
fonte