JavaRush /Java Blog /Random-IT /Dalle 8 alle 13: una panoramica completa delle versioni J...

Dalle 8 alle 13: una panoramica completa delle versioni Java. Parte 2

Pubblicato nel gruppo Random-IT
Questo articolo è la seconda parte della mia recensione delle innovazioni nelle versioni Java 8-13. La prima parte è qui . Senza ulteriori indugi, passiamo al 25 settembre 2018, quando è stato rilasciato il nuovo JDK:

Giava11

Dalle 8 alle 13: una panoramica completa delle versioni Java.  Parte 2 - 1

var (in lambda)

D'ora in poi, possiamo specificare i tipi di parametri lambda o ometterli durante la scrittura di un'espressione lambda (espressioni lambda tipizzate implicitamente):
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Puoi anche aggiungere annotazioni ai parametri lambda senza dover scrivere il nome completo del tipo di variabile:
Function<String, String> append = (@NonNull var string) -> string + " Text";

Z(ZGC)

ZGC è un nuovo garbage collector che non funziona. Alloca nuova memoria ma non la riavvia mai. ZGC promette di gestire grandi quantità di memoria con throughput elevato e bassa latenza (ZGC è disponibile solo su piattaforme a 64 bit). Colorazione di riferimento - ZGC utilizza puntatori a 64 bit con una tecnica chiamata colorazione del puntatore. I puntatori colorati memorizzano informazioni aggiuntive sugli oggetti nell'heap. Quando la memoria diventa frammentata, ciò aiuta a evitare il degrado delle prestazioni quando il GC deve trovare spazio per una nuova allocazione. La raccolta dei rifiuti utilizzando ZGC prevede i seguenti passaggi:
  1. il mondo si ferma: cerchiamo punti di partenza per raggiungere gli oggetti sull'heap (come variabili locali o campi statici);
  2. intersezione dei grafici degli oggetti a partire dai collegamenti radice. Contrassegniamo ogni oggetto che raggiungiamo (ZGC percorre il grafico dell'oggetto ed esamina i marcatori colorati, contrassegnando gli oggetti disponibili);
  3. gestire alcuni casi limite, come i collegamenti deboli;
  4. spostare oggetti viventi, liberando ampie aree dell'heap per accelerare l'allocazione.
  5. quando inizia la fase di spostamento, ZGC divide l'heap in pagine e lavora una pagina alla volta;
  6. Lo ZGC termina il movimento di eventuali radici e avviene il resto del movimento.
Questo argomento è molto complesso e confuso. Una discussione dettagliata richiederebbe un articolo separato, quindi lo lascerò qui:

EpsilonGC

Epsilon è un garbage collector che gestisce l'allocazione della memoria ma non implementa alcun vero meccanismo di recupero della memoria. Una volta esaurito l'heap Java disponibile, la JVM verrà arrestata. Cioè, se inizi a creare un oggetto in un array infinito senza legarlo a un riferimento con questo garbage collector, l'applicazione si bloccherà con un OutOfMemoryError (e se con qualsiasi altro, non lo farà, poiché ripulirà gli oggetti senza riferimenti) . Perché è necessario? Ecco perché:
  1. Test delle prestazioni.
  2. Test di pressione della memoria.
  3. Testare l'interfaccia della VM.
  4. Lavoro estremamente breve.
  5. Miglioramenti della latenza dell'ultima goccia.
  6. Miglioramenti del throughput dell'ultima goccia.
Link utili: Altre innovazioni:
  1. ByteArrayOutputStreamho ottenuto un metodo void writeBytes(byte [])che scrive tutti i byte dall'argomento a OutputStream.
  2. FileReadere FileWriterho ottenuto nuovi costruttori che ti consentono di specificare Charset.
  3. Pathho preso due nuovi metodi, of(String, String [])restituisce Pathda un argomento stringa un percorso o una sequenza di stringhe che, se combinate, formano una stringa di percorso e of(URI): restituisce Percorso da un URI.
  4. Pattern— ha ricevuto un metodo asMatchPredicate()che controlla se una determinata stringa di input corrisponde a un determinato modello (se consente di creare un predicato utilizzando un'espressione regolare in modo da poter, ad esempio, filtrare i dati nel flusso).
  5. StringHo raccolto molti metodi utili, come ad esempio:
    • String strip(): ci restituirà una stringa che è questa stringa, con tutti gli spazi all'inizio e alla fine della stringa rimossi (simile a trim(), ma definisce gli spazi in modo diverso);
    • String stripLeading(): ci restituirà la stringa che è questa stringa, rimuovendo eventuali spazi iniziali dalla stringa;
    • String stripTrailing(): ci restituirà la stringa che è questa stringa, rimuovendo eventuali spazi alla fine della stringa;
    • Stream lines(): ci restituirà Streamfrom String, estratto da questa stringa, separato da separatori di riga;
    • String repeat(int): ci restituirà una stringa che è una concatenazione di questa stringa, ripetuta un numero di volte.
    • boolean isBlank(): restituirà vero se la stringa è vuota o contiene solo spazi, falso altrimenti.
  6. Thread— i metodi destroy() e stop(Throwable) sono stati rimossi.
  7. Filesho ottenuto una serie di nuovi metodi:
    • String readString(Path): legge tutti i dati da un file in una stringa, mentre decodifica da byte a caratteri utilizzando la codifica UTF-8;
    • String readString(Path, Charset): come nel metodo sopra, con la differenza che la decodifica da byte a caratteri avviene utilizzando il Charset specificato;
    • Path writeString (Path, CharSequence, OpenOption []): Scrive una sequenza di caratteri in un file. I caratteri vengono codificati in byte utilizzando la codifica UTF-8;
    • Path writeString(Path, CharSequence,Charset, OpenOption []): Stesso metodo di cui sopra, solo i caratteri vengono codificati in byte utilizzando la codifica specificata in Charset.
Queste sono state le innovazioni API più interessanti (a mio modesto parere), ecco un paio di materiali per una recensione più dettagliata:

Giava 12

Passano sei mesi e vediamo la fase successiva nell'evoluzione di Java. Quindi è il momento di tirare fuori una pala di conoscenza e scavare. Dalle 8 alle 13: una panoramica completa delle versioni Java.  Parte 2 - 2

Aggiorna G1

Sono stati apportati i seguenti miglioramenti per G1:
  1. Recuperare la memoria allocata non utilizzata

    Nella memoria heap Java esiste la memoria inutilizzata (o in altre parole, inattiva). In Java 12 hanno deciso di risolvere questo problema, ora:

    • G1 restituisce la memoria dall'heap in un GC completo o durante un ciclo parallelo; G1 tenta di impedire un GC completo e avvia un ciclo parallelo in base all'allocazione dell'heap. Dovremo forzare G1 a restituire la memoria dall'heap.

    Questo miglioramento si concentra sulle prestazioni restituendo automaticamente la memoria dall'heap al sistema operativo quando G1 non è in uso.

  2. Interruzione delle raccolte miste quando viene superato il tempo di pausa

    G1 utilizza un motore di analisi per selezionare la quantità di lavoro richiesta per la raccolta dei rifiuti. Raccoglie oggetti attivi senza fermarsi dopo aver definito il set e avviato la pulizia. Ciò fa sì che il Garbage Collector superi il tempo di pausa previsto. In realtà, questo problema viene risolto dal miglioramento, poiché se il tempo richiesto per completare il passo successivo è oltre i limiti ragionevoli, questo passo può essere interrotto.

Microbenchmark

Java 12 ha introdotto test di microbenchmarking in modo che le prestazioni della JVM possano essere facilmente testate utilizzando i benchmark esistenti. Questo sarebbe molto utile per chiunque voglia lavorare sulla JVM stessa. I test aggiunti vengono creati utilizzando Java Microbenchmark Harness (JMH). Questi test consentono test continui delle prestazioni sulla JVM. JEP 230 propone l'introduzione di circa 100 test, con nuovi test introdotti man mano che vengono rilasciate nuove versioni di Java. Ecco un esempio dei test aggiunti .

Shenandoah

Si tratta di un algoritmo di Garbage Collection (GC) che mira a garantire tempi di risposta bassi (il limite inferiore è 10-500 ms). Ciò riduce il tempo di pausa del GC quando si esegue il lavoro di pulizia contemporaneamente all'esecuzione dei thread Java. In Shenandoah, il tempo di pausa è indipendente dalla dimensione dell'heap. Ciò significa che il tempo di pausa sarà lo stesso indipendentemente dalla dimensione del tuo heap. Questa è una funzionalità sperimentale e non è inclusa nella build standard (Oracle) di OpenJDK.

Migliora il passaggio

Java 12 ha migliorato le espressioni Switch per la corrispondenza dei modelli. È stata introdotta una nuova sintassi L →. Ecco un elenco dei punti chiave del nuovo switch :
  1. La nuova sintassi elimina la necessità di un'istruzione break per prevenire errori.
  2. Il cambio delle espressioni non fallisce più.
  3. Inoltre, possiamo definire più costanti in una singola etichetta.
  4. il caso predefinito è ora richiesto nelle espressioni switch.
  5. break viene utilizzato nelle espressioni Switch per restituire valori dal registro stesso (in effetti, uno switch può restituire valori).
Consideriamo questo come esempio:
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
            break "Please insert a valid day.";
      else
            break "Looks like a Sunday.";
  }
};
Guida definitiva per cambiare espressione in Java 13 Altre nuove funzionalità:
  1. String:

    transform(Function f)- Applica la funzione fornita a una stringa. Il risultato potrebbe non essere una stringa.
    indent(int x)— aggiunge x spazi alla stringa. Se il parametro è negativo, questo numero di spazi iniziali verrà rimosso (se possibile).

  2. Files- ho preso un metodo come mismatch(), che, a sua volta, trova e restituisce la posizione del primo byte non corrispondente nel contenuto di due file, o -1L se non c'è corrispondenza.

  3. È apparsa una nuova classe:CompactNumberFormat per formattare un numero decimale in una forma compatta. Un esempio di questa forma compatta è 1M anziché 1.000.000, pertanto sono necessari solo due caratteri invece di nove.

  4. Ce n'è anche uno nuovo enum , NumberFormatStyleche ha due valori: LONG e SHORT.

  5. InputStream ho ottenuto il metodo skipNBytes(long n) : salta l'ennesimo numero di byte dal flusso di input.

Link interessanti a Java 12:

Giava 13

Il mondo non sta fermo, si muove, si sviluppa, proprio come Java - Java 13. Dalle 8 alle 13: una panoramica completa delle versioni Java.  Parte 2 - 3

Blocco di testo

Java ha sempre sofferto un po' quando si tratta di definire le stringhe. Se dovevamo definire una riga con uno spazio, un'interruzione di riga, una virgoletta o altro, ciò causava alcune difficoltà, quindi dovevamo utilizzare caratteri speciali: ad esempio \n per un'interruzione di riga, o un escape di parte della riga si. Ciò riduce significativamente la leggibilità del codice e richiede più tempo durante la scrittura di tale riga. Ciò diventa particolarmente evidente quando si scrivono stringhe che visualizzano JSON, XML, HTML, ecc. Di conseguenza, se vogliamo scrivere un piccolo Json, sarà simile a questo:
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
E poi Java 13 entra in scena e ci offre la sua soluzione sotto forma di triple virgolette doppie prima e dopo il testo (che chiamavano blocchi di testo). Diamo un'occhiata all'esempio json precedente utilizzando questa innovazione:
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
Molto più semplice e chiaro, no? Sono stati inoltre aggiunti rispettivamente Stringtre nuovi metodi per la gestione di questi blocchi:
  • stripIndent(): rimuove gli spazi casuali da una stringa. Ciò è utile se stai leggendo stringhe su più righe e desideri applicare lo stesso tipo di esclusione di spazi bianchi casuali che si verifica con una dichiarazione esplicita (essenzialmente simulando il compilatore per rimuovere gli spazi bianchi casuali);
  • formatted(Object... args ): simile a format(String format, Object... arg), ma per blocchi di testo;
  • translateEscapes(): Restituisce una stringa con sequenze di escape (come \r) tradotte nel valore Unicode corrispondente.

Migliora il passaggio

Le espressioni switch sono state introdotte in Java 12 e 13 le perfeziona. In 12 definisci i valori di ritorno usando break. In 13, il valore restituito è stato sostituito con il rendimento. Ora l'espressione switch che avevamo nella sezione Java 12 può essere riscritta come:
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
          yield "Please insert a valid day.";
      else
          yield "Looks like a Sunday.";
  }
};
Anche se per noi programmatori che già conoscevamo Java era normale accettare la pausa, era comunque piuttosto strano. Cosa sta cercando di dirmi la verità? La nuova parola chiave yield (relativamente nuova) è più chiara e potrebbe apparire in futuro in altri luoghi in cui vengono restituiti i valori. Per coloro che sono profondamente interessati a questo argomento, consiglio di familiarizzare con questi materiali:

Archivi CDS dinamici

CDS - Condivisione dei dati di classe. Consente di creare un pacchetto di una serie di classi comunemente utilizzate in un archivio che può essere successivamente caricato da più istanze JVM. perché ne abbiamo bisogno? Il fatto è che nel processo di caricamento delle classi, la JVM esegue molte azioni ad alta intensità di risorse, come leggere le classi, memorizzarle in strutture interne, verificare la correttezza delle classi lette, cercare e caricare classi dipendenti, ecc. ., e solo dopo tutto questo le classi sono pronte a lavorare. Comprensibilmente, molte risorse vengono sprecate, poiché le istanze JVM possono spesso caricare le stesse classi. Ad esempio String, LinckedList, Integer. Bene, o classi della stessa applicazione, e tutte queste sono risorse. Se eseguissimo tutti i passaggi necessari una sola volta e poi posizionassimo le classi riprogettate in un archivio che potrebbe essere caricato nella memoria di più JVM, ciò potrebbe risparmiare in modo significativo spazio di memoria e ridurre i tempi di avvio dell'applicazione. In realtà, CDS rende possibile creare proprio un archivio di questo tipo. Java 9 consentiva solo l'aggiunta di classi di sistema all'archivio. Java 10: include le classi dell'applicazione nell'archivio. La creazione di tale archivio consiste in:
  • creazione di un elenco di classi caricate dall'applicazione;
  • creando un archivio tanto necessario con le classi che abbiamo trovato.
L'innovazione in Java 13 migliora CDS in modo che possa creare un archivio quando l'applicazione termina. Ciò significa che i due passaggi precedenti verranno ora combinati in uno solo. E un altro punto importante: solo le classi caricate durante l'esecuzione dell'applicazione verranno aggiunte all'archivio. In altre parole, quelle classi che sono ancora contenute in application.jar, ma per qualche motivo non sono state caricate, non verranno aggiunte all'archivio.

Aggiorna l'API del socket

L'API Socket ( java.net.Socket e java.net.ServerSocket ) è essenzialmente parte integrante di Java sin dal suo inizio, ma i socket non sono mai stati aggiornati negli ultimi vent'anni. Scritti in C e Java, erano molto, molto ingombranti e difficili da mantenere. Ma Java 13 ha deciso di apportare le proprie modifiche all'intera questione e ha sostituito l'implementazione di base. Ora, invece di PlainSocketImpl, l'interfaccia del provider è sostituita con NioSocketImpl . Questa nuova implementazione codificata si basa sulla stessa infrastruttura back-end di java.nio . Essenzialmente la classe utilizza la cache del buffer java.util.concurrent e il meccanismo di blocco (basati sui segmenti) anziché i metodi sincronizzati. Non richiede più codice nativo, rendendo più semplice il porting su piattaforme diverse. Tuttavia, abbiamo un modo per tornare a utilizzare PlainSocketImpl , ma da ora in poi NioSocketImpl verrà utilizzato per impostazione predefinita .

Ritorno in memoria per ZGC

Come ricordiamo, il Garbage Collector Z è stato introdotto in Java 11 come meccanismo di Garbage Collection a bassa latenza in modo che la pausa GC non superi mai i 10 ms. Ma allo stesso tempo, a differenza di altri HotSpot GC virtuali, come Shenandoah e G1, potrebbe restituire la memoria dinamica inutilizzata al sistema operativo. Questa modifica aggiunge questa capacità J a ZGC. Di conseguenza, otteniamo un ingombro di memoria ridotto insieme a prestazioni migliorate e ZGC ora restituisce la memoria non impegnata al sistema operativo per impostazione predefinita fino al raggiungimento della dimensione heap minima specificata. Ancora una cosa: ZGC ora ha una dimensione heap massima supportata di 16 TB. In precedenza, il limite era di 4 TB. Altre innovazioni:
  1. javax.security- aggiunta una proprietà jdk.sasl.disabledMechanismsper disabilitare i meccanismi SASL.
  2. java.nio- è stato aggiunto un metodo FileSystems.newFileSystem (Path, Map <String,?>)- rispettivamente, per creare un nuovo file.
  3. Le classi java.nioora hanno metodi assoluti (al contrario di relativi) gete set-. Essi, come la classe astratta di base Buffer, includono un metodo slice()per recuperare parte del buffer.
  4. Aggiunti javax.xml.parsersmetodi per istanziare le fabbriche DOM e SAX (con supporto dello spazio dei nomi).
  5. Il supporto Unicode è stato aggiornato alla versione 12.1.
Link interessanti su Java 13:

Risultati

Potremmo ripercorrere le novità annunciate in Java 14, ma poiché vedrà la luce molto presto (il rilascio di JDK 14 è previsto per il 17 marzo 2020), sarebbe meglio effettuarne una revisione separata e completa subito dopo il suo rilascio . Vorrei anche attirare la vostra attenzione sul fatto che in altri linguaggi di programmazione con lunghe pause tra i rilasci, come Python 2–3, non c'è compatibilità: cioè, se il codice è scritto in Python 2, lo farai è necessario lavorare sodo per tradurlo in 3. Java è speciale a questo riguardo perché è estremamente compatibile con le versioni precedenti. Ciò significa che è garantito che il tuo programma Java 5 o 8 venga eseguito su una macchina virtuale Java 8-13, con alcune eccezioni di cui per ora non devi preoccuparti. È chiaro che questo non funziona al contrario: ad esempio, se la tua applicazione utilizza funzioni Java 13 che semplicemente non sono disponibili nella JVM Java 8. Per me oggi è tutto, rispetto per chi ha letto fino a questo punto)) Dalle 8 alle 13: una panoramica completa delle versioni Java.  Parte 2 - 5
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION