2016-05-18 4 views
2

Javaはスレッドのスタックトレースをどのように生成しますか?Javaは内部的にStackTrace機能をどのように維持しますか

例:

functionC通話functionDを呼び出しfunctionBfunctionA呼び出しを考えてみましょう。 functionDgetStackTraceElementArrayの任意の時点で使用されている場合、それはfunctionCallsの配列を与える:

functionC->functionB->functionA 

はどのようにJavaは、実行時にStackTraceElement配列を埋めるのですか?コールされた関数が呼び出された関数の内部に到達したときにそれを満たすと仮定すると、JVMは呼び出されたメソッドの中で呼び出し元のメソッドの参照をどのように取得しますか?

+0

@Robby Cornelissen:これは重複した質問ではありませんが、スタックトレースを取得する方法は問いませんが、Javaは内部的にどのように作成しますか?人口が多い。 –

+1

質問をしてください。メソッドスタックエリアのハンドラがあり、JavaプログラムでStackTraceElement Arrayを手動で作成または埋め込むために使用できます。現在のスタックトレースを取得する方法を探しているように思えます。 –

+1

再開。今[ここ](http://stackoverflow.com/questions/12865180/how-do-stack-traces-get-generated)を参照してください。 –

答えて

3

最も単純なケースでは、スタックトレースはスタックから取得されます。 enter image description here
各スレッドには、現在のスタックフレームのベースアドレスを指すフレームポインタ(FP)レジスタがあります。 Javaメソッドが呼び出されると、新しいスタックフレームが最初に作成されます。つまり、スタックに一連の情報がプッシュされます。

  • リターンアドレス(メソッドが呼び出された場所)。
  • 現在のFP(呼び出し元フレームを指し示す)。
  • 呼び出されているメソッドのメソッドID。定数プールキャッシュなどへ
  • ポインタ

そして、それは新たに作成されたフレームを指すようにFPを更新します。

このようにして、フレームポインタはリンクリストを作成します.FPが指す値を読み取ると、前のフレームのベースアドレスが取得されます。

各フレームについて、メソッドIDは常にFPからの同じオフセットにあることに注意してください。だから、スタック歩行は(擬似コードで書かれた)whileループと同じくらい簡単です:それは解釈方法のためのJVMの内部でどのように機能するか

address fp = currentThread.getFP(); 
while (fp != null) { 
    methodID m = (methodID) read_stack_at(fp + METHOD_OFFSET); 
    print_method(m); 
    fp = (address) read_stack_at(fp); 
} 

がそれです。コンパイルされたメソッドは少し複雑です。通常、スタック上にメソッド参照を保存しません。その代わりに、コンパイルされたコードのアドレスを、コンパイルされたメソッド情報を含むメタデータにマップする構造体があります。しかしスタック歩行の考え方はまだ同じです。

関連する問題