Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか?私の体は不完全です

インタビュー経験

数年前、アリがインタビューに行ってこの質問をしたことを覚えています。

Javaのオブジェクトはヒープに割り当てられていますか?理由を説明!

そのとき、私は驚いた表情で尋ねられ、すぐに完璧に砕かれました。そのとき、彼がテストしている知識ポイントがわかりませんでした。オブジェクトはヒープに割り当てられていませんか?結局、それ以上はありませんでした、私は戻って通知を待ちました。

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

オブジェクトの割り当て

ほとんどすべてのオブジェクトがヒープに割り当てられます。これは誰もがよく目にする文ですが、この文はすべてを意味するわけではありません。JVMのオブジェクトはスタックに割り当てることができますが、前提はエスケープ状態を判断することです。

オブジェクトのエスケープ状態

1. GlobalEscape

つまり、オブジェクトのスコープは現在のメソッドまたは現在のスレッドをエスケープします。いくつかのシナリオがあります。

  • オブジェクトは静的変数です
  • オブジェクトはエスケープされたオブジェクトです
  • 現在のメソッドの戻り値としてのオブジェクト

2.パラメータエスケープ(ArgEscape)

つまり、オブジェクトはメソッドパラメータとして渡されるか、パラメータによって参照されますが、呼び出し中にグローバルエスケープは発生せず、この状態は呼び出されたメソッドのバイトコードによって決定されます。

3.逃げられない

つまり、メソッド内のオブジェクトはエスケープしません。

エスケープ分析コード

public class EscapeAnalysisTest { 
  public static void main(String[] args) throws Exception {    
    long start = System.currentTimeMillis();      
    for (int i = 0; i < 50000000; i++) {            
      allocate();          }           System.out.println((System.currentTimeMillis() - start) + " ms");    
    Thread.sleep(600000);    }​   
    static void allocate() {        
      MyObject myObject = new MyObject(2020, 2020.6);    }​ 
      static class MyObject {        int a;        double b;​        MyObject(int a, double b)
        {            this.a = a;            this.b = b;        
        }    }}

このコードを呼び出すプロセスで、オブジェクトmybojectはグローバルエスケープに属し、JVMはそれをスタックに割り当てることができます

次に、DoEscapeAnalysisスイッチをオン/オフして違いを観察します。

エスケープ分析を有効にする(JVMはデフォルトで有効になっています)

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

実行速度を表示

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

エスケープ分析をオフにする

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

実行速度を表示

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

テスト結果は、エスケープ分析を有効にすると、コードの実行パフォーマンスに大きな影響があることを示しています。では、なぜそのような影響があるのでしょうか。

エスケープ分析

エスケープで解析されたオブジェクトをスタックに配置できる場合は、オブジェクトのライフサイクルはスレッドに従い、ガベージコレクションは不要ですが、このメソッドを頻繁に呼び出すと、パフォーマンスが大幅に向上します。

エスケープ分析を採用した後、エスケープを満たすオブジェクトがスタックに割り当てられます

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

エスケープ分析が有効になっておらず、オブジェクトがヒープに割り当てられているため、ガベージコレクションが頻繁にトリガーされ(ガベージコレクションはシステムパフォーマンスに影響を与えます)、コードの実行が遅くなります

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

コード検証

GC印刷ログを有効にする

-XX:+ PrintGC

エスケープ分析をオンにする

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

GCログがないことがわかります

エスケープ分析をオフにする

Aliインタビュアー:Javaオブジェクトをヒープに割り当てる必要がありますか? 私の体は不完全です

 

エスケープ分析がオフになっていて、JVMがガベージコレクション(GC)を頻繁に実行していることがわかります。この操作がパフォーマンスに大きな違いを引き起こしています。

総括する

JVMは、多くの面接担当者が聞きたいものです。ただし、JVMには幅広く深い知識システムがあるため、面接担当者の質問の中には非常にトリッキーなものもあります。そのため、よくわからない場合は、軽く答えるべきではありません。いくつかの知識は、経験するための練習が必要です。これらの知識のポイントを落ち着いて説明すると、面接で主導権を握ることができます。

おすすめ

転載: blog.csdn.net/python8989/article/details/108759836