Mensagens enviadas por: ceklock
Índice dos Fóruns » Perfil de ceklock » Mensagens enviadas por ceklock
Autor Mensagem
Sobre o esquema de variáveis não usadas que eu falei, é isso que eu li há algum tempo atrás:


The HotSpot compiler is smart enough not to generate code for dead variables.



In the method above, the local variable is never used, so there's no reason to compute its value. So then the method body is empty again and when the code gets compiled (and inlined, because we removed enough code to make it small enough for inlining) it turns into an empty method again.


fonte: http://www.oracle.com/technetwork/java/hotspotfaq-138619.html

ViniGodoy wrote:Ah sim, claro. Você quis dizer que o JInternalFrame são janelas lightweight. Já que janelas são, tipicamente, os únicos componentes heavyweight do Swing.
Aí faz todo sentido.

Na verdade, foi o que pensei poucos segundos após postar para vc a resposta.



É, exatamente.

E eu estava fazendo uns testes com o profiler do NetBeans sobre esse assunto de janelas e etc... Mas não cheguei a uma conclusão ainda.
ViniGodoy wrote:Não percebi que você falou em "componente leve" se referindo a lightweight. Até porque, todos os componentes do Swing são lightweight, e não só o JInternalFrame:
http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/package-summary.html


Não. Não são todos os componentes do Swing que são lightweight.


The only heavyweight components used in Swing are:

swing.JFrame
swing.JDialog
swing.JWindow
swing.JApplet
All AWT components (awt.*), except those noted below.



fonte: http://java.sun.com/products/jfc/tsc/articles/containers/#heavyweights_and

ViniGodoy wrote:Não percebi que você falou em "componente leve" se referindo a lightweight. Até porque, todos os componentes do Swing são lightweight, e não só o JInternalFrame:
http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/package-summary.html

Não entendi o que você quis dizer com o stackoverflow ter mais moderação. Nossa discussão foi estritamente técnica, e encontra-se discussões desse tipo por lá também. Eu não me senti ofendido, nem irritado, pelos seus comentários, e nem "trocamos elogios".

De fato, eu concordo com muitos dos seus argumentos, como o fato de não ficar nulificando variáveis locais, e não ficar otimizando sem um profiler. Inclusive, já dei as mesmas dicas aqui no GUJ, para bastante gente. E sou um grande fã dos artigos do Goetz.

Entretanto, eu só estava deixando claro como funciona o mecanismo de liberação das janelas, sem entrar no mérito de se isso seria ou não uma boa prática sempre. É um erro muito comum acreditar que o dispose() libera toda a memória ocupada por uma janela, mesmo aquela pertencente à VM (como se ele magicamente ampliasse as capacidades do coletor de lixo).



O que eu quero dizer é que aqui as discussões acabam ficando muito longas.

ViniGodoy wrote:Você deve setar como null porque aquela variável não sai do escopo. Se o menu tiver 50 janelas, e cada uma for aberta uma vez, haverá 50 janelas na memória ao final do processo, mesmo que todas tenham sido fechadas!

De qualquer forma, com o que você falou, só vai haver a coleta da memória da janela anterior, quando a nova for aberta. Ou seja, no sistema, haverá pelo menos uma janela daquele tipo ocupando memória, a partir do momento que ela for aberta a primeira vez.



Tá bom. Não vou ficar discutindo. Eu particularmente prefiro sites como o http://www.stackoverflow.com onde tem mais moderação. Ao invés de ficar discutindo devíamos mostrar mais referências/fontes e fazer testes usando profilers.


E sobre componentes leves e pesados, é esse o significado:

"A heavyweight component is one that is associated with its own native screen resource (commonly known as a peer). A lightweight component is one that "borrows" the screen resource of an ancestor (which means it has no native resource of its own -- so it's "lighter")." - http://java.sun.com/products/jfc/tsc/articles/mixing/

Fica difícil tentar ajudar sem ver o código fonte. Cadê esse código fonte?
ViniGodoy wrote:
ceklock wrote:O negócio é o seguinte. Salvo alguma rara exceção, na grande maioria dos casos não é necessário setar uma variável como null. A máquina virtual sabe muito bem quando uma variável/atributo não é mais usado por ninguém.


Eu só discordo de que isso seja exceção, e mais ainda que seja raro.
Já atendi dezenas de tópicos no GUJ com exatamente esse problema.

Se você tem um JFrame assim (como o Visual Editor sugeria):


Você já terá que deixar janela1 null após o dispose(). É ainda mais comum no caso de ser um JInternalPane, uma vez que ele é associado a um DesktopPane. O dispose() não remove a janela do DesktopPane e, portanto, uma referência como a acima se faz necessária. É também necessária uma atitude explícita do programador.



Por que terá que deixar janela1 null?

Nesse caso que você citou acima quando chamar abrirJanela1() a próxima janela vai automaticamente ocupar o lugar da anterior (a variável janela1 vai receber um novo objeto), e a anterior vai perder referencia, desde que vc chame dispose() ao fechar a janela (use setDefaultCloseOperation(DISPOSE_ON_CLOSE) ).



E um JInternalFrame não é uma janela de verdade, é um componente leve. E pra que ficar setando janelas como null? O melhor é deixar só invisivel mesmo, e reutilizar depois. Afinal, é uma interface gráfica. Tu só vai se livrar de janelas se for estritamente necessário.

No fim tem que cuidar do que realmente é um gargalo pra memória e que poderia gerar um memory leak.

ViniGodoy wrote:Ceklock, como falei 3 vezes nesse tópico, não estou falando de definir variáveis que saem de escopo para null. Mas variáveis que se mantém no escopo, como no exemplo que citei anteriormente.

Definir variáveis que saem de escopo para null é desnecessário, pois essas variáveis deixarão de existir.

Aliás, o texto que você linkou, fala exatamente disso:
There is one case where the use of explicit nulling is not only helpful, but virtually required, and that is where a reference to an object is scoped more broadly than it is used or considered valid by the program's specification.


Esse caso que eles citam é uma exceção.

"Unfortunately, programmers often take this advice too far, using explicit nulling in the hope of helping the garbage collector. But in most cases, it doesn't help the garbage collector at all, and in some cases, it can actually hurt your program's performance. "

É isso o que vejo por aqui.

Esse link fala sobre essa história de setar variáveis para null. Fonte: Java theory and practice: Garbage collection and performance http://www.ibm.com/developerworks/java/library/j-jtp01274/index.html


Explicit nulling

Explicit nulling is simply the practice of setting reference objects to null when you are finished with them. The idea behind nulling is that it assists the garbage collector by making objects unreachable earlier. Or at least that's the theory.
There is one case where the use of explicit nulling is not only helpful, but virtually required, and that is where a reference to an object is scoped more broadly than it is used or considered valid by the program's specification. This includes cases such as using a static or instance field to store a reference to a temporary buffer, rather than a local variable, or using an array to store references that may remain reachable by the runtime but not by the implied semantics of the program. Consider the class in Listing 3, which is an implementation of a simple bounded stack backed by an array. When pop() is called, without the explicit nulling in the example, the class could cause a memory leak (more properly called "unintentional object retention," or sometimes called "object loitering") because the reference stored in stack[top+1] is no longer reachable by the program, but still considered reachable by the garbage collector.

Listing 3. Avoiding object loitering in a stack implementation


In the September 1997 "Java Developer Connection Tech Tips" column (see Resources), Sun warned of this risk and explained how explicit nulling was needed in cases like the pop() example above. Unfortunately, programmers often take this advice too far, using explicit nulling in the hope of helping the garbage collector. But in most cases, it doesn't help the garbage collector at all, and in some cases, it can actually hurt your program's performance.
entanglement wrote:Uma curiosidade.

Crie um programa que aloque 100 strings cada uma ocupando 1 MB de memória (ou seja, cada uma delas contém 500 mil caracteres). Ponha-as em um array e imprima a quantidade de memória usada pelo programa. Para garantir que é a memória mesmo, antes de imprimir, execute um System.gc, espere 2 segundos, e entáo execute outro System.gc.

A seguir, crie um outro array de 100 posicóes contendo substrings dessas strings grandes (digamos da pposiçao 1000 até a 2000). Imprima a mem[oria usada. Você deve ver que a quantidade praticamente não se alterou.

Então, limpe o primeiro array (aquele das strings grandes). Execute um System.gc e veja quanta memória está sendo usada.

Perguntas:
1) a quantidade de memória usada caiu ou não?
2) Por que é que isso ocorreu? (Dica: leia o fonte da classe String, método substring)
3) Como evitar esse problema esquisito?



1) a quantidade não vai cair
2) Isso se chama "memory leak" (na verdade não é bem um memory leak, mas se a pessoa não souber o que está fazendo pode ser considerado um) e existem casos em Java onde pode acontecer sim, sendo este um exemplo. substring() mantém referência à String original, por isso vai continuar ocupando a mesma quantidade de memória.
3) Saiba como funciona a classe String e seus métodos. Nesse caso dá pra usar new String(s.substring(...));


Enfim, esse não é o foco desse tópico, mas tudo bem.
Por mim podem encerrar esse tópico. A conversa já tá mudando o foco. Minha dúvida já foi esclarecida.
O negócio é o seguinte. Salvo alguma rara exceção, na grande maioria dos casos não é necessário setar uma variável como null. A máquina virtual sabe muito bem quando uma variável/atributo não é usado.

O dispose() serve justamente para "desamarrar" a janela. Se ela nunca mais for usada ela vai "sumir" da memória até que algum dia seja chamado um método setVisible() ou algo parecido.

E tudo que está dentro da janela pertence à janela e vai "sumir" junto com ela. Se tem um botão adicionado numa janela e eu matar a janela eu não preciso remover o botão da janela para ele ser removido da memória.


http://docs.oracle.com/javase/6/docs/api/java/awt/Window.html#dispose()
É só questão de descarregar da memória as imagens que foram carregadas.

Não vi o código fonte, portanto não sei dizer como remover essas imagens. Mas seria algo assim:

- remove a imagem da janela (depende de como você desenhou/exibiu a imagem);
- descarrega a imagem / limpa buffer;
entanglement wrote:
O "garbage collector" lida com apenas um tipo de recurso finito, que é a memória usada por seu programa. Não é atribuição dele sair limpando outros tipos de recursos.


Isso é claro. Recursos do sistema não são responsabilidade da JVM e devem ser devidamente encerrados quando não são mais utilizados.
lina wrote:
ceklock wrote:
lina wrote:Oi,

A principio, isso me parece um ponto negativo da linguagem (eu não esperava ter que dizer isso um dia).

O Java ou a linguagem deveria interpretar que determinado comando, como o dispose(), deveria remover toda a referência do objeto. A não ser que exista uma razão muito complexa para que isso não aconteça. (?!)

Tchauzin!



dispose() não faz isso? Pelo que pude entender até agora toda a janela e os componentes associados a ela são liberados da memória.


Oi,

Eu entendi ao contrário...

Exemplo:



Fechando:



Liberando da memoria:



Tchauzin!




Eu sempre fiz assim e vou continuar fazendo:



Não precisa de
 
Índice dos Fóruns » Perfil de ceklock » Mensagens enviadas por ceklock
Ir para:   
Powered by JForum 2.1.8 © JForum Team