ポイントツー分析レポート
ポイントツー分析では、分析コール・ツリーとオブジェクト・ツリーの2種類のレポートが生成されます。この情報は、ビルド・プロセスの中間ステップによって生成され、コール・グラフおよびヒープ・オブジェクト・グラフの静的分析ビューを表します。これらのグラフは、事前にバイナリにコンパイルされてバイナリ・ヒープにそれぞれ書き込まれる前に、ビルド・プロセスでさらに変換されます。
分析領域全体の包括的なレポートに加えて、ポイントツー分析では、特定の型/メソッド/フィールドが到達可能な理由に関する到達可能性レポートを生成することもできます。
コール・ツリー
コール・ツリーとは、ポイントツー分析で表示されるコール・グラフの幅優先ツリー縮小です。ポイントツー分析では、分析されたレシーバ・タイプに基づいて、実行時にアクセスできないと判断されるメソッドのコールが排除されます。また、常に失敗する型チェックで保護されたブロックなど、アクセス不能なコード・ブロックでの呼出しも完全に排除されます。コール・ツリー・レポートは、-H:+PrintAnalysisCallTreeコマンドライン・オプションを使用して有効化され、TXTファイル(デフォルト)として、または-H:PrintAnalysisCallTreeType=CSVオプションを使用した一連のCSVファイルとして、フォーマットできます。
TXT形式
TXT形式を使用すると、次の構造を持つファイルが生成されます:
VM Entry Points
├── entry <entry-method> id=<entry-method-id>
│ ├── directly calls <callee> id=<callee-id> @bci=<invoke-bci>
│ │ └── <callee-sub-tree>
│ ├── virtually calls <callee> @bci=<invoke-bci>
│ │ ├── is overridden by <override-method-i> id=<override-method-i-id>
│ │ │ └── <callee-sub-tree>
│ │ └── is overridden by <override-method-j> id-ref=<override-method-j-id>
│ └── interfacially calls <callee> @bci=<invoke-bci>
│ ├── is implemented by <implementation-method-x> id=<implementation-method-x-id>
│ │ └── <callee-sub-tree>
│ └── is implemented by <implementation-method-y> id-ref=<implementation-method-y-id>
├── entry <entry-method> id=<entry-method-id>
│ └── <callee-sub-tree>
└── ...
<と>の間のタグは具体的な値として展開され、残りはこのとおりに出力されます。メソッドは、<qualified-holder>.<method-name>(<qualified-parameters>):<qualified-return-type>を使用してフォーマットされ、これ以上のコール先にアクセスできなくなるまで展開されます。
これはコール・グラフのツリー縮小であるため、各具象メソッドは1回のみ展開されます。ツリー表現では、別のブランチで検索されたり、以前に同じブランチで検索されたメソッドのコールは本質的に省略されます。この制限により、再帰の問題が暗黙的に修正されます。ツリー縮小によって失われる情報を伝達するために、各具象メソッドには一意のIDが与えられます。したがって、メソッドへの初回アクセス時に、識別子はid=<method-id>として宣言されます。同じメソッドの後続の検出では、以前の展開場所を指すために識別子参照が使用されます(id-ref=<method-id>)。検索を容易にするために、各id=<method-id>およびid-ref=<method-id>の後に空白が続きます。
各呼出しは、呼出しbciを使用してタグ付けされます(@bci=<invoke-bci>)。インライン・メソッドの呼出しの場合、<invoke-bci>は、->で区切られたbci値のリストで、インラインの場所を元の呼出しの場所まで逆方向に列挙したものです。
CSV形式
CSV形式を使用すると、メソッドとその関係のRAWデータを含む一連のファイルが生成されます。これらのファイルの目的は、このRAWデータをグラフ・データベースに簡単にインポートできるようにすることです。グラフ・データベースでは、次の機能が提供されます:
- コール・ツリー・グラフの高度なグラフィカル表示。テキストベース形式と比較して、異なる視点が提供されます。
- (たとえば)ツリーのサブセットを表示して、特定のコード・パスをコール・ツリー分析に含めることができる複雑な問合せを実行する機能。このような問合せ機能は、大きな分析コール・ツリーを管理しやすくするために重要です。
ファイルをグラフ・データベースにインポートするプロセスは、各データベースに固有です。グラフ・データベースのプロバイダが提供する指示に従ってください。
オブジェクト・ツリー
オブジェクト・ツリーは、ネイティブ・バイナリ・ヒープに含まれるオブジェクトを完全に展開したものです。ツリーは、ネイティブ・バイナリ・ヒープのオブジェクト・グラフの深さ優先ウォークによって取得されます。これは、-H:+PrintImageObjectTreeオプションを使用して有効にします。ルートは、埋込み定数を含む静的フィールドまたはメソッド・グラフのいずれかです。出力される値は、ネイティブ・バイナリ・ヒープに追加される具象定数オブジェクトです。この場合、次の構造のファイルが生成されます:
Heap roots
├── root <root-field> value:
│ └── <value-type> id=<value-id> toString=<value-as-string> fields:
│ ├── <field-1> value=null
│ ├── <field-2> toString=<field-2-value-as-string> (expansion suppressed)
│ ├── <field-3> value:
│ │ └── <field-3-value-type> id=<field-3-value-id> toString=<field-3-value-as-string> fields:
│ │ └── <object-tree-rooted-at-field-3>
│ ├── <array-field-4> value:
│ │ └── <array-field-4-value-type> id=<array-field-4-value-id> toString=<array-field-4-value-as-string> elements (excluding null):
│ │ ├── [<index-i>] <element-index-i-value-type> id=<element-index-i-value-id> toString=<element-index-i-value-as-string> fields:
│ │ │ └── <object-tree-rooted-at-index-i>
│ │ └── [<index-j>] <element-index-j-value-type> id=<element-index-j-value-id> toString=<element-index-j-value-as-string> elements (excluding null):
│ │ └── <object-tree-rooted-at-index-j>
│ ├── <field-5> value:
│ │ └── <field-5-value-type> id-ref=<field-5-value-id> toString=<field-5-value-as-string>
│ ├── <field-6> value:
│ │ └── <field-6-value-type> id=<field-6-value-id> toString=<field-6-value-as-string> (no fields)
│ └── <array-field-7> value:
│ └── <array-field-7-value-type> id=<array-field-7-id> toString=<array-field-7-as-string> (no elements)
├── root <root-field> id-ref=<value-id> toString=<value-as-string>
├── root <root-method> value:
│ └── <object-tree-rooted-at-constant-embeded-in-the-method-graph>
└── ...
<と>の間のタグは具体的な値として展開され、残りはこのとおりに出力されます。ルート・フィールドは、<qualified-holder>.<field-name>:<qualified-declared-type>を使用してフォーマットされます。非ルート・フィールドは、<field-name>:<qualified-declared-type>を使用してフォーマットされます。値の型は、<qualified-type>を使用してフォーマットされます。ルート・メソッドは、<qualified-holder>.<method-name>(<unqualified-parameters>):<qualified-return-type>を使用してフォーマットされます。配列なしオブジェクトは、すべてのフィールド(nullを含む)に対して展開されます。フィールドのない配列なしオブジェクトは、(no fields)でタグ付けされます。配列オブジェクトは、null以外のすべてのインデックスに対して展開されます([<element-index>] <object-tree-rooted-at-array-element>)。空の配列オブジェクトまたはすべてがnull要素の配列オブジェクトは、(no elements)でタグ付けされます。
各定数値は、フォーマットを圧縮するために1回のみ展開されます。値が複数のブランチからアクセスされる場合は、初回にのみ展開され、識別子が与えられます(id=<value-id>)。同じ値の後続の検出では、以前の展開場所を指すために識別子参照が使用されます(id-ref=<value-id>)。
値の展開の抑制
String、BigInteger、プリミティブ配列などの一部の値は、デフォルトでは展開されず、(expansion suppressed)でマークされます。その他すべての型はデフォルトで展開されます。デフォルトで展開される型を強制的に抑制するには、-H:ImageObjectTreeSuppressTypes=<comma-separated-patterns>を使用します。デフォルトまたはオプションで抑制されている型を強制的に展開するには、-H:ImageObjectTreeExpandTypes=<comma-separated-patterns>を使用します。-H:ImageObjectTreeSuppressTypesと-H:ImageObjectTreeExpandTypesの両方が指定されている場合は、-H:ImageObjectTreeExpandTypesが優先されます。
同様に、多数の文字列を出力するjava.lang.Character$UnicodeBlock.map"などの一部のルートは、まったく展開されず、(expansion suppressed)でマークされます。その他すべてのルートはデフォルトで展開されます。デフォルトで展開されるルートを強制的に抑制するには、-H:ImageObjectTreeSuppressRoots=<comma-separated-patterns>を使用します。デフォルトまたはオプションで抑制されているルートを強制的に展開するには、-H:ImageObjectTreeExpandRoots=<comma-separated-patterns>を使用します。-H:ImageObjectTreeSuppressRootsと-H:ImageObjectTreeExpandRootsの両方が指定されている場合は、-H:ImageObjectTreeExpandRootsが優先されます。
前述のすべての抑制/展開オプションで、パターンのカンマ区切りリストを指定できます。型の場合、パターンは型の完全修飾名に基づき、定数の具象型を参照します。(配列型の場合、要素型を指定するのみです。その型のすべての次元のすべての配列と一致します。)ルートの場合、パターンは前述のルートの文字列形式に基づきます。このパターンでは、*修飾子を指定できます:
- ends-with:
*<str>- パターンは、<str>で終わるすべてのエントリと完全に一致します - starts-with:
<str>*- パターンは、<str>で始まるすべてのエントリと完全に一致します - contains:
*<str>*- パターンは、<str>を含むすべてのエントリと完全に一致します - equals:
<str>- パターンは、<str>と等しいすべてのエントリと完全に一致します - all:
*- パターンは、すべてのエントリと一致します
サンプル
型の抑制/展開:
-H:ImageObjectTreeSuppressTypes=java.io.BufferedWriter-java.io.BufferedWriterオブジェクトの展開を抑制します-H:ImageObjectTreeSuppressTypes=java.io.BufferedWriter,java.io.BufferedOutputStream-java.io.BufferedWriterおよびjava.io.BufferedOutputStreamオブジェクトの展開を抑制します-H:ImageObjectTreeSuppressTypes=java.io.*- すべてのjava.io.*オブジェクトの展開を抑制します-H:ImageObjectTreeExpandTypes=java.lang.String-java.lang.Stringオブジェクトを強制的に展開します-H:ImageObjectTreeExpandTypes=java.lang.String,java.math.BigInteger-java.lang.Stringおよびjava.math.BigIntegerオブジェクトを強制的に展開します-H:ImageObjectTreeExpandTypes=java.lang.*- すべてのjava.lang.*オブジェクトを強制的に展開します-H:ImageObjectTreeSuppressTypes=java.io.* -H:ImageObjectTreeExpandTypes=java.io.PrintStream-java.io.PrintStreamオブジェクトを除き、すべてのjava.io.*オブジェクトの展開を抑制します-H:ImageObjectTreeExpandTypes=*- デフォルトで抑制されているものも含め、すべての型のオブジェクトを強制的に展開します
ルートの抑制/展開:
-H:ImageObjectTreeSuppressRoots="java.nio.charset.Charset.lookup(String)"-com.oracle.svm.core.amd64.FrameAccess.wordSize()のグラフに埋め込まれたすべての定数の展開を抑制します-H:ImageObjectTreeSuppressRoots=java.util.*-java.util.で始まるすべてのルートの展開を抑制します-H:ImageObjectTreeExpandRoots=java.lang.Character$UnicodeBlock.map-java.lang.Character$UnicodeBlock.map静的フィールド・ルートを強制的に展開します-H:ImageObjectTreeSuppressRoots=java.util.* -H:ImageObjectTreeExpandRoots=java.util.Locale-java.util.Localeを除き、java.util.で始まるすべてのルートの展開を抑制します-H:ImageObjectTreeExpandRoots=*- デフォルトで抑制されているものも含め、すべてのルートを強制的に展開します
到達可能性レポート
コード・サイズまたはセキュリティの問題を診断する際、開発者は多くの場合、特定のコード要素(型/メソッド/フィールド)に到達できる理由を知る必要があります。到達可能性レポートは、その目的のために設計されています。型、メソッドおよびフィールドそれぞれの到達可能性の理由を診断するために、3つのオプションがあります。
-H:AbortOnTypeReachable=<pattern>-H:AbortOnMethodReachable=<pattern>-H:AbortOnFieldReachable=<pattern>
各オプションについて、右側は診断するコード要素のパターンを指定します。
- 型およびフィールドを指定するための構文は、抑制/拡張の構文と同じです(前述の
-H:ImageObjectTreeSuppressTypesのドキュメントを参照)。 - メソッドを指定する構文は、メソッド・フィルタの構文と同じです(
-Dgraal.MethodFilterのドキュメントを参照)。
オプションのいずれかが有効で、対応するコード要素に到達できる場合、到達可能性トレースはTXTファイルにダンプされ、ネイティブ・イメージは中止されます。-H:AbortOnTypeReachable=java.io.Fileの到達可能性レポートの例を次に示します:
Type java.io.File is marked as allocated
at virtual method com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:105), implementation invoked
├── at virtual method com.oracle.svm.core.jdk.JNIPlatformNativeLibrarySupport.loadJavaLibrary(JNIPlatformNativeLibrarySupport.java:44), implementation invoked
│ ├── at virtual method com.oracle.svm.core.posix.PosixNativeLibrarySupport.loadJavaLibrary(PosixNativeLibraryFeature.java:117), implementation invoked
│ │ ├── at virtual method com.oracle.svm.core.posix.PosixNativeLibrarySupport.initializeBuiltinLibraries(PosixNativeLibraryFeature.java:98), implementation invoked
│ │ │ ├── at static method com.oracle.svm.core.graal.snippets.CEntryPointSnippets.initializeIsolate(CEntryPointSnippets.java:346), implementation invoked
│ │ │ │ str: static root method
│ │ │ └── type com.oracle.svm.core.posix.PosixNativeLibrarySupport is marked as in-heap
│ │ │ scanning root com.oracle.svm.core.posix.PosixNativeLibrarySupport@4839bf0d: com.oracle.svm.core.posix.PosixNativeLibrarySupport@4839bf0d embedded in
│ │ │ org.graalvm.nativeimage.ImageSingletons.lookup(ImageSingletons.java)
│ │ │ at static method org.graalvm.nativeimage.ImageSingletons.lookup(Class), intrinsified
│ │ │ at static method com.oracle.svm.core.graal.snippets.CEntryPointSnippets.createIsolate(CEntryPointSnippets.java:209), implementation invoked
│ │ └── type com.oracle.svm.core.posix.PosixNativeLibrarySupport is marked as in-heap
│ └── type com.oracle.svm.core.jdk.JNIPlatformNativeLibrarySupport is reachable
└── type com.oracle.svm.core.jdk.NativeLibrarySupport is marked as in-heap
scanning root com.oracle.svm.core.jdk.NativeLibrarySupport@6e06bbea: com.oracle.svm.core.jdk.NativeLibrarySupport@6e06bbea embedded in
org.graalvm.nativeimage.ImageSingletons.lookup(ImageSingletons.java)
at static method org.graalvm.nativeimage.ImageSingletons.lookup(Class), intrinsified
レポート・ファイル
レポートは、ビルド・ディレクトリに対して相対的なreportsサブディレクトリに生成されます。native-image実行可能ファイルを実行すると、ビルド・ディレクトリはデフォルトで作業ディレクトリに設定され、-H:Path=<dir>オプションを使用して変更できます。
コール・ツリー・レポート名の構造は、TXT形式を使用する場合はcall_tree_<binary_name>_<date_time>.txtで、CSV形式を使用する場合はcall_tree_*_<binary_name>_<date_time>.csvになります。CSV形式のコール・ツリー・レポートを生成する場合、最新のコール・ツリーCSVレポートを指す構造call_tree_*.csvに続くシンボリック・リンクも生成されます。オブジェクト・ツリー・レポート名の構造は、object_tree_<binary_name>_<date_time>.txtです。バイナリ名は、生成されるバイナリの名前であり、-H:Name=<name>オプションを使用して設定できます。<date_time>のフォーマットはyyyyMMdd_HHmmssです。
到達可能性レポートは、reportsディレクトリにもあります。同じ命名規則に従います。
- 型到達可能性レポート:
trace_types_<binary_name>_<date_time>.txt - メソッド到達可能性レポート:
trace_methods_<binary_name>_<date_time>.txt - フィールド到達可能性レポート:
trace_fields_<binary_name>_<date_time>.txt