2

私はJavaアプリケーションの経験がありませんが、これらのアプリケーションのメモリアドレスへの静的ポインタなどを見つけることは、明らかにコードを処理するJavaエンジンのために(ほぼ)不可能であることがわかりました(この方法で名前を付ける場合は修正してください)間違ってください)。

今、私は VisualVM ( https://visualvm.dev.java.net/ ) を使用しましたが、それは素晴らしいことです。Java プロセスを選択して、ヒープ ダンプを作成できます。次に、すべてのクラスとその値が表示されます。

このメソッドを使用してヒープ ダンプを継続的にポーリングし、ゲームの XY や Z などのオブジェクト値を受け取ることはできますか? このようなアプリケーションとプログラムで対話するにはどうすればよいですか?また、これを VisualVM で行うべきではない場合、代替手段は何でしょうか?

編集:これが私がする必要があることです: 特定の値を持つプロパティを持つすべてのクラスを見つけることができる必要があります。例: X 座標 (float) を検索すると、クラス "PlayerCoordsHandler" (単なる例) とそれに対応する float とその値が返されるはずです... または、この同じ float を再度見つける方法にすぎません。 (たとえば再起動後)。このプロセスは、現在既知のプロパティ (x float) の値を要求してプログラムで取得できる限り、プログラムである必要はありません (たとえば、コマンド ライン ユーティリティを使用するか、ファイルから読み取る)。

Edit2: ターゲット アプリケーションは Windows 実行可能ファイル (ただし Java で作成) であり、独自の Java VM を起動します。デバッグ用の Java パラメータを追加することはできません。ただし、VirtualVM はプロセスを問題なくデバッグできるため、これは必須ではないようです。誰でも方法を知っていますか?

前もって感謝します。

4

7 に答える 7

3

実行中の Java アプリケーションをデバッグしたいようです。

「公式」Java デバッガーは JDB です。JDKの一部だと思います。ブレークポイントの設定、ヒープの調査、変数の一覧表示と表示、さらには変数の変更、実行中のスレッドの表示などの機能があります。通常のデバッガーのもの。しかし、これはコマンド ラインなので、操作が面倒です。

代わりに、デバッガーが統合された IDE を使用することは非常に理にかなっています。私はエクリプスを使用しています。変数を使用してウィンドウを表示するなど、通常のデバッグ作業をすべて行うことができます。条件付きブレークポイントを設定できますが、他にもたくさんあります。具体的には、質問への回答として、ウォッチ式を設定できます。これは、プログラムの実行中に評価され、表示が変更されたときに新しい値で更新されます。

IDE 内で Java アプリケーションを実行したくない場合があります。または、Web アプリケーション サーバーで実行されている可能性があります。JDB や Eclipse (または NetBeans や IntelliJ Idea などの他の IDE) にとっては問題ありません。実行中の JVM に接続して、同じレベルの利便性でリモートでデバッグできます。

このようにリモートまたはその他の方法でデバッグされているプログラムは、そうでない場合よりも実行速度が多少遅くなります。あなたのゲームは、デバッグ中はかなり見栄えの悪い FPS で実行されます。ただし、ゲームプレイのインタラクションには多かれ少なかれ正常に応答する必要があります。


リモート デバッグ:

Eclipse NetBeans デバッガーを実行中の Java プロセスに接続できるようにするには、次の Java オプションを使用してそのプロセスを開始する必要があります…</p>

-Xdebug -Xrunjdwp:transport=dt_socket,address=3704,server=y,suspend=n
于 2010-01-07T11:32:11.920 に答える
2

ヒープダンプのトリガーは、メモリ リークなどの事後分析に役立ちますが、Java ガベージ コレクタがオブジェクトを移動するため、ヒープダンプのメモリ値を使用してそれらのオブジェクトに確実にアクセスすることはできません。

アプリケーションの外部から内部値を照会する方法が必要な場合は、必要な値を取得できる RMI サービス API の設定を検討できます。

別の方法 (何かをテストする必要がある場合) は、Java デバッグ API を介してプロセスに接続することです。

使用されている JRE の場所がわかっている場合は、java.exe の名前を変更し、Carl によってリストされたデバッグ オプションを追加して renamed_java.exe を呼び出す (C/C++) ラッパーを作成できます。

別の可能性.jarとして、アプリケーションのファイルにクラスを追加または更新することがあります。これを行うのにソースは必要ありません。

トム、特にその動作を難読化しようとするアプリケーションをリバース エンジニアリングしようとしているのですか? もしそうなら、メーカーに連絡して、あなたが達成しようとしていることについて彼らがどのような可能性を見ているかを尋ねると、さらに前進するかもしれません?

于 2010-01-07T11:03:19.377 に答える
2

YourKitを見てください。CPU、メモリ、スレッドをライブで監視し、必要なときにいつでもダンプを生成できます。さまざまなメモリ ダンプを比較して、追加/削除されたオブジェクトを表示することもできます。

無料ではありませんが、15 日間 (または 30 日間?) の完全に機能する評価期間があります。無料が問題にならないのであれば、間違いなく優れたツールです。

于 2010-01-07T11:05:56.270 に答える
2

良い出発点は、jpsJava jstat6 で追加されたツールです (と思います)。jps各アプリケーションの pid とメイン クラスを提供します。jstatプロセスの詳細を教えてください

于 2010-01-07T11:07:45.990 に答える
2

VisualVM と同じように、JVM への独自の JMX 接続を作成することで、ヒープ ダンプを簡単に生成できます。ヒープダンプの分析は非常に可能です (データはそこにあり、JVM から完全に切断されているため、gc からの干渉はありません)。

ただし、探しているのが非常に具体的なシナリオでない限り、ヒープダンプをMATに渡して、そこで使用する適切なワークフローを見つけたほうがよいでしょう。

編集:この特定のケースでは、何らかの特定の API を作成して、外部から値にアクセスすることをお勧めします (JMX を使用して値を MBean として公開することもできます)。いくつかの値を監視するだけの場合、ヒープ ダンプを取得するのは大変な作業です。

Edit2:あなたの編集に基づいて、JMX を介して独自の MBean を公開することで本当に利益が得られるように思えます。私は会議に出馬しなければなりませんが、私が留守の間に他の誰かがそれをしない限り、後であなたにいくつかの指針を与えることを忘れないようにします. これの編集または新しい投稿のいずれかで。

于 2010-01-07T11:08:36.300 に答える
1

Java アプリケーションの実行中に特定のオブジェクトの値をポーリングする場合は、ヒープ ダンプを使用するよりも、 JMXを使用する方がより適切で効率的な方法であることに気付くでしょう。JMX を使用すると、どの値を公開するかを定義し、VisualVM や JConsole などのツールを使用して実行時にそれらを表示できます。

于 2010-01-07T11:06:48.407 に答える