Tenho uma duvida, sempre ouvi dizer que o modificador static compartilha o codigo com todas as instancia na memoria. A duvida é: Quando seto um static num metodo, o fato dele dizer que aquele metodo sera unico em todas as instancias daquela classe, farao que este metodo consuma menos memoria por ser unico e tenha uma execuçao mais rapida por ja estar carregado na memoria?
O que vcs acham desse static em metodos? Será bom mesmo sempre usar ele?
abraços
Não: o consumo de memória independe se o método é static ou não. O carregamento de um método é feito quando do carregamento de sua classe; a compilação desse método depende da quantidade de vezes que ele tiver sido executado.
Quando seto uma variavel membro como static, ela fica na memoria ate que a VM seja descarregada. Nao é?
Acredito que este mesmo comportamento se aplique igual a um metodo static, com isto nao teria um ganho na execuçao do metodo?
Pois todas as novas instancias aproveitariam o metodo ja carregado na memoria, de uma outra instancia utilizada.
Sempre soube que quando instanciava varias classes, aquele metodo static da classe era unico e se utilizava o mesmo espaço de memoria para todos.
Nao sei como a VM faria isso, tipo teria varias classes numa area da memoria que apontariam para outro trecho de memoria com aquele metodo compartilhado…
Se estou enganado, vc poderia me explicar melhor como seria este comportamento na memoria?
Alguém me corrija se eu estiver errado, mas pelo que eu sei, o que estará ou não na memória depende da máquina virtual. O funcionamento mais comum é criar, para cada objeto, uma área para os atributos e outra área para os métodos. Ao instanciar um novo objeto, caso já exista um objeto daquele tipo na memória, será criada uma referência interna para o conjunto de métodos já existente. Ao ser invocada a execução de determinado método, é criado um frame (estrutura interna da JVM para controle da pilha) e este frame irá conter os dados (incluindo atributos) a serem utilizados pelo método. Caso o mesmo método seja invocado diversas vezes, vários frames serão empilhados, como se o método estivesse na pilha diversas vezes.
Assim, quanto a estar na memória ou não, acredito que não existam grandes diferenças de performance/ consumo de recursos entre os métodos de classe e de instância. O que pode aumentar o consumo de recursos seria a operação de criação de novos objetos (new), considerada uma operação “lenta”.
Os métodos static são utilizados quando necessário. Quando existe a intenção de executar algum código sem a necessidade de gerar uma instância, que possivelmente será utilizada apenas para a execução de um método, ou em outros casos mais específicos.
Os métodos static são utilizados quando necessário. Quando existe a intenção de executar algum código sem a necessidade de gerar uma instância, que possivelmente será utilizada apenas para a execução de um método, ou em outros casos mais específicos.[/quote]
Com certeza são utilizados quando necessário.
Que casos específicos? Não consegui pensar em nenhum a não ser sem a necessidade de instância.
A minha pergunta é por que razão disseram que “não é aconselhável utilizar métodos static à toa”?
Deve estar no sentido de não programar corretamente, isso é óbvio.
No livro do Deitel tem uma dica de desempenho para usar métodos static sempre que a execução do método não precisar depender de um objeto.
[quote=davidtiagoconceicao]Alguém me corrija se eu estiver errado, mas pelo que eu sei, o que estará ou não na memória depende da máquina virtual. O funcionamento mais comum é criar, para cada objeto, uma área para os atributos e outra área para os métodos. Ao instanciar um novo objeto, caso já exista um objeto daquele tipo na memória, será criada uma referência interna para o conjunto de métodos já existente. Ao ser invocada a execução de determinado método, é criado um frame (estrutura interna da JVM para controle da pilha) e este frame irá conter os dados (incluindo atributos) a serem utilizados pelo método. Caso o mesmo método seja invocado diversas vezes, vários frames serão empilhados, como se o método estivesse na pilha diversas vezes.
.[/quote]
davidtiagoconceicao, gostei da sua explicaçao…
Porém neste modelo da VM nao vejo diferença entre um metodo static e nao static na area de memoria. ¿Como uma VM sabe que aquele metodo é static?
¿O que diferencia internamente numa VM algo ser static?
Por favor, falem o que tiver certeza, de preferência com referência bibliográfica de algum livro ou link, e não o que ouviu falar, porque eu já ouvi falar coisas diferentes sobre desempenho em Java. Só com uma referência confiável se pode tirar conclusões.
Conforme nosso amigo disse, não é aconselhável sair criando métodos como static à toa. Conforme havia dito, os métodos static podem ser utilizados quando não se quer forçar a criação de uma instância ou quando o programador não quer que exista instância (implementação do padrão singleton, por exemplo), pode ser utilizado para métodos que configuram atributos antes da instanciação da classe, ou para configurar atributos que serão utilizados por todas as instâncias da classe. Estes são alguns usos que já fiz do modificador static, mas os usos dele vão até o limite da sua imaginação
Acredito que ela obtém esta informação do bytecode e à partir daí efetua o controle necessário.
Infelizmente não posso pesquisar agora (mal estou tendo tempo para postar estas respostas :lol: ). Posso pesquisar mais tarde e postar os links. Em todos os casos, se você quizer realmente saber sobre performance e afins, sugiro que pesquise nas documentações da Sun sobre a linguagem e sobre a implementação da JVM.
Quando vc diz “forçar a criação de uma instância ou quando o programador não quer que exista instância”, mesmo sendo static se cria uma instancia na memoria de uma classe, se esta nao for um Singleton.
O ponto que eu me cituo e porque dizem que um metodo static e mais rapido que um metodo normal.
abraços
Quando você chama um método estático nenhuma instância é criada em lugar nenhum. É exatamente por não existir uma instância que o método é chamado de estático.
Vou me limitar ao ambiente Java EE, que é o que eu mais conheço.
Em Java EE, não use variáveis static. A variável static é iniciada quando é feita a primeira chamada à classe e todas as classes são criadas pelo classloader. Problema: os containeres de hoje em dia possuem váááários classloaders. Fatalmente, acabará criando algumas “instâncias” da variável static sem perceber.
Existem jeitos mais elegantes para o uso de static. Exemplo: se você precisa de um objeto único por toda a aplicação, crie um listener (registre-o no web.xml) onde, dentro dele, é criado um objeto que é guardado em escopo de aplicação.
Alguns casos de “singleton” são os façades, mas soluções como EJB3 e Spring estão aí para gerenciar esses tipos de objetos pra você.
[quote=Mauricio Linhares]
Quando você chama um método estático nenhuma instância é criada em lugar nenhum. É exatamente por não existir uma instância que o método é chamado de estático.[/quote]
Mas indiretamente a VM cria uma instancia da classe, pois imagina se vc tem uma variavel membro static… esta fica retida na memoria ate a VM ser derrubada… nao importando se vc cria o objeto via new ou chame via Classe.variavel
Creio que a VM diferencia de alguma forma o static nos metodos e variaveis dos sem. Se pensarmos no fato de um valor compartilhado permancer na memoria para todas as instancias, podemos imaginar em alguma acelaraçao no codigo por ja estar carregado…
[quote]What code shapes does the JVM optimize best? Here is a list.
[…]
Methods
* Methods are often inlined. This increases the compiler’s “horizon” of optimization.
* Static, private, final, and/or “special” invocations are easy to inline.[/quote] http://wikis.sun.com/display/HotSpotInternals/PerformanceTechniques
[quote=joaosiqueira]
Mas indiretamente a VM cria uma instancia da classe, pois imagina se vc tem uma variavel membro static… esta fica retida na memoria ate a VM ser derrubada… nao importando se vc cria o objeto via new ou chame via Classe.variavel
Creio que a VM diferencia de alguma forma o static nos metodos e variaveis dos sem. Se pensarmos no fato de um valor compartilhado permancer na memoria para todas as instancias, podemos imaginar em alguma acelaraçao no codigo por ja estar carregado…
abrs[/quote]
Não entendo a razão de haver alguma aceleração. Minha impressão: você está tentando argumentar um design ruim (o uso excessivo de static) em nome de uma suposta otimização de desempenho?
Lembre-se: se você estiver fazendo uma aplicação web, por exemplo, a suposta diferença entre o carregamento de uma variável static e outra não-static é simplesmente imperceptível para o usuário. Ou seja: faça sempre um bom design e não se preocupe com otimização, a menos que essa questão realmente apareça.
De nada, por favor, se encontrarem mais sobre o assunto postem aqui junto com os links!
Eu me interesso bastante nessa área de otimização, já li o livro “Java Platform Performance: Strategies and Tactics” e foi interessante. (tem disponibilizado em http://java.sun.com/docs/books/performance/)
Isto ainda nao responde as duvidas, pois vejo no artigo:
It’s OK to store them in static final fields, too.
Static final fields can hold non-primitive, non-string constants.
Static, private, final, and/or “special” invocations are easy to inline.
Portanto static sao muito mais rapidas… como se prova! Nao existem razoes para nao quererem usar, vejo o contrario indicaçoes recomendando da propria JVM!!