Novidades do Java 12

java 12

Onde Baixar o novo JDK 12?

Você pode baixar o novo JDK diretamente no site Java.net através do link: https://jdk.java.net/12

Também é possível baixar a versão do código fonte fornecidas sob a Licença Pública Geral GNU v2 como o OpenJDK (https://openjdk.java.net/projects/jdk/12/) ou mesmo versões comerciais da Oracle ou de outros fabricantes.

Quais os Novos Recursos?

Retorno imediato de memória confirmada não usada

O Java 12 aprimora o G1 para retornar automaticamente a memória heap Java ao sistema operacional quando estiver ocioso. Essa memória é liberada em um período de tempo razoável quando há atividade de aplicativo muito baixa.

Anteriormente, o G1 retornava apenas a memória do heap em um processo de garbage collector completo ou durante um ciclo concorrente. Com o G1 tentando evitar as coletas completas, apenas acionando um ciclo concorrente baseado na ocupação de heap e na atividade de alocação, ele não retornaria a memória heap em muitos casos, a menos que fosse forçado a fazê-lo externamente. Esse comportamento era desvantajoso em ambientes de contêiner onde os recursos são pagos pelo uso. Mesmo quando a JVM usa apenas uma fração de sua memória atribuída devido a inatividade, o G1 retinha o heap completo. Assim, os clientes pagavam por todos os recursos o tempo todo, e os provedores de nuvem não podiam fazer uso total de seu hardware.

Com o Java 12, a JVM pode detectar fases de subutilização de heap e reduzir automaticamente seu uso de heap durante esse tempo.

G1 Mixed Collections abortáveis

Seo o G1 descobre que a heurística de seleção do conjunto de coleta seleciona repetidamente o número errado de regiões, então ocorre a alternância para uma forma incremental de mixed collections, ou seja, o conjunto é dividido na coleta em duas partes: uma obrigatória e uma opcional. A parte obrigatória compreende partes do conjunto de coleta que o G1 não pode processar de forma incrementarl (Ex: novas regiões), mas também pode conter regiões antigas para gerar maior eficiência. Com isso pode-se, por exemplo, ter até 80% do conjunto de coleta previsto e os aproximados 20% restantes, que consiste apenas de regiões antigas, uma forma opcional.

Após o G1 terminar de coletar a parte obrigatória, ele começa a coletar a parte opcional em um nível muito mais granular, se houver tempo sobrando. A granularidade da coleta dessa parte opcional depende da quantidade de tempo restante, no máximo, até uma região por vez. Depois de concluir a coleta de qualquer parte do conjunto de coleta opcional, o G1 pode decidir interromper a coleta, dependendo do tempo restante.

À medida que as previsões se tornam mais precisas novamente, a parte opcional de uma coleção torna-se cada vez menor, até que a parte obrigatória mais uma vez compreenda todo o conjunto de coleta (ou seja, G1 depende completamente de sua heurística). Se as previsões se tornarem imprecisas novamente, as próximas coleções consistirão em uma parte obrigatória e opcional novamente.

API de constantes da JVM

Essa APIs modelam descrições nominais de artefatos de arquivo e de tempo de execução de classe-chave, particularmente algumas constantes carregáveis ​​do conjunto de constante. O Java 12 define uma família de tipos de referência simbólica baseada em valor em um novo pacote Java chamado “java.lang.invoke.constant”.

Conjuntos constantes existem em todas as classes Java, armazenando e operando instruções de bytecode na classe. As entradas no conjunto constante descrevem artefatos de tempo de execução, como classes e métodos, ou valores simples, como cadeias de caracteres e inteiros. Essas entradas são conhecidas como constantes carregáveis.

Programas que manipulam arquivos de classe devem modelar instruções de bytecode e, por sua vez, constantes carregáveis. Mas o uso de tipos Java padrão para modelar constantes carregáveis ​​é inadequado. Isso pode ser aceitável para uma constante carregável que descreve uma string, mas é problemático para uma constante carregável que descreve uma classe, porque produzir um objeto de classe “ativo” que depende da exatidão e consistência do carregamento da classe. O carregamento de classes, no entanto, tem muitas dependências ambientais e modos de falha.

Assim, programas que lidam com constantes carregáveis ​​poderiam ser simplificados se pudessem manipular classes e métodos e artefatos menos conhecidos, como manipuladores de métodos e constantes computadas dinamicamente em uma forma simbólica e nominal. Assim, a API de constantes da JVM fornece às bibliotecas e ferramentas uma maneira única e padrão de descrever constantes carregáveis.

Número reduzido de portas ARM

O Java 12 remove todas as origens relacionadas ao “arm64”, mantendo o ARM de 32 bits e o “aarch64” de 64 bits. A remoção dessa porta permitirá que colaboradores foquem esforços em uma única implementação de ARM de 64 bits e eliminem o trabalho duplicado resultante da manutenção de duas portas. Versões anteriores de JDK mantem duas portas ARM de 64 bits.

Aprimoramentos na Inicialização, CDS e Garbage Collector

O Java 12 aprimora o processo de construção do JDK para gerar um padrão para o class data-sharing (CDS), usando a lista de classes padrão, em plataformas de 64 bits. Isso melhora o tempo de inicialização pronto para uso e elimina a necessidade de executar o parâmetro “-Xshare:dump” para se beneficiar do CDS. O processo de compilação do JDK foi modificado para executar “java-xshare:dump” após vincular a imagem.

Opções de linha de comando adicionais foram incluídas para ajustar os tempos de heap da garbage collector para melhorar o layout da memória nos casos comuns. Usuários com requisitos mais avançados, como listas de classes personalizadas que incluem classes de aplicativos e diferentes configurações de garbage collector, ainda podem criar um arquivo CDS personalizado.

Shenandoah garbage collector

O Java 12 adicionou a arquitetura Shenandoah, um algoritmo experimental de garbage collector, que reduz o tempo de pausa durante o processo de liberação (limpeza), realizando trabalhos de expurgo simultaneamente com a execução de encadeamentos Java. Shenandoah é um algoritmo apropriado para aplicativos que necessitam de grande capacidade de resposta e pausas muito curtas e calculadas. Obviamente não se deve esperar que todos os problemas a este respeito estejam solucionados, pois este é um procedimento complexo e que demanda CPU, mas a inclusão desta tecnologia ajuda bastante a quem sofre com este problema. Até a data de postagem as arquiteturas suportadas eram: Aarch64 e AMD64.

Suíte básica de benchmark

O JDK 12 inclui um conjunto básico de “micro-benchmarks”, que foram adicionados ao código-fonte da plataforma. O objetivo é facilitar aos desenvolvedores executar benchmarks existentes ou criar novos.

A proposta do pacote microbenchmarks, criada em julho de 2014 e atualizada no início de novembro de 2018, foi apoiada pelo Java Microbenchmark Harness (JMH), para a criação de benchmarks escritos em Java e outras linguagens da JVM. A suíte é colocada com código-fonte JDK em um único diretório, para que os desenvolvedores sejam capazes de adicionar novos benchmarks.

Não era uma meta fornecer benchmarks para novos recursos do JDK ou criar um conjunto completo de benchmarks cobrindo tudo no JDK. Observa-se também que o conjunto de benchmarking não é necessário para compilações regulares do JDK, mas é um destino de compilação separado.

Nova expressão Switch

No Java 12, um novo aprimoramento foi feito para o switch, adicionando novos recursos, o que simplifica a codificação ao estender a antiga instrução switch para ser usada como uma instrução regular de switch aprimorada ou como uma “expressão switch”.

Isso possibilita formas de comportamento do escopo e controle de fluxo tanto “tradicionais” quanto “simplificados”. Estas alterações simplificam a codificação diária e preparam o caminho para o uso da correspondência de padrões usando a instrução/expressão switch no futuro.

À medida que os construtores Java se movem para suportar a correspondência de padrões, as irregularidades da instrução do “switch” Java tornaram-se impedimentos. Estes incluem o comportamento de fluxo de controle padrão dos blocos de switch; escopo padrão dos blocos de switchs, em que o bloco é tratado como um único escopo; e mude o funcionamento apenas como uma declaração. O design atual da instrução switch do Java segue de perto as linguagens como C++ e, por padrão, suporta a semântica de avanço. Esse fluxo de controle foi útil para escrever código de baixo nível. Mas quando o switch é usado em contextos de nível superior, sua natureza propensa a erros começa a superar a flexibilidade.

Vejam exemplos abaixo:

public void teste(int i) {
    switch (i) {
        case 1 -> System.out.println("1");
        case 2 -> System.out.println("2");
        case 3 -> System.out.println("3");
    }
}

e

static boolean ehDiaUtil(String dia) {
    return switch (dia) {
        case "mon", "tue", "wed", "thu", "fri" -> false;
        case "sat", "sun" -> true;
        default -> {
            if (dia.startsWith("s")) {
                System.out.println("parece final de semana");
                break true;
            }

            System.out.printf("dia não identificado: %s\n", dia);
            break false;
        }
    };
}

Conclusão

A maioria dos principais aprimoramentos no Java 12 estão mais ou menos na área da JVM. Além disso, o Java 12 tem uma atualização interessante na linguagem Java, embora não estejam ativadas por padrão. Esperamos que para a versão 13 sejam melhoradas e definitivamente finalizadas.