O que é 'referência JNI global'
Pergunta
Eu estou usando JProfiler para encontrar vazamentos de memória em um aplicativo Java Swing. Eu identifiquei instâncias de um JFrame que continua crescendo na contagem.
Esta estrutura é aberta e depois fechada.
Usando JProfiler e visualizar os caminhos para GC Root há apenas uma referência, 'JNI global de referência'.
O que isso significa? Por que é pendurado em cada instância do frame?
Solução
A Wikipedia tem uma boa visão do Java Native Interface , essencialmente, que permite a comunicação entre Java e nativas operar bibliotecas do sistema escrito em outras línguas.
referências globais de JNI são propensas a vazamentos de memória, como eles não são automaticamente lixo coletado, e o programador deve libertá-los explicitamente. Se você não está escrevendo qualquer código JNI mesmo, é possível que a biblioteca que você está usando tem um vazamento de memória.
Editar aqui é um pouco mais informações sobre vs. locais referências globais, e por referências globais são utilizados (e como eles devem ser libertados)
Outras dicas
A JNI referência global é uma referência de código "nativo" para um objeto Java gerido pelo coletor de lixo Java. Sua finalidade é evitar a recolha de um objeto que ainda está em uso por código nativo, mas não parece ter quaisquer referências ao vivo no código Java.
A JFrame é uma java.awt.Window
, e está associada a um objeto Window "nativo". Quando você está completamente terminado com uma instância JFrame particular, você deve invocar o seu método dispose()
para limpar.
Eu não tenho certeza se algum código nativo está criando uma referência global para o JFrame, mas parece provável. Se isso acontecer, isso vai impedir que o JFrame de ser lixo coletado. Se você estiver criando muitos do Windows (ou subclasses) e vendo que eles nunca são coletados, certifique-se de que eles são eliminados.
Eu tive esse problema exato em que o conserto de vazamentos de memória em um aplicativo JavaFX. No final, o problema acabou por ser que eu estava executando o aplicativo no modo de depuração e tinha vários pontos de interrupção no código. Esta parece ter causado objetos a ser "referência JNI Global e ser mantido na memória, sem razão aparente. Quando eu desliguei o modo de depuração tudo funcionou como deveria!