Modificador static nos metodos, codigo mais rapido?

89 respostas
J

Hola pessoal,

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 :slight_smile:

89 Respostas

T

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.

Não é bom usar static em métodos à toa.

J

Hola,

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?

abrs :lol:

D

Se não é aconselhável usar static em métodos, porque é utilizado na API do Java para diversos métodos?

D

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.

D

davidtiagoconceicao:

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.

Com certeza são utilizados quando necessário. :stuck_out_tongue:
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.

J

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.
.

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?

abraços :shock:

D

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.

D

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 :slight_smile:

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.

J

Hola davidtiagoconceicao,

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 :slight_smile:

M

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.

L

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ê.

J

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.

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

D

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.

http://wikis.sun.com/display/HotSpotInternals/PerformanceTechniques

D

Muito bom dionat4n, obrigado pelas informações.
Também vou ler mais sobre o assunto.

L

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

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.

D

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/)

Lá também explica como funciona o Java HotSpot, vale a pena dar uma olhada.
http://java.sun.com/docs/books/performance/1st_edition/html/JPAppHotspot.fm.html#998924

J


Hola,

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!!

C

Tente usar nomes de variaveis de uma letra so, fica mais rapido tb! :lol:

Agora serio, se vc quer evitar o custo de criacao do objeto seria mais inteligente fazer um cache do mesmo.

D

Como se faz cache do objeto? hehe

F

Hola joaosiqueira

Minha opinião sobre o tema:

  1. Alta performance e baixo uso de memória em sistemas OO sempre foi uma questão difícil de resolver vamos dizer assim.

  2. O uso mínimo ou nenhum uso de statics é uma caracteristica de bons designs.

Indo mais direto ao ponto: O código sendo estatico ou não ele tem que estar em um trecho da memória da máquina, como o sistema operacional + JVM não são bobos eles mantem estes trechos de código registrado na memória o máximo possível (provavemente seguindo alguma regra baseado no uso). Se tanto o código estatico e o não estático se encontram na mesma condição, vamos dizer assim, resta uma coisa que vou chamar de “code pointer” que aponta para o local da memória onde está o início do trecho de código que será processado; para este mecanismo não importa se o código é estatico ou não o processador verifica o endereço, desloca, processa e pronto.

Resumindo: A questão de ser static está mais associado com estrategia do que com performance, alguns programadores utilizam static ao definir constantes; pois se é uma constante eles não encontram muito sentido deixar o valor ser criado em todas as instancias da classe.

flws.

M

joaosiqueira:
davidtiagoconceicao:

What code shapes does the JVM optimize best? Here is a list.
Methods



Hola,

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!!

Este trecho cita também métodos private e final. E não prova nada, só diz que é mais fácil de otimizar. No máximo, será mais rápido para compilar - não é possível se basear nisso em tempo de execução.

No mais, acredito que procurar “otimizações” para uso do static seja apenas querer argumentar a favor de um design mal projetado: nada contra o uso dele, mas existem casos e casos.

J

Se vc pensar que todas variaveis membro declarados como static ficam carregas ate vc derrubar a VM, indica q existe um tipo de “cache estatico” na memoria, nao e?

Por isso, partindo desta ideia teriamos uma acelaraçao para os metodos static.
Nao estou considerando design e melhores praticas de refatoraçao.

Pensemos somente em velocidade de execuçao para um código!!

abrs

M

joaosiqueira:

Se vc pensar que todas variaveis membro declarados como static ficam carregas ate vc derrubar a VM, indica q existe um tipo de “cache estatico” na memoria, nao e?

Por isso, partindo desta ideia teriamos uma acelaraçao para os metodos static.
Nao estou considerando design e melhores praticas de refatoraçao.

Pensemos somente em velocidade de execuçao para um código!!

abrs

Mas se você criar um objeto e passar ele pelo seu programa, ele também fica em memória… No final, todo o ‘custo adicional’ seria relacionado à criação do objeto.

E não entendi como você chegou a conclusão de que um método static pode ser mais rápido se as variáveis static ficam em cache…

D

Uma dúvida:
Se for criado X>1 objetos do tipo T,
cada objeto T com um método M (não estático),
serão criados X códigos para os métodos dps X objetos? Ou será criado apenas um código na memória e compartilhado entre os objetos?
(por favor, respondam com certeza)

V

Olha, na maioria das JVMs comerciais (todas, eu acho), cada objeto corresponde a uma área de memória. No offset 0 está a referência ao objeto Class correspondente (aquilo que é retornado pelo Object.getClass()), e os demais espaços da área de memória do objeto contém os atributos, um após o outro.

Existem quatro tipos de bytecodes de chamada de métodos: invokestatic, invokevirtual, invokeinterface e invokespecial. Há propostas para que no java 7 apareça o invokedynamic.

De uma forma simples*, podemos dizer que o invokestatic recebe como parâmetro um ponteiro para um objeto Class, um ID de um método estático e um monte de tipos primitivos e ponteiros de Objects que são os parâmetros. Então a JVM vai lá no objeto Class, procura o método ESTÁTICO correspondente ao ID e o invoca passando-lhe os parâmetros.

O invokevirtual e o invokeinterface recebem como parâmetro um ponteiro de um objeto que é a instância em que o método é invocado, um ID de um método não-estático e os parâmetros. A JVM verifica se o ponteiro da instância é nula e lança NullPointerException se for. Se não for, ela vai lá no endereço apontado pelo ponteiro da instância (que é onde está o objeto) e pega a classe deste (que está no offset 0, ou seja exatamente para onde o ponteiro aponta). Tendo então a classe, ela procura o método NÃO-ESTÁTICO correspondente ao ID e o invoca passando-lhe os parâmetros.

O invokespecial é para a chamada de construtores e se não me engano chamada de métodos sobrescritos da superclasse (não sei bem direito como isso funciona no nível dos bytecodes, mas isso não é relevante aqui neste tópico). O invokedynamic vamos deixar para quando sair o java 7.

Então, a estrutura do objeto não contém referências aos métodos. O objeto tem apenas um ponteiro para o objeto Class correspondente e os atributos um após o outro. A JVM usa o ponteiro para o objeto Class para localizar os métodos. Desta forma, objetos de uma mesma classe, ao apontar para o mesmo objeto Class usarão os mesmos métodos que estão no mesmo endereço de memória. Portanto, não há diferenças no uso da memória ou no desempenho** ao deixar um método como estático ou não-estático.

    • Simples, bem simples, para leigos entenderem.
      ** - Nunca vi nenhum benchmark de quanto tempo a JVM demora para empilhar os parâmetros para a chamada do método (incluindo o ID do método e a referência da instância do invokevirtual/invokeinterface), e nem quanto tempo ela demora para verificar se a referência da instância é nula ou não. Mas seja lá qual for este tempo, ele deve ser ínfimo e desprezível. Se você está tão desesperado por desempenho que isto pode lhe fazer diferença, então você nem devia estar programando em java, e sim em assembler (ou até no hardware).

EDITs: Correções de pequenos erros.

D

Boa explanação victorwss!

T

Completando o que o Victor disse.

Teoricamente, uma chamada “virtual” é um pouquinho* mais lenta que uma chamada não-virtual (e é por isso que o default do C# e do C++ - as chamadas são só “virtual” se forem explicitamente especificadas - é diferente do default do Java). Isso porque em vez de chamar o método diretamente, sem prestar atenção à classe do objeto, o Java deveria chamar o método indiretamente, por um ponteiro contido na definição da classe. Procure por “VTBL” na Internet.

Entretanto,
A JVM compensa esse fato de a chamada ser mais lenta efetuando uma pré-análise da chamada. Se for determinado em tempo de compilação just-in-time que a chamada não precisa ser “virtual” (ou seja, a variável contém um objeto de um determinado tipo apenas, em vez de ficar trocando de tipos que têm em comum apenas a mesma superclasse ou superinterface), então a JVM não faz a chamada virtual e sim a chamada direta (é como se ela determinasse que uma “invokevirtual” na verdade pudesse ser tão rápida quanto uma “invokespecial”).
Então não é necessário ficar especificando ou não “virtual” em Java, como é feito no C# ou no C++. Se vocês já programaram em alguma dessas linguagens, viram que na prática vocês acabam tendo de especificar sempre “virtual” para os métodos, para evitar alguns problemas esquisitos. Ou seja: veja o que o Java simplifica para vocês.

J

Por favor, me expliquem a diferença na memoria neste codigo static.
NAO adianta dizer q de uma forma eu crio uma instancia e na outra nao com o uso do new, pois penso q no final tudo se cria uma instancia internamente na VM. Pelo que li nos post acima, o desempenho seria igual nos 2, mas o q difere um do outro?

class T{
	static void show(){
		System.out.println("ddd");
	}
}

public class Lixo {

	public static void main(String[] args) {
		T.show();
		new T().show();
	}

}

Como o valor atribuido a um atributo static de uma clase pode manter um valor na memoria ate que a VM seja descarregada, onde esse valor e guardado pra que todas as classes possam ler o valor armazenado e compartilhado?

abrs

T

A chamada a um método estático de uma classe não envolve instanciar essa classe, apenas carregá-la. Portanto o que você disse está errado. Uma forma de você saber isso é criar um construtor e ver quantas vezes esse construtor é chamado: ele será chamado apenas 1 vez.

T

Resumidamente, o valor atribuído a um atributo static é referenciado pelo objeto do tipo java.lang.Class que representa essa classe. Internamente a JVM cria um objeto java.lang.Class para cada classe carregada (para cada classloader), e que contém uma lista dos atributos static dessa classe.

Então, os métodos podem ler o tal valor armazenado e compartilhado referindo-se a essa classe.

J
thingol:
A chamada a um método estático de uma classe não envolve instanciar essa classe, apenas carregá-la. Portanto o que você disse está errado. Uma forma de você saber isso é criar um construtor e ver quantas vezes esse construtor é chamado: ele será chamado apenas 1 vez.

Thingol,

Isto de ser chamado 1 vez nao acontece.. fiz ate o exemplo e veja:

class T{
	T(){
		System.out.println("T");
	}
	static void show(){
		System.out.println("ddd");
	}
}

public class Lixo {

	public static void main(String[] args) {
		T.show();
		T.show();
		
		new T().show();
		new T().show();
	}
}

OutPut:
ddd
ddd
T
ddd
T
ddd

Cade essa unica vez q vc falou???

T

Se você chamou “new T” uma vez, então o construtor vai ser chamado 1 vez. Se você chamou 2 vezes (como é o seu caso), vai ser chamado 2 vezes. Eu é que não seu contar?

J

Thingol,

O que vc quiz dizer e que qdo eu uso o new passo pelo construtor, e qdo chamo o metodo static direto nao posso pelo construtor… certo???

Agora me explique, pra eu carregar uma classe eu nao preciso instanciala internamente? Nao entendo como posso carregar algo sem automaticamente instanciar, vejo como um processo sequencia… ? Mesmo que o construtor nao seja invocado, instanciar e uma forma de carregar…

Posso pensar que o T.show() e uma outra forma de instanciar uma classe na memoria sem passar por um construtor… tipo, a VM faz uma instancia diferenciada pro static…

Nao acha algo logico isso? :slight_smile:

T

Carregar uma classe (ou seja, carregar o código do arquivo .class ou .jar para poder chamar algum de seus métodos) é diferente de instanciar essa classe (ou seja, criar um objeto que pertence a essa classe.)

As palavras são diferentes (carregar X instanciar), porque o que é feito em cada caso é diferente.

J

Thingol,

Entao podemos dizer que qdo eu faço uma Reflection de uma classe, estou carregando da mesma forma que um static faz?

Se eu pensar neste modelo, sempre que dizer que um Reflection e mais lento do que dar um new, certo?? Teria que dizer que o static e mais lento tb, nao e?

O que vc acha disso?
:twisted:

M

joaosiqueira:
Thingol,

Entao podemos dizer que qdo eu faço uma Reflection de uma classe, estou carregando da mesma forma que um static faz?

Se eu pensar neste modelo, sempre que dizer que um Reflection e mais lento do que dar um new, certo?? Teria que dizer que o static e mais lento tb, nao e?

O que vc acha disso?
:twisted:

Impressão minha ou esse cara escreve feito o Márcio Duran?

J

Mauricio Linhares,

Por favor, so responda a minha pegunta! Pois e uma questao de logica de associaçao…
Afinal e educaçao respeitar a opiniao do outros.

abrs

L

Peraí,

vc entende o significado de new T().show() abaixo?

class T{
	static void show(){
		System.out.println("ddd");
	}
}

public class Lixo {

	public static void main(String[] args) {
		T.show();
		new T().show();
	}

}

Como o pessoal falou, os atributos estáticos pertencem à java.lang.Class. Quando você tem um método estático, mesmo que você dê new, o método não é aplicado ao objeto que vc criou, mas sim à classe da instância.

Então, dizer que existe diferença entre T.show() e new T().show() é absurdo, ambas são exatamente a mesma coisa! A única diferença é que no segundo exemplo, você simplesmente cria uma instância e a joga imediatamente.

Minha impressão é que você não entende muito de orientação a objetos, acredito que você precise dar uma estudada sobre isso.

J

Ola pessoal,

Uma duvida:

O processo que o modificador static faz nao e a mesma ideia que uma Reflection ?
Sempre que dizemos que um Reflection e mais lento do que dar um new, certo??

Portanto teria que dizer que o static e mais lento tb que fazer uma instanciaçao, nao e?

Qual o opiniao de vcs nisso?

abrs :slight_smile:

C

Acho que uma instancia “new” pode gastar mais memoria do que fazer uma chamada static direto.

Mas nao tenho certeza disso, vcs que me corrijam se estiver enganado.

J

Ninguem poderia ajudar com a minha dúvida, por favor? :?:

M

joaosiqueira:
Ola pessoal,

Uma duvida:

O processo que o modificador static faz nao e a mesma ideia que uma Reflection ?
Sempre que dizemos que um Reflection e mais lento do que dar um new, certo??

Portanto teria que dizer que o static e mais lento tb que fazer uma instanciaçao, nao e?

Qual o opiniao de vcs nisso?

abrs :slight_smile:

Não. Não necessariamente. Não.

E sua pergunta já estava respondida pelo post do victorwss.

V

Não confunda carregar uma classe com instanciar uma classe. São coisas bem diferentes.

Carregar uma classe = A JVM lê um arquivo .class e inicialmente vê apenas um monte de bytes. Então ela lê estes bytes e monta a estrutura da classe (com os métodos, atributos e todas as instruções que há nos métodos). Toda esta estrutura é carregada internamente na JVM e pode ser parcialmente acessada por meio da classe java.lang.Class. Sempre que uma classe é carregada, a JVM cria um objeto do tipo java.lang.Class para representá-la. Imediatamente após isto ser feito, a JVM inicializa os valores dos atributos estáticos bem como os blocos de inicialização de classe (na verdade toda esta inicialização nos bytecodes aparece como um método chamado “<clinit>”.

Instanciar uma classe = A JVM aloca uma área de memória do tamanho necessário para a instância e a limpa (para evitar problemas com memória não-inicializada, comuns em C e C++). Por estar limpa significa que todos os atributos terão o valor inicial false para campos boolean, 0 para os demais primitivos e null para campos de tipo objeto. Em seguida a JVM coloca na primeira parte desta área alocada o ponteiro para o objeto Class correspondente (que é aquilo que o método getClass() retorna) e após isto, o construtor é invocado como se fosse um método void.

Para a classe ser instanciada, ela precisa ser primeiramente carregada.
Sempre que a JVM vê que uma classe precisa ser carregada, ela a carrega automaticamente sem que você peça isso. Se na inicialização da classe uma exceção for lançada, um ExceptionInInitializerError é lançado. Isso é um Error porque em geral a hora em que uma classe é inicializada costuma ser pouco previsível ou controlável. E se a classe não pôde ser inicializada corretamente, então fatalmente ela não poderá ser usada adequadamente.

J

victorwss,

Muito boa boa sua explicaçao, gostei mesmo.

Mas nesse momento nao teriamos que concordar com o ccaneta?

Quando diz que o fato de usar uma classe carregada usaria menos memoria e evitaria o tempo de instanciar uma classe, ao contrario do new em que temos que carregar e depois instanciar?

Pensando assim usar um static seria mais vantajoso?
Eu penso logicamente que 1 passo e sempre mais rapido que 2 passos, agora nao sei a opiniao de voces em relaçao a isso…

O que vcs opinam?

:smiley:

A

Mauricio Linhares:
joaosiqueira:
Thingol,

Entao podemos dizer que qdo eu faço uma Reflection de uma classe, estou carregando da mesma forma que um static faz?

Se eu pensar neste modelo, sempre que dizer que um Reflection e mais lento do que dar um new, certo?? Teria que dizer que o static e mais lento tb, nao e?

O que vc acha disso?
:twisted:

Impressão minha ou esse cara escreve feito o Márcio Duran?

Impressão minha ou ele é um fake do Mr. Duran Duran?

L

joaosiqueira:
victorwss,

Muito boa boa sua explicaçao, gostei mesmo.

Mas nesse momento nao teriamos que concordar com o ccaneta?

Quando diz que o fato de usar uma classe carregada usaria menos memoria e evitaria o tempo de instanciar uma classe, ao contrario do new em que temos que carregar e depois instanciar?

Pensando assim usar um static seria mais vantajoso?
Eu penso logicamente que 1 passo e sempre mais rapido que 2 passos, agora nao sei a opiniao de voces em relaçao a isso…

O que vcs opinam?

:smiley:

Um passo é mais rápido que dois passos, obviamente. Mas sua aplicação não rodará duas vezes mais rápido só porque você teve preguiça de usar OO e usou static em tudo quanto é quanto. O motivo é simples: a instanciação de objetos não é parte mais custosa de aplicação. O que é custoso é mandar queries no banco de dados, escrever arquivos, enviar dados via rede, fazer serialização, parsear XML… Ou seja, instanciar ou não objetos é coisa ínfima, perto de muitas outras coisas.

E eu já falei que não é recomendável usar variáveis estáticas em ambiente Java EE, devido aos múltiplos classloaders, não falei? Sabia que há problema na serialização de objetos quando a variável é estática? Lembre-se também que muitos containeres dependem que seus métodos não sejam estáticos.

Então qual é o ponto? Você quer provar que orientação a objetos não vale a pena?

J

Leonardo3001,

Nao estamos pensando em fatores de midleware, somente num simples trecho de codigo java ao maximo da performance…

Pelo que vejo, vc ja esta concordando comigo em alguma coisa:
1 processo e mais rapido que 2

Portanto se com um metodo static eu evito um processo de instanciaçao, vemos que um static por mais desaconselhavel de praticas de design, J2EE e etc, e mais rapido e nao podemos negar!

Quando vamos começar a pensar que o simples gera o avançado, e nao pensar que nem sempre temos memoria em todos os dispositivos… ja pensou se um aplicativo java da Nasa pudesse usar o que um simples cadastro exige num mero PC!!
:shock:

M

Essa aula de Static e Refletion já vai ser bom pro seu curriculum hein… mais ainda Heap e Stack são assuntos basico até para certificação Java hein… [size=18]; )[/size]

L

joaosiqueira:
Leonardo3001:

Um passo é mais rápido que dois passos, obviamente. Mas sua aplicação não rodará duas vezes mais rápido só porque você teve preguiça de usar OO e usou static em tudo quanto é quanto. O motivo é simples: a instanciação de objetos não é parte mais custosa de aplicação. O que é custoso é mandar queries no banco de dados, escrever arquivos, enviar dados via rede, fazer serialização, parsear XML… Ou seja, instanciar ou não objetos é coisa ínfima, perto de muitas outras coisas.

Leonardo3001,

Nao estamos pensando em fatores de midleware, somente num simples trecho de codigo java ao maximo da performance…

Pelo que vejo, vc ja esta concordando comigo em alguma coisa:
1 processo e mais rapido que 2

Portanto se com um metodo static eu evito um processo de instanciaçao, vemos que um static por mais desaconselhavel de praticas de design, J2EE e etc, e mais rapido e nao podemos negar!

Quando vamos começar a pensar que o simples gera o avançado, e nao pensar que nem sempre temos memoria em todos os dispositivos… ja pensou se um aplicativo java da Nasa pudesse usar o que um simples cadastro exige num mero PC!!
:shock:

Não realidade, quando concordo que “um é mais rápido que dois”, não implica que concordo que static é mais rápido que dar new. Na verdade, não tenho a inteligência do Kumpera para detalhes do baixo nível do Java. Tudo que sei é que, pela minha experiência, não há diferenças, para o usuário, entre uma aplicação que usa static de outra que não usa.

J2EE não é só para middleware. A maioria das pessoas usam a plataforma para fazer aplicações web também.

Quando não se tem memória, deve-se evitar usar muitos recursos, só isso, não tem nada a ver fazer instanciação ou não. Outra, otimizações locais não resultam em grandes melhorias no resultado final. Otimizar é pensar globalmente, na aplicação como um todo, não em detalhes irrelevantes de baixo nível.

Aplicações da Nasa, ou até do Google, tem requisitos tão especiais que acredito que eles utilizam só a linguagem Java, a plataforma é proprietária feita por eles mesmos. Mas ainda assim, acho impossível eles sugerirem que se deva usar static ao invés de instanciar objetos.

M

Você não consegui relacionar static com SOA ,você sabe como isso fuciona ?

B

Numa análise fria, nestes termos super-simplificados, sim, static é mais rápido.

E quem vir essa frase acima e for usar static pra tudo, e digo parabéns. Parabéns por ferrar com toda a arquitetura do teu projeto p/ ganhar alguns microsegundos. Ou parabéns por usar uma arquitetura totalmente procedural numa linguagem orientada a objetos, e ignorar todos os outros recursos úteis da linguagem.

A discussão foi ótima com toda a explicação técnica do que acontece nos bastidores, útil para quem quiser fazer algo extremamente avançado e específico. Para o resto, isso só serve para inflar o ego pra dizer que estavam certos, mesmo que não tenha a mínima importância na vida deles.

M

Bruno Laturner:
Numa análise fria, nestes termos super-simplificados, sim, static é mais rápido.

E quem vir essa frase acima e for usar static pra tudo, e digo parabéns. Parabéns por ferrar com toda a arquitetura do teu projeto p/ ganhar alguns microsegundos. Ou parabéns por usar uma arquitetura totalmente procedural numa linguagem orientada a objetos, e ignorar todos os outros recursos úteis da linguagem.(…)…


:arrow:In object-oriented Java were a great improvement over the procedural paradigm (Naturalmente isso é baseado em que Arquitetura estamos falando se Framework) ou se ERP´s,ou você quer discutir OFBIZ ?,pois nessa tecnologia existem serviços static, você sabia ???

J

Bruno,

Acredito que a razao aqui nao e provar nada para ninguem dizendo vc esta certo ou errado, e apenas buscar uma melhor soluçao num momento critico…
No mundo de TI, existem momentos em que termos a melhor arquitetura e a melhor saida… mas como digo, existem outros momentos em que queremos somente perfomance ao limite!!

Ai nao adianta botarmos patterns, patterns, pq o que vai deixar rapido de verdade é o código simples ao extremo e quanto mais estruturado melhor! Como um profissional de TI posso lhe garantir!

Mas a grande enquente aqui foi, so se um static era mais rápido num metodo, e como podemos concluir isso é verdade! Depois de muita polemica e contradiçao no forum GUJ.

Se pensarmos isso é bonito? Talvez nao, mas se olharmos de outro angulo as vezes e a melhor soluçao, so cabe a vc decidir quando fugir ao extremo.

:slight_smile:

T

Uma coisa que brasileiro adora é tomar decisões na seguinte base:

  • Eu acho que…
  • Ouvi falar que…
  • Me falaram que…
    e a pior:
  • Minha opinião é que…

Em vez de fazer experimentos e verificar os números. Nesse caso é relativamente fácil determinar os números.

Como dizia um personagem do Jô Soares, “meu negócio é números”.

Então que tal fazer alguns “benchmarks” e ver qual é a diferença de tempo entre usar “static” ou não?

Já vou antecipando que a diferença é desprezível na maior parte dos casos de uso, mas não tomem minha palavra por verdade absoluta.

J

thingol:

Então que tal fazer alguns “benchmarks” e ver qual é a diferença de tempo entre usar “static” ou não?

Já vou antecipando que a diferença é desprezível na maior parte dos casos de uso, mas não tomem minha palavra por verdade absoluta.

Thingol,

Estou partindo por lógica que 1 passo e mais rápido que 2
Ai e so a questao de averiguar o quanto mais rápido, mas a lógica sempre vem antes de testar e programar…

Quem nunca ouviu de “tentiva e erro na programaçao”, ai quem sofre é o compilador! rs…
:roll:

M

thingol:

Então que tal fazer alguns “benchmarks” e ver qual é a diferença de tempo entre usar “static” ou não?

Não podemos ter intuições ou entender observância sobre o que é o melhor estudo de viabilidade ou escalabilidade de fatores complicadores, você toma decisão através de uma calculadora ciêntifica.


Já vou antecipando que a diferença é desprezível na maior parte dos casos de uso, mas não tomem minha palavra por verdade absoluta.

A verdade absoluta foi negar ao proprio benchmarks, por entender que decisões vão de um entendimento ciêntifico de sua intuição.

T

A lógica diz apenas :

Se vou executar 1 passo em vez de 2, vou gastar menos tempo.

A experimentação diz:

Executar apenas 1 passo, em vez de 2, economiza apenas 0,002% do tempo de processamento*, e não vale a pena.

Não dá para determinar essa porcentagem só por lógica. E pela minha experiência não dá para determinar essa porcentagem nem sabendo exatamente quais são as instruções adicionais que o computador irá executar, porque o tempo de processamento das instruções de máquina é complexo demais para ser calculado com precisão nas máquinas modernas. Antigamente, você poderia saber que uma instrução ADD gastava 4 ciclos de máquina em um microprocessador 8086 e como ele rodava a 4,77 Mhz você saberia que o ADD gastava 4 * (1 / 4770000) segundos = 0,839 microssegundos. Mas hoje em dia isso não pode ser determinado tão simplesmente assim.

  • Estou dizendo 0,002, mas obviamente esse tempo tem de ser determinado - é para isso que serve a experiência. Método científico, não é “tentativa e erro”, hein?
J

Qualquer experimentaçao só existe pq alguem usou alguma logica…
A tipica frase: Penso, logo, existo… Uma aula de filosofia eheheh

Enfim, se imaginarmos que num projeto de milhares de classes poderemos evitar uma instanciaçao e poucar memoria e GC ter que ser acionado, pq isso nao seria bem vindo as vezes! Imagina a economia que teriamos :slight_smile:

A unica dúvida que fico: O Refactoring utiliza o mesmo processo de carga que um static ?

saudaçoes :stuck_out_tongue:

T

Você está confundindo “refactoring” com “reflection”.

A rigor, o processo de reflection (onde é que a tal “reflection” entrou na história?) é naturalmente um pouco lento (já que envolve obter métodos e classes por nome, em vez de usar suas referências já “prefabricadas”), mas foi devidamente acelerado pela JVM para se tornar útil, a partir do Java 1.4.

Leia um pouco sobre como a reflection foi acelerada pela JVM a partir do Java 1.4 - o processo é um bocado complexo, e envolve a criação de classes anônimas e temporárias pela JVM. Depois do almoço eu digo como é que a reflection é implementada.

J

Ola thingol,

Opa, me confundi, e Reflaction que quiz dizer mesmo!!

O Reflaction utiliza o mesmo processo de carga que um static?
Pois os dois sao cargas de classes feitas pela VM na memória…

abraços
:roll:

M

thingol:
Você está confundindo “refactoring” com “reflection”. (…)…
classes anônimas e temporárias pela JVM. Depois do almoço eu digo como é que a reflection é implementada.

Acho que depois do almoço o Thingol vai explicar melhor reflection sobre static… vamos esperar… [size=18]; )[/size]

M

Utilizar ‘static’ em todo o seu programa muito provavelmente não melhorará sua performance - é provável que, devido à falta de orientação a objetos em uma linguagem orientada a objetos, seus algoritmos fiquem cada vez mais complexos, difíceis de entender e conseqüentemente mais lentos. Uma arquitetura bem feita leva em consideração a passagem de mensagens entre um método e outro - possivelmente reduzindo o trabalho do GC, um dos pontos citados por você.

A melhor maneira de obter uma melhor performance é otimizar os algoritmos e estruturas de dados do programa em seus pontos críticos, o que se sabe através de um processo de ‘profiling’. Se você quer se aprofundar (muito) mais, pega um decompiler e analisa o bytecode pra ver como as instruções são traduzidas e executadas - isso pode lhe mostrar muita coisa sobre sua maneira de programar. Não adianta nada você fazer um programa baseado em métodos estáticos se você fica dando loops e enchendo buffers toda hora… além do que se você precisa de ‘performance ao limite’, Java não é a linguagem que você quer: apele ao clássico C ou ao Assembly mesmo…

L

Uma coisa tem que ficar clara: você não vai conseguir economizar memória usando static. Numa situação hipotética onde toda a sua estrutura de dados está armazenada de maneira estática (dica: você não vai conseguir), todos os recursos estarão alocados, mesmo que você não esteja utilizando boa parte deles no momento.

Linguagens orientadas a objeto te incentiva a criar e destruir objetos dinamicamente, fazendo com que, num determinado momento, você só tenha os objetos (e por consequencia, memória) que precisa.

M

MarceloS:

A melhor maneira de obter uma melhor performance é otimizar os algoritmos e estruturas de dados do programa em seus pontos críticos, o que se sabe através de um processo de ‘profiling’. Se você quer se aprofundar (muito) mais, pega um decompiler e analisa o bytecode pra ver como as instruções são traduzidas e executadas - isso pode lhe mostrar muita coisa sobre sua maneira de programar. Não adianta nada você fazer um programa baseado em métodos estáticos se você fica dando loops e enchendo buffers toda hora… além do que se você precisa de ‘performance ao limite’, Java não é a linguagem que você quer: apele ao clássico C ou ao Assembly mesmo…

Você esta colocando isso sobre CVS não entendi ? Quanto a otimizar os algoritmos e estruturas de dados, você diz ao ponto críticos a atráves de profiling ou atráves de instrumentação pela VM… algo como JSON no JBoss pode dar melhor exemplo…

M

?

K

Marcio Duran:
thingol:
Você está confundindo “refactoring” com “reflection”. (…)…
classes anônimas e temporárias pela JVM. Depois do almoço eu digo como é que a reflection é implementada.

Acho que depois do almoço o Thingol vai explicar melhor reflection sobre static… vamos esperar… [size=18]; )[/size]

Quero ver isso também…

Inté.

M

Marcio Duran:

Você esta colocando isso sobre CVS não entendi ? Quanto a otimizar os algoritmos e estruturas de dados, você diz ao ponto críticos a atráves de profiling ou atráves de instrumentação pela VM… algo como JSON no JBoss pode dar melhor exemplo…

CVS? O que que controle de versão tem a ver?

E sobre as estruturas de dados estava me referindo a utilizar as estruturas adequadas ao caso: já vi muita gente que ainda usa Vector, ou usa uma List e procura dentro de um for pra achar o elemento quando podia usar um Map… só de exemplos mais básicos.

S

Os métodos de instância também são compartilhados por todas as instâncias. Não tem sentido a VM manter cópias idênticas dos métodos.

V
joaosiqueira:
Mas nesse momento nao teriamos que concordar com o ccaneta?
ccaneta:
Acho que uma instancia "new" pode gastar mais memoria do que fazer uma chamada static direto.

Mas nao tenho certeza disso, vcs que me corrijam se estiver enganado.


Aqui são dois problemas diferentes. Instanciar vários objetos na memória a toa, com certeza é ruim. Mas isso não significa que todas as chamadas devem ser estáticas. Afinal, não há desperdício de memória em criar objetos apenas quando é necessário e invocar os métodos não-estáticos deles.

Quando diz que o fato de usar uma classe carregada usaria menos memoria e evitaria o tempo de instanciar uma classe, ao contrario do new em que temos que carregar e depois instanciar?
Ou você não entendeu a minha resposta ou eu não entendi a sua dúvida. Cada classe é carregada uma única vez na memória durante a execução. A JVM não carrega nunca a mesma classe duas vezes. A classe é carregada porque acontece mais ou menos isso:
Programa: Ei JVM, quero chamar o método Foo da classe Bar. JVM: Bem, ainda não carreguei a classe Bar. Espera um pouquinho que eu vou montá-la aqui. [JVM carrega a classe Bar] JVM: Ok, terminei de carregar a classe, agora vou chamar o Foo. [JVM chama o método Foo] Programa: Legal. Agora chame o método Abc da classe Bar. JVM: Ok, como eu já carreguei a classe antes, é só chamar o método. [JVM chama o método Abc]
Um exemplo:
class A {
    public static final int X;
    static {
        System.out.println("Carregando A");
        X = 7;
    }
}

public class B {
    static {
        System.out.println("Carregando B");
    }

    public static void main(String[] args) {
        System.out.println("Executando o main");
        System.out.println("A.X = " + A.X);
        System.out.println("A.X = " + A.X);
        System.out.println("A.X = " + A.X);
    }
}
joaosiqueia:
1 processo e mais rapido que 2....
Não é bem assim. Aquilo que escrevi foi de um modo simples. A JVM tem alguns truques em baixo da manga para acelerar as coisas, de forma que ela possa eliminar a verificação de instância = null se ela perceber que não existe forma daquilo ser null. Além disso, em muitos casos o uso de static pode também deixar o código mais lento, porque objetos alcançáveis por meio de atributos estáticos não podem ser recolhidos pelo coletor de lixo e podem causar desperdício de memória e em casos extremos lentidão devido ao swap. Como atributos de instância não são acessíveis em métodos estáticos, você acabaria preso aos métodos estáticos.

Além disso, atributos estáticos são uma grande dor de cabeça em programas com mais de uma Thread (e se você precisa muito de desempenho, provavelmente terá mais de uma Thread rodando). Várias Threads acessando atributos estáticos concorrentemente sem a devida sincronização cria toda a (má) sorte de condições de corridas que resultam em erros obscuros, difíceis de reproduzir e de ocorrência aleatória e misteriosa, justamente aqueles que são os maiores pesadelos na hora do debug. Para que várias Threads possam acessar atributos estáticos concorrentemente sem estes problemas, você vai precisar de sincronização ou na melhor das hipóteses colocar os atributos como volatile, mas qualquer uma destas abordagens é mais custosa do que transformar o atributo em atributo de instância.

Mais além, a JVM é capaz de fazer otimizações melhores quando ela sabe que o objeto vai ficar restrito a um único local, coisa que não é a cara de atributos estáticos.

E repetindo, eu falei tudo isso sobre atributos estáticos porque há pouco sentido em se ter atributos de instância sem ter métodos de instância. Além disso, o acesso aos atributos de uma instância A de dentro de um método de instância de A tende a ser melhor otimizado do que o acesso a um atributo (de instância) de A dentro de um método estático ou de um método da instância B. Isso ocorre porque a JVM pode otimizar o acesso ao ponteiro this.
Ok, ela também pode otimizar o acesso aos atributos estáticos da mesma classe, mas isso ainda não resolve o problema.

eu mesmo:
Mas seja lá qual for este tempo, ele deve ser ínfimo e desprezível. Se você está tão desesperado por desempenho que isto pode lhe fazer diferença, então você nem devia estar programando em java, e sim em assembler (ou até no hardware).
J

Victorwss,

Sua explicaçao foi demais, tenho q admitir… gostei!

Em que momentos vc acha que deveria utililizar um metodo static? Pois atualmente utilizo em metodos de classe de serviços de negocio, classes utilitarias e algumas vezes em blocos static para inicializaçao de valores.

O processo de carga de uma classe em uma Reflection e o mesmo que um static? Pois sempre dizemos que uma Reflection e lento, e o melhor seria utilizar o new diretamente no código em tempo de compilçao e nao execuçao.

Obrigado pela força!
abraços
:slight_smile:

V

joaosiqueira:
Victorwss,

Sua explicaçao foi demais, tenho q admitir… gostei!

Em que momentos vc acha que deveria utililizar um metodo static? Pois atualmente utilizo em metodos de classe de serviços de negocio, classes utilitarias e algumas vezes em blocos static para inicializaçao de valores.

O processo de carga de uma classe em uma Reflection e o mesmo que um static? Pois sempre dizemos que uma Reflection e lento, e o melhor seria utilizar o new diretamente no código em tempo de compilçao e nao execuçao.

Obrigado pela força!
abraços
:slight_smile:

Não existe regra receita-de-bolo para saber se um método deveria ser estático ou não. Mas há algumas diretrizes.

Prefira os métodos de instância. O static é uma coisa que normalmente vai contra a OO, mas por vezes ele é necessário. Na dúvida prefira os métodos de instância. Só use o static quando você realmente tiver certeza que não precisa e nem nunca precisará da instância e nem do polimorfismo.

Reflection serve para manipular classes, métodos e atributos que você normalmente só vai saber quais são durante a execução. Se você pode saber quais são em tempo de compilação, então não há muito sentido em usar reflection.

M

joaosiqueira:

Em que momentos vc acha que deveria utililizar um metodo static[i][color=blue]? Pois atualmente utilizo em metodos de classe de serviços de negocio, classes utilitarias e algumas vezes em blocos static para inicializaçao de valores.[/color]
[/i]

:arrow: “Para qual paradigma você esta se referindo”, onde você trabalhar esses metodos de serviços para SOA engine ?

J

Ola Marcio Duran,

Os serviços em que me refiro fiz sao classes POJO.

Vc tb utiliza static em serviços SOA?

abraços

M

joaosiqueira:
Ola Marcio Duran,

Os serviços em que me refiro fiz sao classes POJO.

Vc tb utiliza static em serviços SOA?

abraços

“É hacker te peguei”

:arrow: POJO Service Engine

M

Alias… cade a explicação do Thingol sobre Reflection?

V

Bem, não sei muito sobre como o reflection é implementado, mas sei um pouco. E já que o thingol não compareceu, vou tentar explicar.

O objeto Class contém referências aos objetos Method, Constructor, Field e Annotation, não muito diferente de como você criaria alguma estrutura de dados comum. A classe Class tem alguns métodos que permitem você pesquisar ou iterar estas estruturas de dados. Até aqui, nada além de java normal manipulando estruturas de dados simples.

As classes Class, Method, Constructor e Field também têm algumas estruturas de dados referentes a Annotations, que são instanciadas pela JVM quando a classe é carregada. O reflection para ler estas Annotations pode ser facilmente implementado baseado apenas em java simples (isso fica a critério dos implementadores da JVM).

Estas estruturas de dados são montadas pela JVM quando ela cria o objeto Class (ou dependendo da JVM de forma lazy), inclusive a instanciação das Annotations existentes.

O reflection da classe Field se baseia em uma implementação native. Essa implementação está dentro da JVM, que vai no endereço do atributo e lê ou escreve algum valor naquele endereço.

O reflection da classe Method também se baseia em native. Dentro da JVM, já no lado native, há um ponteiro para função que é invocado e então o método executa. O ponteiro "this" aparece como um parâmetro para este método (tal como empilhado pelo invokevirtual e pelo invokeinterface).

O reflection da classe Constructor funciona de forma semelhante ao de Method.

O Class.newInstance() delega para a classe Constructor.

Resumindo, as estruturas de dados poderiam ser montadas assim:
public class Class {
    private final Method[] methods;
    private final Field[] fields;
    private final Constructor[] constructors;
    private final Class superClass;
    private final Class[] implementedInterfaces;
    private final Class[] innerClasses;
    private final Annotation[] annotations;

    // Uma porrada de métodos.
}

public class Constructor {
    private final Class[] parameterTypes;
    private final Annotation[] annotations;
    private final Annotation[][] parametersAnnotations;
    private final Class baseType;

    // Uma porrada de métodos, inclusive newInstance().
}

public class Method {
    private final Class[] parameterTypes;
    private final Annotation[] annotations;
    private final Annotation[][] parametersAnnotations;
    private final Class returnType;

    // Uma porrada de métodos, inclusive invoke().
}

public class Field {
    private final Annotation[] annotations;
    private final Class fieldType;

    // Uma porrada de métodos, inclusive set() e get().
}
T

Obrigado, Victor; a explicação foi melhor que o que eu conseguiria dizer (normalmente eu ponho uma explicação complicada demais e muito bitolada para a implementação Sun da JVM).

V

thingol:
Obrigado, Victor; a explicação foi melhor que o que eu conseguiria dizer (normalmente eu ponho uma explicação complicada demais e muito bitolada para a implementação Sun da JVM).

  1. :smiley:
M

Gostei.

Mas vou procurar para ver como a JVM faz mais internamente.

D

Mark_Ameba:
Gostei.

Mas vou procurar para ver como a JVM faz mais internamente.

Se encontrar, por favor escreva um livro sobre isso, porque o que menos tem é literatura específica do funcionamento da JVM.

M

Agora eu desesti de procurar. :stuck_out_tongue:

T

O que você pode procurar é o wiki do pessoal do OpenJDK; lá há alguma coisa.

http://wikis.sun.com/display/HotSpotInternals/PerformanceTechniques

M

Eu procurei no OpenJDK sobre Reflection e não tinha achado… mas valeu vou olhar o link.

J

Nossa esse post foi demais, o que gerou de debate e polemica…

Isso prova como algo simples pode se tornar complexo, devido a amplitude de recursos de uma boa linguagem de prograçao.

Abraços a todos!
:slight_smile:

M

joaosiqueira:
Nossa esse post foi demais, o que gerou de debate e polemica…

Isso prova como algo simples pode se tornar complexo, devido a amplitude de recursos de uma boa linguagem de prograçao.

Abraços a todos!
:slight_smile:


Para quem quiser melhor informações sobre Reflection
:arrow: [b]Tutorial Java Reflection[/b]

J

Valeu Marcio Duran,

Esse artigo de Reflections me ajudou bastante.

Obrigado!
:smiley:

M

Uma parte ali que eu nao conhecia era sobre as Proxys com Reflection… eu sabia sobre elas mas não sabia que fazia parte.

J

Marcio Duran,

So trazendo o mundo hacking no GUJ… eheheh

muito bom!!! :twisted:

T

Veja bem, é uma questão de lógica. Uma classe é uma estrutura em que existem metodos e variáveis.

Mas quando um metodo é definido não importa se ele é estático ou dinamico a estrutura dele será a mesma, ou seja, o trecho de código que o método estático ou dinâmico (no compilador) sao quase iguais (semanticamente falando) o que mudam são as posições de memória pois metodos estáticos nao podem referenciar variaveis de uma instância.

O mesmo não é verdade para uma váriavel estática, que está sim economiza espaço de memória.

Veja o código:

public class Pessoa{

	public int idadeLimite1 = 18;
	public static int idadeLimite2 = 18;

	public printIdade(){

		System.out.println(this.idadeLimite1);
		System.out.println(Pessoa.idadeLimite2); 
	}
}

Em:

System.out.println(this.idadeLimite1); // cada instância de pessoa terá uma posição para armazenar o valor

No entanto em:

System.out.println(Pessoa.idadeLimite2); // na memória  existirá uma posição para armazenar o valor dessa variável
Criado 12 de janeiro de 2009
Ultima resposta 20 de jan. de 2009
Respostas 89
Participantes 18