JavaRush /Blogue Java /Random-PT /Pausa para café #88. O poder dos metadados: como trabalha...

Pausa para café #88. O poder dos metadados: como trabalhar com código espaguete. Coleta de lixo em Java – como funciona e quais as suas vantagens

Publicado no grupo Random-PT

O poder dos metadados: como trabalhar com código espaguete

Fonte: Hackernoon Todos nós tentamos usar abordagens comuns e padrões conhecidos para criar um aplicativo com esforço mínimo e impacto máximo. Temos excelentes bibliotecas e estruturas poderosas que realizam operações de rotina para nós. Usamos tudo isso para focar apenas na lógica de negócios. No entanto, essa busca muitas vezes nos leva ao código espaguete, especialmente quando se trata de implementar uma função sem uma solução pronta para ela. Neste artigo, quero compartilhar com vocês uma ferramenta poderosa que, na minha experiência, nem todos os desenvolvedores apreciam. Esta ferramenta está presente na maioria das linguagens de programação e é frequentemente usada em muitos frameworks - anotações. Pausa para café #88.  O poder dos metadados: como trabalhar com código espaguete.  Coleta de lixo em Java – como funciona e quais as suas vantagens – 1

Voce gosta de espaguete?

Vejamos um exemplo que encontrei alguns anos atrás. Eu precisava analisar uma planilha do Excel para colocar os dados analisados ​​em um banco de dados. Eu também queria coletar alguns dados do banco de dados e criar uma planilha. Para implementação, usei a conhecida biblioteca Java - Apache POI. A API da biblioteca facilita seu trabalho porque permite criar manualmente uma planilha, linha, célula e outros elementos. Isso é muito bom, mas quando é necessário gerar diversas planilhas Excel, o código fica completamente ilegível e insuportável. Como resultado, como geralmente acontece, a primeira versão do aplicativo acaba sendo simplesmente terrível. A implementação consistiu em uma classe de dados que representava uma string com todos os campos necessários para análise. Havia também um analisador onde os campos do Excel eram analisados ​​célula por célula e colocados em uma instância de classe de dados recém-criada. No início, o programa funcionou muito bem e fez o que era exigido dele. Os problemas começaram quando chegou a hora de fazer algumas modificações; o código não foi lido. Mesmo eu, que escrevi este código, não consegui encontrar um local adequado para colocar novas linhas para implementar a nova função que precisava.

Resgate em anotações

Salvei o aplicativo deste código espaguete de anotação. Para me livrar do código não suportado, precisei mover a lógica para determinar qual coluna analisar, que tipo de dados uma célula continha e tudo o mais para um local diferente. Para fazer isso, criei uma anotação na qual especifiquei o nome da coluna para cada campo de classe. Na anotação, também adicionei uma variável que permite selecionar a cor e a fonte da célula. Assim, o código na classe de análise foi significativamente reduzido. Apenas um processador criou dinamicamente a planilha com base nos parâmetros retirados das anotações. Foi uma vitória. Então, para fazer qualquer alteração na aplicação, bastava criar uma classe com anotações. A solução lembrava a biblioteca Jackson, que analisa JSON usando anotações, e acho que não há necessidade de dizer o quão convenientes são Jackson ou bibliotecas semelhantes.
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnExcel {

    String name() default "";

    int position();

    ExcelColumnDataFormat cellTypePattern() default ExcelColumnDataFormat.NONE;

    IndexedColors cellColor() default IndexedColors.AUTOMATIC;

    ExcelTotalFormula total() default ExcelTotalFormula.NONE;

}
ColumnExcel columnExcel = field.getAnnotation(ColumnExcel.class);
À medida que o aplicativo evoluiu, ele recebeu uma nova anotação que poderia ser usada para criar uma célula em uma planilha com uma função dentro. Vários campos podem ser multiplicados, subtraídos e quaisquer funções comuns do Excel podem ser usadas. Também adicionei uma linha total para mostrar a soma por coluna. E fiz tudo isso modificando ligeiramente o analisador principal e simplesmente adicionando anotações às classes.
@ColumnExcel(
            name = "Views",
            position = 4,
            total = ExcelTotalFormula.SUM)
    private BigDecimal variableC;

    @ColumnExcelFormula(
            name = "Conversion",
            position = 5,
            cellTypePattern = CellDataTypeFormatPattern.PERCENTAGE
    )
    public String variableD(int rowNumber) {
        return new CellAddress(rowNumber, 4).formatAsString() + "*"
		+ new CellAddress(rowNumber, 2).formatAsString();
    }

    @ColumnExcelTotalFormula(position = 4, cellTypePattern = CellDataTypeFormatPattern.RUR)
    public static String getVariableCTotalFormula(int firstRowNum, int lastRowNum) {
        return "SUM( " + new CellAddress(firstRowNum, 4).formatAsString() + ":"
		+ new CellAddress(lastRowNum, 4).formatAsString() + ")";
    }

Coleta de lixo em Java – como funciona e quais as suas vantagens

Fonte: Dev.to Coleta de lixo significa destruir ou limpar objetos não utilizados na memória. Java lida com a desalocação de memória automaticamente porque, uma vez criado um objeto, ele usa alguma memória no heap. Pausa para café #88.  O poder dos metadados: como trabalhar com código espaguete.  Coleta de lixo em Java – como funciona e quais as suas vantagens – 2

Como funciona?

Antes do Java, a linguagem de programação mais popular era C ou C++. Se você fala esses idiomas, saiba que eles gerenciam sua própria memória manualmente. Por exemplo, C possui métodos como calloc() , malloc() e realloc() que permitirão usar memória buffer. Você deve determinar quanta memória precisa para seu programa e especificar o que é chamado por esta API. Você pode então obter um buffer de memória para criar um nó de lista vinculada ou qualquer outra coisa. Quando o seu programa termina, em algum momento, você também é responsável por limpar essa memória. Portanto, um aplicativo grande escrito em C continua alocando memória buffer e às vezes se esquece de liberá-la. Em última análise, isso causa vazamentos de memória e muitos problemas no aplicativo. Ao contrário de C e C++, a linguagem Java vem com gerenciamento automático de memória por meio de um thread chamado coletor de lixo. Seu principal objetivo é liberar memória heap destruindo objetos inacessíveis. O coletor de lixo sempre é executado em segundo plano.

O que são objetos inacessíveis em Java?

Quando um objeto tem a chance de iniciar a coleta de lixo? Se houver objetos inacessíveis - aqueles para os quais não há links ativos. Vejamos um exemplo:
public static void main(String[] args)
{
// StringBuffer object sb is not eligible for garbage collection
StringBuffer sb = new StringBuffer("Flower Brackets");
System.out.println(sb);
// StringBuffer object sb is eligible for garbage collection
sb = null;
}
No método principal criei um objeto StringBuffer e uma referência a ele. Neste ponto, o objeto StringBuffer não é elegível para coleta de lixo. Agora vou definir o objeto StringBuffer como "nulo". O objeto agora é elegível para coleta de lixo e se torna um objeto inacessível na memória heap. Ou seja, a coleta de lixo geralmente funciona nos casos em que os objetos ficam inacessíveis. Isso significa que os objetos geralmente são criados no contexto de um “bloco if” ou método. Assim, os objetos saem do escopo assim que a execução do método é concluída e podem ser descartados pelo coletor de lixo. Como as referências de objetos antigos para novos existem em número limitado, isso significa que os objetos que estão presentes no seu aplicativo há muito tempo geralmente não são objetos recém-criados. Aqui estão alguns termos com os quais devemos estar familiarizados; um deles é um objeto vivo. É um objeto em um aplicativo referenciado por outro objeto no mesmo aplicativo. Existe também um objeto “morto”. Um objeto morto é um objeto inacessível criado durante uma chamada de método e, quando a chamada de método é concluída, o objeto sai do contexto e apenas fica na pilha.

Quando um objeto é elegível para coleta de lixo?

Se um objeto não tiver nenhuma variável de referência, ele será elegível para coleta de lixo.

Como disponibilizar um objeto para coleta de lixo?

Abaixo estão várias maneiras:
  1. null reference variable
    Student obj = new Student();
    obj = null;

  2. re-assign reference variable
    Student obj1 = new Student();
    Student obj2 = new Student();
    obj1 = obj2;

  3. reate anonymous object
    new Student();

    Depois que um objeto é disponibilizado ao coletor de lixo, ele não é destruído imediatamente.

Quando a Java Virtual Machine executa o coletor de lixo, apenas o objeto é destruído. NOTA: O coletor de lixo coleta apenas objetos criados utilizando a palavra-chave “new”, para objetos sem a palavra-chave “new”, utilize o método finalize() . Existem vários métodos para executar o coletor de lixo na Java Virtual Machine:
  1. Método System.gc()

  2. método finalizar()

  3. Método Runtime.getRuntime().gc()

O método estático gc() está localizado na classe System . Este método pede à JVM para chamar o coletor de lixo. Vamos ver como um aplicativo Java chama o coletor de lixo usando o método gc() .
public class GarbageCollector
{
public static void main(String[] args)
{
Employee obj1 = new Employee();
Employee obj2 = new Employee();
obj1 = null;
obj2 = null;
System.gc();
}
public void finalize()
{
System.out.println("object garbage collected");
}
}
Resultado:
objeto coletado lixo objeto coletado lixo
O método finalize() é chamado pouco antes de o objeto ser limpo. Este método é definido na classe Object :
protected void finalize() throws Throwable
  1. O método Finalize é usado para fechar a conexão com o banco de dados.

  2. Este método é chamado pelo coletor de lixo, não pela JVM.

  3. Precisamos substituir o método finalize() . Porque tem uma implementação vazia.

  4. É chamado apenas uma vez por objeto.

O método getRuntime().gc() está presente na classe de tempo de execução. Ele retorna o objeto Runtime associado ao aplicativo Java atual. Vejamos esse método em um programa Java.
public class Demo
{
public static void main(String[] args)
{
Demo obj1 = new Demo();
Demo obj2 = new Demo();
// nullifying reference variable
obj1 = null;
// nullifying reference variable
obj2 = null;
// running Garbage Collector
Runtime.getRuntime().gc();
}
@Override
protected void finalize() throws Throwable
{
System.out.println("Garbage collector called");
System.out.println("Object garbage collector: " + this);
}
}
Resultado:
Coletor de lixo chamado Coletor de lixo Object: Demo@2130772 Coletor de lixo chamado Coletor de lixo Object: Demo@cd4e940

Benefícios da coleta de lixo:

  1. A coleta de lixo em Java ocorre automaticamente, o que nos poupa do fardo adicional de liberar memória usada. Isso torna a memória do programa Java mais eficiente.
  2. A coleta de lixo garante a integridade do programa.
  3. Não precisamos escrever nenhum código adicional, pois o coletor de lixo faz parte da JVM.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION