他の言語で読む: English Español 中文
行ブレークポイントの設定、値のログ記録、式の評価方法を説明するデバッガー チュートリアルが多数存在します。この知識だけでもアプリケーションをデバッグするための多くのツールが提供されますが、実際のシナリオはもう少し複雑で、より高度なアプローチが必要になる場合があります。
この記事では、設計に関する事前知識がなくても、UI フリーズの原因となるコードを見つけて、欠陥のあるコードをリアルタイムで修正する方法を学びます。
フォローしたい場合は、まずこのリポジトリのクローンを作成してください: https://github.com/flounder4130/debugger-example
何らかのアクションを実行するとクラッシュする複雑なアプリケーションがあるとします。バグを再現する方法はわかっていますが、問題は、コードのどの部分がこの機能を担当しているのかがわからないことです。
このサンプル アプリでは、ボタン N をクリックするとスリープが発生します。ただし、このアクションを実行するコードを見つけるのはそれほど簡単ではありません:
デバッガーを使用してそれを見つける方法を見てみましょう。
メソッド ブレークポイントの行ブレークポイントに対する利点は、クラス階層全体にわたって使用できることです。これは私たちの場合にどのように役立ちますか?
サンプル プロジェクトを見ると、すべてのアクション クラスが単一のメソッド Perform() を使用して Action インターフェイスから派生していることがわかります。
このインターフェイス メソッドにメソッド ブレークポイントを設定すると、派生メソッドのいずれかが呼び出されるたびにアプリケーションが一時停止されます。メソッド ブレークポイントを設定するには、メソッドを宣言する行をクリックします。
デバッガー セッションを開始し、ボタン N をクリックします。アプリケーションは ActionImpl14 で一時停止されます。これで、このボタンに対応するコードがどこにあるかが分かりました。
この記事ではバグの発見に重点を置いていますが、この手法は、大規模なコードベースで何かがどのように動作するかを理解したい場合にも、多くの時間を節約できます。
メソッド ロック ポイントを使用したアプローチはうまく機能しますが、親インターフェイスについて何かを知っているという前提に基づいています。この仮定が間違っていたり、他の理由でこのアプローチを使用できない場合はどうなりますか?
そうですね、ブレークポイントがなくてもこれを行うことができます。 ボタン N をクリックし、アプリケーションがロックされている間に IntelliJ IDEA に移動します。メイン メニューから、実行 | を選択します。 アクションのデバッグ | プログラムを一時停止します.
アプリケーションが一時停止され、スレッドと変数 タブでスレッドの現在の状態を調べることができます。これにより、アプリケーションが現在何を行っているかがわかります。ロックされているため、ロック方法を特定し、呼び出しの場所まで追跡できます。
このアプローチには、従来のスレッド ダンプに比べていくつかの利点があります。これについては後ほど説明します。たとえば、変数に関する情報を便利な方法で提供し、さらにプログラムの実行を制御できるようにします。
注:プログラムの一時停止に関するその他のヒントとテクニックについては、「ブレークポイントを使用しないデバッグ」および「Debugger.godMode()」を参照してください。
最後に、スレッド ダンプを使用できます。これは厳密にはデバッガ機能ではありません。デバッガを使用しているかどうかに関係なく利用できます。
ボタン N をクリックします。アプリケーションがロックされている間に、IntelliJ IDEA に移動します。メイン メニューから、実行 | を選択します。 アクションのデバッグ | スレッド ダンプを取得.
左側で使用可能なスレッドを確認すると、AWT-EventQueue の下に問題の原因が表示されます。
スレッド ダンプの欠点は、スレッド ダンプが取得された時点でのプログラムの状態のスナップショットしか提供されないことです。スレッド ダンプを使用して変数を調べたり、プログラムの実行を制御したりすることはできません。
この例では、スレッド ダンプに頼る必要はありません。ただし、このテクニックは、デバッグ エージェントなしで起動されたアプリケーションをデバッグしようとする場合など、他の場合にも役立つ可能性があるため、それでも言及しておきたいと思いました。
デバッグ手法に関係なく、ActionImpl14 に到達します。このクラスでは、誰かが別のスレッドで作業を行うつもりでしたが、Thread.start() と、呼び出し元のコードと同じスレッドでコードを実行する Thread.run() を混同しました。
IntelliJ IDEA の静的アナライザーは、設計時にこれについて警告します。
負荷の高い作業 (この場合は大量のスリープ) を実行するメソッドが UI スレッドで呼び出され、メソッドが終了するまでブロックされます。そのため、ボタン N をクリックした後、しばらく UI で何もできなくなります。
バグの原因が判明したので、問題を修正しましょう。
プログラムを停止し、コードを再コンパイルして、再度実行することもできます。ただし、ちょっとした変更のためだけにアプリケーション全体を再折りたたみするのが必ずしも便利であるとは限りません。
賢い方法でこれをやりましょう。まず、提案されているクイックフィックスを使用してコードを修正します。
コードの準備ができたら、[実行] をクリックします。 アクションのデバッグ | 変更されたクラスを再ロードします。新しいコードが VM に到達したことを確認するメッセージが表示されます。
アプリに戻って確認してみましょう。 ボタン N をクリックしてもアプリがクラッシュしなくなりました。
ヒント: HotSwap には制限があることに注意してください。 HotSwap の拡張機能に興味がある場合は、DCEVM や JRebel などの高度なツールを検討してみるとよいでしょう。
推論といくつかのデバッガー機能を使用して、プロジェクト内で UI のフリーズを引き起こしているコードを特定することができました。その後、実際のプロジェクトでは時間のかかる再コンパイルや再デプロイに時間を無駄にすることなく、コードの修正に進みます。
ここで説明したテクニックがお役に立てば幸いです。ご意見をお聞かせください。
デバッグとプロファイリングに関連する他の記事に興味がある場合は、私の他の記事をいくつかチェックしてください:
以上が非アクティブなアプリケーションのデバッグの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。