bugfix> java > 投稿

時間が経つにつれてJVMがよりスマートになることを私は知っています(コードの最適化など...)。
しかし、それはどれほど賢くなりますか?

私がよく目にする実際のシナリオを考えてみましょう。

public static String toJson(final Object object) throws JsonProcessingException {
   final ObjectMapper mapper = new ObjectMapper();
   return mapper.writeValueAsString(object); 
}

これを分析すると、 ObjectMapper (私が重いと思うもの)は、このメソッドが呼び出されるたびにヒープ上に作成されます。
これはガベージコレクターにとって非常にコストがかかります。

だから私の質問は、JVMは十分に賢く、1つのインスタンス(静的インスタンスのようなもの)だけを作成できるかということです。

回答 2 件
  • JVMは、Java言語仕様に違反する静的オブジェクトに関して、このオブジェクトを暗黙的に共有しません。オブジェクト自体にメンバーがない場合でも、他のオブジェクトとその状態に依存していると、動作が変わる可能性があり、スレッドセーフではない可能性があります。オブジェクトがスレッドセーフであるか、コードがシングルスレッドである場合でも、実装が常に初期状態から開始されるとは限らないため、暗黙的な再利用によって元のコードの想定が破られる可能性があります。

    オブジェクトの割り当て自体を排除することに関しては、それは実行可能であり、特定の状況下で実行されます。エスケープ分析により、JITは、新しく作成されたオブジェクトへの参照が、ローカル変数の現在のセットに関して現在のフレームを理論的に離れるか「エスケープ」できるかどうかを判断できます。この場合、参照は他のヒープオブジェクトのフィールドに格納される可能性があります。分析の結果、特定のオブジェクトがそうではないことが判明した場合、オブジェクトの存続期間は現在のフレームに制限されているため、ヒープ割り当てをスタック割り当てに置き換えることができます。

    Oracle JVM実装はエスケープ分析を実行できますが、ヒープ割り当てをスタック割り当てに置き換えることはありません。代わりに、「スカラー置換」と呼ばれる最適化を実行します。これは、オブジェクト参照が現在のフレームをエスケープせず、呼び出されたすべてのオブジェクトメソッドをインライン化できる場合、オブジェクトフィールドアクセスが対応するローカル変数に置き換えられることを意味します。これにより、JVMは実際のオブジェクトインスタンスを完全に排除します。の実装に応じて ObjectMapper 、この最適化はあなたの例に適用できます。

    詳細については、以下を参照してください。

    https://docs.oracle.com/javase/8/docs/technotes/guides/vm/performance-enhancements-7.html#escapeAnalysis

    ドキュメントに基づいてオブジェクトを安全に共有および再利用できることがわかっている場合、最善のアプローチは、潜在的な最適化に依存するのではなく、インスタンスを明示的に再利用することです。

  • いいえ。これらのことを伝える必要があります。 Java言語仕様を読んで、JVMがどのように動作するかを正確に学習してください。

    https://docs.oracle.com/javase/specs/

あなたの答え