JavaRush /Java Blog /Random-JA /8 から 13: Java バージョンの完全な概要。パート2
Константин
レベル 36

8 から 13: Java バージョンの完全な概要。パート2

Random-JA グループに公開済み
この記事は、Java バージョン 8 ~ 13 のイノベーションに関する私のレビューの第 2 部です。最初の部分はここにあります。早速、新しい JDK がリリースされた 2018 年 9 月 25 日に話を進めましょう。

Java 11

8 から 13: Java バージョンの完全な概要。 パート 2 - 1

var (ラムダ内)

今後は、ラムダ式 (暗黙的に型付けされたラムダ式) を作成するときに、ラムダ パラメーターの型を指定したり省略したりできるようになります。
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
完全な変数型名を記述しなくても、ラムダ パラメーターに注釈を追加することもできます。
Function<String, String> append = (@NonNull var string) -> string + " Text";

ゼット(ZGC)

ZGC は新しいガベージ コレクターですが、機能しません。新しいメモリは割り当てられますが、再起動はされません。ZGC は、高スループットと低遅延で大量のメモリを管理することを約束します (ZGC は 64 ビット プラットフォームでのみ利用可能です)。参照カラーリング - ZGC は、ポインター カラーリングと呼ばれる手法で 64 ビット ポインターを使用します。色付きのポインターは、ヒープ上のオブジェクトに関する追加情報を保存します。これにより、メモリが断片化すると、GC が新しい割り当てのためのスペースを見つける必要があるときにパフォーマンスの低下を回避できます。ZGC を使用したガベージ コレクションは、次の手順で構成されます。
  1. 世界が停止します: ヒープ上のオブジェクト (ローカル変数や静的フィールドなど) に到達するための開始点を探します。
  2. ルート リンクから始まるオブジェクト グラフの交差。到達した各オブジェクトにマークを付けます (ZGC はオブジェクト グラフ内を歩き、色付きのマーカーを調べ、利用可能なオブジェクトをマークします)。
  3. 弱いリンクなどのいくつかの特殊なケースを処理します。
  4. 生きているオブジェクトを移動し、ヒープの広い領域を解放して割り当てを高速化します。
  5. 移動フェーズが始まると、ZGC はヒープをページに分割し、一度に 1 ページずつ処理します。
  6. ZGC はルートの移動を終了し、残りの移動が行われます。
このトピックは非常に複雑でわかりにくいです。詳細な説明には別の記事が必要になるため、ここでは省略します。

イプシロン GC

Epsilon は、メモリ割り当てを処理するガベージ コレクタですが、実際のメモリ回復メカニズムは実装していません。使用可能な Java ヒープがなくなると、JVM がシャットダウンします。つまり、このガベージ コレクターを使用して参照にバインドせずに無限配列内のオブジェクトの作成を開始すると、アプリケーションはOutOfMemoryErrorでクラッシュします(他の場合は、参照のないオブジェクトをクリーンアップするため、クラッシュしません)。 )。なぜ必要なのでしょうか? その理由は次のとおりです。
  1. 性能試験。
  2. メモリプレッシャーテスト。
  3. VM インターフェイスをテストしています。
  4. 非常に短い作業。
  5. ラストドロップのレイテンシーが改善されました。
  6. ラストドロップのスループットが向上しました。
役立つリンク: その他の革新:
  1. ByteArrayOutputStreamvoid writeBytes(byte [])引数からのすべてのバイトを に書き込むメソッドを取得しましたOutputStream
  2. FileReaderFileWriterCharset を指定できる新しいコンストラクターを取得しました。
  3. Path2 つの新しいメソッドを取得し、文字列引数からパスまたは組み合わせてパス文字列を形成する文字列のシーケンスof(String, String [])を返し、 : URI からパスを返します。Pathof(URI)
  4. Pattern— 指定された入力文字列が指定されたパターンに一致するかどうかをチェックするメソッドを受け取りましたasMatchPredicate()(たとえば、ストリーム内のデータをフィルターできるように、正規表現を使用して述語を作成できるかどうか)。
  5. String次のような便利な方法をたくさんピックアップしました。
    • String strip(): は、この文字列の先頭と末尾のスペースをすべて削除した文字列を返します (trim() と似ていますが、スペースの定義が異なります)。
    • String stripLeading(): は、文字列から先頭のスペースを削除して、この文字列である文字列を返します。
    • String stripTrailing(): は、文字列の末尾にあるスペースを削除して、この文字列である文字列を返します。
    • Stream lines()Stream: は、この文字列からString抽出され、行区切り文字で区切られて返されます。
    • String repeat(int): は、この文字列を何度も繰り返して連結した文字列を返します。
    • boolean isBlank(): 文字列が空であるかスペースのみが含まれている場合は true を返し、それ以外の場合は false を返します。
  6. Thread— destroy() メソッドと stop(Throwable) メソッドが削除されました。
  7. Filesいくつかの新しいメソッドを取得しました。
    • String readString(Path): UTF-8 エンコーディングを使用してバイトから文字にデコードしながら、ファイルからすべてのデータを文字列に読み取ります。
    • String readString(Path, Charset): 上記のメソッドと同じですが、指定された Charset を使用してバイトから文字へのデコードが行われる点が異なります。
    • Path writeString (Path, CharSequence, OpenOption []): 一連の文字をファイルに書き込みます。文字は UTF-8 エンコーディングを使用してバイトにエンコードされます。
    • Path writeString(Path, CharSequence,Charset, OpenOption []): 上記と同じ方法で、Charset で指定されたエンコーディングを使用して文字のみがバイトにエンコードされます。
これらは (私の謙虚な意見では) 最も興味深い API イノベーションでした。より詳細なレビューのためのいくつかの資料を以下に示します。

Java 12

6 か月が経過し、Java の進化は次の段階に進みます。さあ、シャベルを取り出して知識を掘り起こしましょう。 8 から 13: Java バージョンの完全な概要。 パート 2 - 2

G1 を更新する

G1 では次の改善が行われました。
  1. 未使用の割り当てられたメモリを再利用する

    Java ヒープ メモリには、未使用のメモリ (つまり、非アクティブなメモリ) が存在します。Java 12 では、この問題を次のように修正することが決定されました。

    • G1 は、フル GC または並列ループ中にヒープからメモリを返します。G1 はフル GC の防止を試み、ヒープ割り当てに基づいて並列ループを開始します。G1 にヒープからメモリを強制的に返す必要があります。

    この改善は、G1 が使用されていないときにメモリをヒープから OS に自動的に戻すことにより、パフォーマンスに焦点を当てています。

  2. 一時停止時間を超えた場合の混合コレクションの中止

    G1 は分析エンジンを使用して、ガベージ コレクションに必要な作業量を選択します。セットを定義してクリーンアップを開始した後も、停止することなくライブオブジェクトを収集します。これにより、ガベージ コレクターは一時停止時間の目標を超過します。実際には、次のステップを完了するのに必要な時間が妥当な制限を超えた場合、このステップは中断される可能性があるため、この問題は改善によって解決されました。

マイクロベンチマーク

Java 12 ではマイクロベンチマーク テストが導入され、既存のベンチマークを使用して JVM パフォーマンスを簡単にテストできるようになりました。これは、JVM 自体で作業したい人にとっては非常に便利です。追加されたテストは、Java Microbenchmark Harness (JMH) を使用して作成されます。これらのテストにより、JVM での継続的なパフォーマンス テストが可能になります。JEP 230 では、Java の新しいバージョンがリリースされると新しいテストが導入されるなど、約 100 のテストの導入が提案されています。追加されるテストの例を次に示します。

シェナンドー

これは、短い応答時間 (下限は 10 ~ 500 ミリ秒) を保証することを目的としたガベージ コレクション (GC) アルゴリズムです。これにより、Java スレッドの実行と同時にクリーンアップ作業を行う場合の GC の一時停止時間が短縮されます。Shenandoah では、一時停止時間はヒープ サイズとは無関係です。これは、ヒープのサイズに関係なく、一時停止時間が同じになることを意味します。これは実験的な機能であり、OpenJDK の標準 (Oracle) ビルドには含まれていません。

スイッチの改善

Java 12 では、パターン マッチングの Switch 式が改善されました。新しい構文 L → が導入されました。新しいスイッチの重要なポイントのリストは次のとおりです。
  1. 新しい構文では、エラーを防ぐために Break ステートメントを使用する必要がなくなりました。
  2. Switch 式は失敗しなくなりました。
  3. さらに、単一のラベルに複数の定数を定義できます。
  4. switch 式ではデフォルトのケースが必須になりました。
  5. Break は、レジスタ自体から値を返すために Switch 式で使用されます (実際、スイッチは値を返すことができます)。
これを例として見てみましょう:
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.";
  }
};
Java 13 で式を切り替えるための決定版ガイド その他の新機能:
  1. String:

    transform(Function f)- 提供された関数を文字列に適用します。結果は文字列ではない可能性があります。
    indent(int x)— x 個のスペースを文字列に追加します。パラメータが負の場合、この数の先頭のスペースが (可能な場合) 削除されます。

  2. Files- のようなメソッドを取得しmismatch()、次に 2 つのファイルの内容で最初の不一致バイトの位置を検索して返します。不一致がない場合は -1L を返します。

  3. CompactNumberFormat10 進数をコンパクトな形式にフォーマットするための新しいクラスが登場しました。このコンパクトな形式の例としては、1,000,000 ではなく 1M が挙げられます。したがって、必要な文字は 9 文字ではなく 2 だけです。

  4. LONG と SHORT の 2 つの値を持つ新しいもの enumもありますNumberFormatStyle

  5. InputStream メソッドを取得しました skipNBytes(long n): 入力ストリームから n 番目のバイト数をスキップします。

興味深い Java 12 リンク:

Java 13

Java - Java 13 のように、世界は静止するのではなく、動き、発展します。 8 から 13: Java バージョンの完全な概要。 パート 2 ~ 3

テキストブロック

Java は文字列の定義に関して常に少し苦労してきました。スペース、改行、引用符などを使用して行を定義する必要がある場合は、いくつかの問題が発生するため、特殊文字を使用する必要がありました。たとえば、改行には \n を使用するか、行の一部をエスケープする必要があります。自体。これにより、コードの可読性が大幅に低下し、そのような行を記述するときに余分な時間がかかります。これは、JSON、XML、HTML などを表示する文字列を記述するときに特に顕著になります。その結果、小さな Json を書きたい場合は次のようになります。
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
そして、Java 13 が登場し、テキスト (テキスト ブロックと呼ばれる) の前後に三重二重引用符の形式でそのソリューションを提供します。このイノベーションを使用した前の JSON の例を見てみましょう。
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
はるかにシンプルで明確ですね。Stringこれらのブロックを管理するための3 つの新しいメソッド もそれぞれ追加されました。
  • stripIndent(): 文字列からランダムなスペースを削除します。これは、複数行の文字列を読み取り、明示的な宣言で発生するのと同じ種類のランダムな空白の除外を適用する場合に便利です (基本的に、ランダムな空白を削除するコンパイラをシミュレートします)。
  • formatted(Object... args ): に似ていますformat(String format, Object... arg)が、テキスト ブロック用です。
  • translateEscapes(): 対応する Unicode 値に変換されたエスケープ シーケンス (\r など) を含む文字列を返します。

スイッチの改善

Switch 式は Java 12 で導入され、13 ではそれが改良されました。12ではbreakを使って戻り値を定義します。13 では、戻り値は yield に置き換えられました。Java 12 セクションで説明した switch 式は次のように書き換えることができます。
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.";
  }
};
すでに Java に慣れ親しんでいるプログラマにとって、ブレークを受け入れるのは普通のことでしたが、それでも非常に奇妙でした。Break True は私に何を伝えようとしているのでしょうか? 新しい (比較的新しい) yield キーワードはより明確であり、将来、値が返される他の場所にも表示される可能性があります。このトピックに深く興味がある方は、次の資料をよく理解しておくことをお勧めします。

動的 CDS アーカイブ

CDS - クラスデータ共有。よく使用されるクラスのセットをアーカイブにパッケージ化し、後で複数の JVM インスタンスによってロードできるようにします。なぜ私たちはこれが必要なのですか?実際、JVM はクラスをロードするプロセスで、クラスの読み取り、内部構造への保存、読み取りクラスの正確性のチェック、依存クラスの検索とロードなど、リソースを大量に消費するアクションを実行します。 . そして、これがすべて終わって初めてクラスが動作する準備が整います。JVM インスタンスは同じクラスをロードすることが多いため、当然のことながら、多くのリソースが無駄になります。たとえば、文字列、LinkedList、整数などです。そうですね、同じアプリケーションのクラス、これらはすべてリソースです。必要な手順をすべて 1 回だけ実行し、再設計したクラスを複数の JVM のメモリにロードできるアーカイブに配置すると、メモリ領域が大幅に節約され、アプリケーションの起動時間が短縮される可能性があります。実際、CDS を使用すると、まさにそのようなアーカイブを作成できます。Java 9 では、システム クラスのみをアーカイブに追加できました。Java 10 - アーカイブにアプリケーション クラスを含めます。 このようなアーカイブの作成は次の手順で構成されます。
  • アプリケーションによってロードされるクラスのリストを作成します。
  • 見つかったクラスを使用して必要なアーカイブを作成します。
Java 13 の技術革新により CDS が改善され、アプリケーションの終了時にアーカイブを作成できるようになりました。これは、上記の 2 つのステップが 1 つに結合されることを意味します。そしてもう 1 つ重要な点があります。アプリケーションの実行中にロードされたクラスのみがアーカイブに追加されます。つまり、application.jar にまだ含まれているものの、何らかの理由でロードされなかったクラスは、アーカイブに追加されません。

ソケットAPIの更新

ソケット API ( java.net.Socket および java.net.ServerSocket ) は、Java の誕生以来本質的に Java に不可欠な部分ですが、ソケットは過去 20 年間一度も更新されていません。C と Java で書かれていたため、非常に大きく、保守が困難でした。しかし、Java 13 はこの問題全体に対して独自の調整を行うことを決定し、基本実装を置き換えました。現在、プロバイダー インターフェイスはPlainSocketImplの代わりにNioSocketImplに置き換えられています。この新しいコード化された実装は、 java.nioと同じバックエンド インフラストラクチャに基づいています。基本的に、このクラスは、同期メソッドではなく、java.util.concurrent バッファ キャッシュとロック メカニズム (セグメントベース) を使用します。ネイティブ コードが不要になったので、さまざまなプラットフォームへの移植が容易になりました。それでも、 PlainSocketImplの使用に戻す方法はありますが、今後はNioSocketImpl がデフォルトで使用されます。

ZGCのメモリーリターン

覚えているとおり、Z ガベージ コレクターは、 GC の一時停止が 10 ミリ秒を超えないように、低レイテンシーのガベージ コレクション メカニズムとして Java 11 に導入されました。しかし同時に、Shenandoah や G1 などの他の仮想 GC ホットスポットとは異なり、未使用の動的メモリを OS に返す可能性があります。この変更により、この J 機能が ZGC に追加されます。したがって、パフォーマンスの向上とともにメモリ フットプリントが削減され、指定された最小ヒープ サイズに達するまで、ZGC はデフォルトでコミットされていないメモリをオペレーティング システムに返すようになりました。もう 1 つ: ZGC でサポートされる最大ヒープ サイズは 16 TB になりました。以前は 4TB が制限でした。 その他の革新:
  1. javax.securityjdk.sasl.disabledMechanisms- SASL メカニズムを無効にするプロパティを追加しました。
  2. java.nio- メソッドが追加されましたFileSystems.newFileSystem (Path, Map <String,?>)- それぞれ、新しいファイルを作成します。
  3. クラスjava.nioには、(相対ではなく) 絶対メソッドgetset- メソッドが追加されました。これらには、基本抽象クラスと同様に、バッファーの一部を取得するBufferメソッドが含まれています。slice()
  4. DOM および SAX ファクトリをインスタンス化するためのメソッドが追加されましたjavax.xml.parsers(名前空間のサポートあり)。
  5. Unicode サポートがバージョン 12.1 に更新されました。
Java 13 に関する興味深いリンク:

結果

Java 14 で発表されたイノベーションを確認することもできますが、間もなく光が当たることになるため、JDK 14 は 2020 年 3 月 17 日にリリースされる予定であるため、リリース直後に個別の完全なレビューを実施することが最善です。 。また、Python 2 ~ 3 など、リリース間に長い中断がある他のプログラミング言語には互換性がないという事実にも注意していただきたいと思います。つまり、コードが Python 2 で書かれている場合、互換性はありません。これを 3 に変換するには懸命に取り組む必要があります。Java は非常に下位互換性があるため、この点で特別です。これは、Java 5 または 8 プログラムが Java 8 ~ 13 仮想マシン上で実行されることが保証されていることを意味します。ただし、いくつかの例外はありますが、現時点では心配する必要はありません。これが逆に機能しないことは明らかです。たとえば、アプリケーションが Java 8 JVM では使用できない Java 13 関数を使用している場合です。今日はこれで終わりです、ここまで読んでくださった方に敬意を表します)) 8 から 13: Java バージョンの完全な概要。 パート 2 ~ 5
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION