第12章. Java SE APIのヒント
この作品はAIを使って翻訳されている。ご意見、ご感想をお待ちしている:translation-feedback@oreilly.com
この章では、パフォーマンスに影響を与える実装の癖があるJava SE APIの領域を取り上げる。このような実装の詳細は、JDK全体に数多く存在する。これらの領域は、(私自身のコードでさえも)パフォーマンスの問題を常に発見している。この章には、文字列(特に重複文字列)を処理する最良の方法、I/Oを適切にバッファリングする方法、クラスローディングと、多くのクラスを使用するアプリケーションの起動を改善する方法、コレクションの適切な使用、LambdaやストリームなどのJDK 8の機能についての詳細が含まれている。
文字列
文字列は、(意外にも)最も一般的なJavaオブジェクトである。このセクションでは、文字列オブジェクトが消費するすべてのメモリを処理するためのさまざまな方法を見ていく。また、連結を含む文字列のJDK 11の新機能も取り上げる。
コンパクトな文字列
Java 8では、文字列のエンコーディングにかかわらず、すべての文字列は16ビット文字の配列としてエンコードされる。これは無駄である。欧米のほとんどのロケールでは、文字列を8ビットのバイト配列にエンコーディングできるし、すべての文字に16ビットを必要とするロケールであっても、プログラム定数のような文字列は8ビットバイトとしてエンコーディングできることが多い。
Java 11では、文字列は、明示的に16ビット文字を必要としない限り、8ビットバイトの配列としてエンコーディングされる。Java 6の同様の(実験的な)機能は、圧縮文字列として知られていた。コンパクト文字列も概念的には同じだが、実装は大きく異なる。
したがって、Java 11の平均的なJava文字列のサイズは、Java 8の同じ文字列のサイズのおよそ半分である。これは一般的に大きな節約である。平均して、一般的なJavaヒープの50%が文字列オブジェクトによって消費される可能性がある。もちろんプログラミングはさまざまだが、平均してJava 11で実行されるプログラムのヒープ要件は、Java 8で実行される同じプログラムの75%にすぎない。
ガベージ・コレクションの実行に膨大な時間を費やしているプログラミングをJava 8で実行することができる。同じサイズのヒープを持つJava 11で同じプログラムを実行すると、コレクターに費やす時間は事実上ゼロになり、性能は3倍から10倍向上すると報告されている。このような主張は大目に見てほしい。通常、このような制約のあるヒープでJavaプログラムを実行することはないだろう。そのような制約のあるヒープでJavaプログラムを実行することは通常ないだろう。しかし、すべてのことが同じであれば、ガベージ・コレクションに費やされる時間は減るだろう。
平均的なプログラムの最大ヒープサイズを25%削減しても、同じパフォーマンスを得ることができる。逆に、ヒープサイズを変更しないままであれば、アプリケーションに多くの負荷を導入しても、GCのボトルネックは発生しないはずだ(ただし、アプリケーションの他の部分は、増加した負荷を処理できなければならない)。
この機能は-XX:+CompactStrings
true フラグによって制御される。しかし、Java 6の圧縮文字列とは異なり、コンパクト文字列は堅牢性とパフォーマンスが高い。例外として考えられるのは、すべての文字列が16ビット・エンコーディングを必要とするプログラムである。これらの文字列に対する演算子は、コンパクト化された文字列の方がコンパクト化されていない文字列よりもわずかに長くなる可能性がある。 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access