3

Java プログラムのメモリ アクセス パターンを調べたい。これを達成するためのフレームワークまたは方法はありますか。

メモリアドレス m1、m2、m3 などをこの順序でアクセスするプログラム P があるとします。これらのアクセスをその順序で確認できるようにしたいのですが、可能であれば、どのタイプのオブジェクトがアクセスされましたか?

更新(Durandalの提案に追加):

PIN インストルメンテーションを使用して Java プログラムを実行することで、いつでもメモリ アクセス パターンを見つけることができます。これは、オブジェクトへのメモリアドレスのマッピングを失うことを除いて、すべて良いことです。私がやりたい研究の重要な側面の 1 つは、メモリ使用量を対応する型 (クラス) にマップできるようにすることです。

メモリ使用パターンが JVM の実装に依存することは正しく述べられていますが、それは調査の後のステップとして検討したいと思います。現在、バイトコードのインストルメンテーションのみを探しています。(間違った方向に進んでいる場合は修正してください!)

バイトコード インストルメンテーションがキャッシュの使用状況の分析にどのように役立つと思いますか? 説明の前に!これは私がやりたいことのほんの一面です。これは、さまざまなオブジェクト (または特定のクラスに属するオブジェクト) によるキャッシュの使用状況に関する情報を提供するには、メモリ アクセス パターン (PIN、または変更された VM などから取得) が不十分な場合に行います。 . バイトコードアクセスを次のように取得するとします

ObjectA
ObjectB
ObjectC
...

オブジェクトのサイズを簡単に見つけることができます。また、これがオブジェクトへの最初のアクセスであるかどうかによって、オブジェクトのメモリ アクセスがメモリ割り当てであったかどうかを確認することもできます。次に、実行時に JVM が継続的にメモリを割り当てると仮定すると、(キャッシュ シミュレーションを実行することで) キャッシュの使用量を推測できます。さて、これはあまり良い仮定ではありませんが、それでもキャッシュ使用量の上限を与えてくれます (少なくとも私はそう信じています)。

4

2 に答える 2

2

VM を変更するという難しい方法をいつでも実行できます。Java で完全に記述された JVM 実装があり、必要なデータを収集するために変更できる可能性があります。

ただし、メモリ アクセス パターンは、プログラムを実行している特定の VM に大きく依存することを強く確信しています (メモリ内でデータを異なる方法でグラニュライズするため)。異なる VM = 異なるアクセス パターン。測定する VM に JIT がある場合、JIT が開始されるかどうかにも依存します。

すべてのメモリ アクセスを実際に収集する方法は、何らかのサンドボックス環境で VM を実行し、そのアクセスをカウントすることです (これは、エミュレーターで、または MMU の助けを借りて行うことができます)。


編集 (質問の更新 - バイトコード インストルメンテーションのみ): バイトコード インストルメンテーションを使用すると、基本的にインストルメント プロファイラーの機能に非常に近くなります。現在の主な問題は、オブジェクトとメモリ アドレスの関係を簡単に確立できないことです。これを回避するには、次の 2 つの方法が考えられます。

  • オブジェクト、フィールド、および配列の絶対メモリアドレスを取得できる(JRE プライベートですが使用可能な) クラス sun.misc.Unsafe があります (それを行うためのメソッドがたくさんあります)。バイトコードをインストルメント化してカウント用のユーティリティ メソッドを呼び出すと、Unsafe を使用して使用するアドレスを決定できます。ただし、Unsafe は実装固有であり、ヒープ内でオブジェクトを移動するガベージ コレクターに問題がある可能性があります。これは、測定したいものである場合とそうでない場合があります。少なくともこれは、妥当な量の努力で実装できます。

  • メモリ アドレスの概念を完全に放棄し、オブジェクト IDフィールド(それぞれ配列 ID とインデックス)に置き換えることができます。プロファイリング インストルメンテーションは、オブジェクトとアクセスされたフィールドを追跡する必要があります。本当に注意を払う必要がある唯一のことは、ガベージ コレクターをブロックしない方法 (たとえば、WeakReferences を使用) でオブジェクト参照を保持する必要があるということです。これも、実装するのがそれほど難しくないはずです。このアプローチは、ホット メモリロケーションを特定するのではなく、ホット オブジェクト/フィールドを特定します。

収集されたデータは分析対象のコードと同じヒープに格納されるため、どちらのアプローチも測定に影響を与えます。それが非常に望ましくない場合は、JNI を使用してオフヒープでデータを収集できます。

于 2012-07-23T11:49:27.870 に答える
0

Java プログラムのどの部分ですか? 「public static void main(String[] args) {...」によってロードされ、以前にアクセス可能だったクラスで構成される Java「ユーザー空間」、または舞台裏のメモリ管理、ガベージ コレクション、デバッグ機能、管理機能など

実メモリ アドレスを探していた場合は、JVM をデバッグする必要があります。これは Java プログラムのデバッグとは大きく異なります。実メモリと「ユーザー空間」プログラムの間にメモリ抽象化レイヤが存在するからです。実メモリ アクセスをチューニングするには、Java プログラムを書き直すことはできません。JVM を書き直す必要があります。

バイトコードの挿入は、依然として「ユーザー空間」Java プログラムの一部です。つまり、バイトコードの挿入によって絶対メモリ アドレスを特定することはできません。実際、実メモリ アドレスへの JVM 参照の「ユーザ空間」マッピングは、同じオブジェクトに対して時間の経過とともに一定であるとは期待されていません。

于 2012-07-23T16:57:23.553 に答える