Modificador static nos metodos, codigo mais rapido?

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:

[quote=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.
[/quote]
Acho que depois do almoço o Thingol vai explicar melhor reflection sobre static… vamos esperar… [size=18]; )[/size]

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…

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.

[quote=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… [/quote]
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…

?

[quote=Marcio Duran][quote=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.
[/quote]
Acho que depois do almoço o Thingol vai explicar melhor reflection sobre static… vamos esperar… [size=18]; )[/size][/quote]
Quero ver isso também…

Inté.

[quote=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…[/quote]

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.

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.

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.

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:

Um exemplo:[code]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);
}

}[/code][quote=joaosiqueia]1 processo e mais rapido que 2…[/quote]
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.

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:

[quote=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:

[/quote]

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.

[quote=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][/quote][/i]

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

Ola Marcio Duran,

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

Vc tb utiliza static em serviços SOA?

abraços

[quote=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

[/quote]

“É hacker te peguei”

:arrow: POJO Service Engine

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

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:

[code]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().

}[/code]

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

[quote=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).
[/quote]

  1. :smiley:

Gostei.

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