自分で行うJavaプロファイリング

前回のAppication Developer Daysカンファレンスで、 Roman Elizarovelizarov )がプロファイル方法、つまり Javaベースのアプリケーションのパフォーマンスを調査するために、特別なツールを使用せずに、ベンダースタイルまたはオープンソースであるかどうかにかかわらず、JVMに組み込まれているあまり知られていない機能(スレッドダンプ、Javaエージェント、バイトコード操作)を使用し、プロファイリングを迅速かつ効率的に実装できることがわかりました戦闘システムでも常に実行できます。 ビデオレポートを以下に示します(ここでは不器用ですが、1280x720であり、すべてが完全に読み取り可能です)。



しかし、ビデオとスライドから私が編集した、カットの下にあるイラスト入りの記事の転写の70Kテキストを見てみることもお勧めします。

DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf 本日、「Javaでプロファイリングを自分で行う」というレポートを作成します。 スライドは英語で、レポートはロシア語で作成します。 非常に多くのスライドがありますが、それほど時間はありません。そのため、いくつかの質問をすぐにスキップし、質問のために最後にもっと時間を残してみてください。 原則として、突然何かを尋ねたり明確にしたり、あるいは私をさえぎりたいと思っても恥ずかしがらないでください。 私が伝えたいことを単に伝えるよりも、あなたが興味を持っているものをより詳細に説明した方が良いでしょう。



レポートは実際の経験に基づいており、10年以上にわたり、1秒あたり数百万の見積もり、何万人ものユーザーがオンラインで、大量のデータを扱う非常に負荷の高い複雑な金融アプリケーションを作成してきました。アプリケーションのプロファイリング。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf アプリケーションのプロファイリングは最適化の必然的な要素であり、プロファイリングなしの最適化は不可能です。 プロファイルを作成し、ボトルネックを見つけ、最適化プロファイルを作成します。これは一定のサイクルです。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf レポートが「Do It Yourself Java Profiler」と呼ばれるのはなぜですか、なぜ自分で何かをするのですか? プロファイリングを支援する既製のツールが多数あります-実際にはプロファイラーと同様のツールです。



しかし、実際には、まず、サードパーティのツールに問題がある可能性があります。 単に何らかの理由で-信頼性またはセキュリティは、ある種の生活環境でサードパーティのツールを実行できない場合があります。 そして残念なことに、テストプラットフォームだけでなく、ライブプラットフォームでもプロファイリングを行うことが必要になることがよくあります。常に負荷の高いプラットフォームでは、システムの同一のコピーを作成して同じ負荷で実行する機会とリソースがあります。 また、多くのボトルネックは、非常に特定の条件下でのみ、高負荷の下でのみ明らかにできます。 システムが正常に動作していないことがわかりますが、その理由はわかりません。 そのためにどのような負荷パターンを作成する必要がありますか。その結果、問題が明らかになります。したがって、多くの場合、稼働中のシステムのプロファイルを作成する必要があります。



金融アプリケーションを作成するとき、システムの信頼性を確保するタスクがまだあります。 そして、私たちは「銀行」をしません。そこでは、主なことはあなたのお金を失うことではありませんが、何時間も利用できないかもしれません。 システムの可用性が常に24×7であるオンライン取引用の仲介システムを作成します。これはその重要な品質の1つであり、決して低下することはありません。



そして、業界全体が規制されており、実際のシステムでサードパーティ製品を使用できない場合があることも既に述べました。



しかし、ツールはしばしば不透明です。 はい、「何」を説明するドキュメントがありますが、彼がこれらの結果をどのように取得するかについては説明していません。



そして、ツールがオープンソースであっても、何も変更しません。このコードがたくさんあるので、それを理解するのに多くの時間を費やすことになります。 ツールを習得する必要があります。もちろん、自分で何かをすることの方がはるかに楽しいです。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf 学習の問題は何ですか? 当然、何らかのツールを頻繁に使用する場合は、学ぶ価値があります。 好きな開発環境で毎日プログラミングすれば、それを広く知っています。もちろん、この知識は100倍の成果をもたらします。



また、たとえば月に1回、パフォーマンスバグのプロファイリングを行う必要があるなど、月に1回何かを行う必要がある場合、適切なツールを学習することで成果を上げることはできません。 もちろん、ツールが何倍も速く問題を解決する状況がない場合。



自分の手で何かをすることで、知識を再利用できます。 たとえば、プログラミング言語やツールの知識がある場合、新しいツールを学習するのではなく、既存のツールを学習することで、それらを深め、拡張し、明確にすることができます。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf Javaについてレポートする理由 まあ、私たちの会社のプログラムはJavaだけでなく、TIOBEインデックスによる2001年の主要言語であり、エンタープライズアプリケーションに最適です。 また、この特定の講義では、Javaは仮想マシンで動作するマネージ言語であり、Javaでのプロファイリングは非常に簡単であるため、一般的に素晴らしいです。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf まず、Javaでコードを作成して、多くのプロファイリングの問題を解決する方法について説明します。 使用できるJavaマシンの機能について説明し、バイトコード操作などの手法について説明します。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf 今日は、CPUとメモリの両方のプロファイリングを見ていきます。 さまざまなテクニックについてお話します。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf CPUプロファイリング。 最も簡単な方法は、単につかんでプログラムすることです。 プログラムのどこで、どれだけ、何で、時間がかかり、何回呼び出されるかを把握する必要がある場合、最も簡単な方法は次のとおりです。ツールは不要で、コードを数行書くだけです。



Javaには、現在の時刻を返す「currentTimeMillis」という素晴らしい機能があります。 ある場所でそれを測定し、別の場所でそれを測定してから、これが行われた回数、合計時間、最小時間と最大時間などを計算できます。 最も簡単な方法。 最大限のシンプルさと初歩的なDIY。



奇妙なことに、実際には、この方法はうまく機能し、多くの利点をもたらします-高速、便利、効率的だからです。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf この方法はいつうまく機能しますか? これはビジネスメソッドに最適です。ビジネスメソッドは大きく、あまり呼び出されないため、何かについて測定する必要があります。 さらに、このコードを書いたのは、あなたが書いたからです-それはあなたのアプリケーションの一部と機能の一部になります。 多かれ少なかれ、現代の大規模なアプリケーションには、管理インターフェイス、統計などが含まれています...そして一般に、アプリケーションのパフォーマンスは、アプリケーションの機能の一部として、アプリケーション自体が表示されることを頻繁に見たい3つのものの1つです



この意味で、アプリケーション自体をプロファイルするようにプログラムすることは論理的なステップです。 アプリケーションの機能を強化すると、アプリケーションのプロファイリングがその機能の一部になります。 特に、この方法でエンドユーザーが呼び出すビジネスメソッドに定義を配置すると、この情報はエンドユーザーにとっても意味のあるものになります。 何回呼び出されたか、どのメソッドが呼び出されたか、どれだけ時間がかかったかなど。 この場合、このアプローチで収集する情報は完全に管理下にあります。 コール数、最小時間、最大時間、平均カウントを測定でき、ランタイムの分布のヒストグラムを作成し、中央値とパーセンタイルをカウントできます。 この例のように、コード内のさまざまな実行パスをさまざまな方法で追跡できます。この例では、話をしながら何とかしましたが、実行パスに応じて、クエリ結果がキャッシュに入れられた頻度と時間それには、要求がデータベースにクロールされる頻度と、その所要時間がかかりました。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf これは、このコードを自分で記述し、統計を収集し、アプリケーションに自分を埋め込む場合に可能です。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf さらに、あなたにとって、プロファイリング最適化サイクルに関与する人として、あなたはこの情報を使用します-あなたのアプリケーションで何が起こりますか? この情報は常にアプリケーション内にあり、コードは稼働中のシステムで実行されます。 不幸な日がありました。システムがそのように機能しなかったので、ログの統計を調べたり、把握したりできます。



すばらしいテクニックです。サードパーティのツールはなく、Javaのほんの少しのコードです。
メソッドが短く、より頻繁に呼び出される場合はどうすればよいですか?



実際には、「currentTimeMillis」メソッドは高速ではなく、ミリ秒単位でしか測定されないため、このような直接メソッドはもはや適切ではありません。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf 呼び出し数のみを測定する必要がある場合は、Javaクラス「AtomicLong」を使用してこれをすばやく実行できます。 これにより、パフォーマンスに最小限の貢献をすることで、関心のあるメソッドの呼び出し回数を計算できます。 これは、アプリケーション自体の動作を大きく歪めることなく、1秒あたり数万件の呼び出しまで機能します。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf それでもランタイムを測定する必要がある場合はどうなりますか? 短いメソッドの実行時間の測定は非常に複雑なトピックです。 Javaには「systemNanoTime」メソッドがあるという事実にもかかわらず、標準のメソッドでは解決できません。これらの問題は解決せず、それ自体で遅く、それで高速なものを測定することは困難です。



唯一の実際の解決策は、ネイティブコードを使用することです。x86プロセッサには、プロセッサのクロックサイクル数のカウンタを返すような素晴らしい命令rdtscがあります。 それへの直接アクセスはありません;「rdtsc」を呼び出すCの単一行メソッドを記述し、それをJavaコードにリンクしてJavaから呼び出すことができます。 この呼び出しには100サイクルかかります。1000サイクルまたは2サイクルかかるコードを測定する必要がある場合は、各マシンサイクルを最適化し、「プラスまたはマイナス」、「高速、低速」を理解する必要があります。 「仕事の仕方。 すべてのメジャーを最適化する必要がある場合、これは非常にまれなケースです。



ほとんどの場合、短いコードの一部、より頻繁に呼び出されるコードに関しては、「サンプリング」と呼ばれる別のアプローチを使用します。 何回、何が呼び出されるかを正確に測定する代わりに、プログラムの実行を定期的に分析し、任意の時点で、たとえば1秒に1回、10秒に1回など、プログラムの実行場所を確認します DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf 実行が行われる場所と、プログラムが頻繁に見つかる場所を確認します。 プログラムにすべてを費やしている行、またはその時間の少なくとも90%、たとえばあるサイクルがあり、そこに深さのある行がある場合、おそらく実行を停止すると、この行でキャッチします。



プログラム内のこのような場所は「ホットスポット」と呼ばれます。 これは常に最適化の優れた候補です。 これはすごい-すべてのスレッドのダンプを取得するための「スレッドダンプ」と呼ばれる組み込み関数があります。 Windowsでは、コンソールでCTRL-Breakを押すことで行われます。Linuxおよび他のUnixでは、これは3番目のシグナル「kill -3」コマンドを送信することで行われます。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf この場合、Javaマシンはコンソール上のすべてのスレッドのステータスの詳細な説明を表示します。 そして、コードに本当にホットスポットがある場合、ほとんどの場合、そこにプログラムがあります。 したがって、コードのパフォーマンスに問題がある場合、プロファイラーを実行する必要はありません。何もする必要はありません。 速度が低下することを確認し、少なくとも1つのスレッドダンプを作成して確認します。 プログラムが常に費やしているホットスポットが1つある場合、スレッドダンプになり、サードパーティの追加ツールを使用せずに、この行がお気に入りの開発環境に表示されます。 このコードを見て、勉強し、最適化してください-頻繁に呼び出されるか、動作が遅いので、結果報告、最適化、またはさらなるプロファイリングがあります。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf また、最新のJavaマシンには素晴らしいユーティリティ「jstack」があり、プロセスIDを渡すことができ、出力でスレッドダンプを取得できます。



複数のスレッドダンプを実行し、スレッドダンプを実行します。 最初のものがキャッチされない場合は、さらに2、3を見てください。 プログラムは、ホットスポットで時間の100%を費やすのではなく、50%を費やすかもしれません。 いくつかのスレッドダンプを作成したら、明らかにこれらのポイントのうち少なくとも1つをホットスポットからコードから取り出し、コードを見つけた場所を目で見てください。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf このアイデアはさらに発展させることができます。 Javaマシンを起動することにより、その出力をファイルにリダイレクトし、3秒ごとにスレッドダンプを行うスクリプトを実行できます。 これは、生きているシステムで非常に冷静に行うことができます。 スレッドダンプの収集自体は非常に高速な手順であるため、非常に多数のスレッドがある場合でも100ミリ秒かかります。



また、Javaで記述する場合、システムはリアルタイムではなく、ナノ秒は重要ではありません。これは、すでに定期的にガベージコレクションなどが発生しているためです。 つまり 100ミリ秒の災害に対して不必要に眠りに落ちるシステムを作成しません。



そして私たちの金融分野でさえ、私たちが書いているシステムのほとんど、人々のために書いています、人々は彼らと一緒に働いています、はい、毎秒何百万もの引用があります、はい、ロボットがありますこれらの引用は、プラスまたはマイナス100ミリ秒で目で気付かない人によって監視されます。 200ミリ秒の間ブレーキがかかっている場合、人は気づくでしょう。すでに人にとって顕著な遅延ですが、100ミリ秒はそうではありません。



したがって、余分な100ミリ秒を心配することはできず、3秒ごとにスレッドダンプを行うことで、稼働中のシステムであっても完全に安全に実行できます。 同時に、スレッドダンプはJavaマシンの一部であり、十分にテストされています。Javaマシンでスレッドダンプを実行しようとすると、悪い結果が発生することは、これまで見たことがありません。



つまり これは、生活システムと作業システムをプロファイリングするための完全に安全なツールです。 その後、スレッドダンプファイルを受け取ったら、それを目で見てみるか、少なくとも統計情報を分析し、少なくとも愚かなことを考慮して、どのメソッドが何回出現したか、スレッドの状態を確認するコードの簡単な部分を書くことができます。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf さらに、標準のプロファイリングツールがJavaマシン(「実行可能」)が表示するストリームの状態を実際に見る場合、実際には、プログラムはデータベースで多く動作し、多くの場合、外部...ネットワークを使用すると、コードはネットワーク経由でデータを受信することを期待できますが、Javaマシンはそれを「実行可能」と見なし、何も理解できません-あなたの本当の方法とネットワークからのデータを待っています。 一方、自分でスタックを分析すると、プログラムが何をするのか、これがデータベースへの呼び出しであること、スタック上のこのメソッドがデータベースにログインしていることを意味することを書くことができます。データベースに費やす時間の割合など。 この方法は実際にはCPUを消費しないことを知っているかもしれませんが、Javaマシンは「実行可能」であると考えています。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf さらに、スレッドダンプはアプリケーションに統合できます。Javaには素晴らしい方法があります
  Thread.getAllStackTraces 
これにより、スタックトレースに関する情報をプログラムで取得できます。



したがって、プロファイリングをこのアプリケーションの機能部分として統合し、組み込みのプロファイリングを使用してアプリケーションを顧客に配布できます。 したがって、アプリケーションを改善するために分析できる情報の一定の流れが得られます。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf しかし、問題があります。 実際、Javaマシンにスレッドダンプを作成するように要求すると、プロセスを停止してスタックを作成するだけでなく、Javaマシンが次の安全な場所で停止する必要があるというフラグが含まれます。 「安全な場所」とは、コードに従ってコンパイラが配置する特別な場所で、プログラムが特定の状態にある、レジスタがあることが明らかである、実行ポイントが明確であるなどです。 逆遷移やサイクルがない連続したコードを使用すると、「安全点」がまったくない場合があります。 さらに、メソッド呼び出しがインラインでホットスポットになることは問題ではなく、セーブポイントもありません。



したがって、スレッドダンプに行がある場合、これがコードのホットラインであることを意味するものではなく、単にホットポイントに最も近いセーブポイントであることを意味します。 「CTRL-BREAK」を押すと、Javaはすべてのスレッドを「最も近いセーブポイントで停止」するようにストリーミングし、Javaマシンは停止したときにのみ、実行中の状態を分析します。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf 次に、これがどのように行われたかのメモリのプロファイリングに移りましょう。



まず、Javaマシンにはすぐに使えるすばらしい機能があります。 メモリーが何でいっぱいなのか、どのオブジェクトがどのくらいのメモリーを占有しているかのヒストグラムを表示する優れたjmapツールがあります。 これは、何が起こっているのか、メモリがどのように詰まっているのかを概観するのに最適なツールです。



繰り返しますが、プログラムのプロファイルを作成したことがない場合、ほとんどの場合、すぐに問題が見つかり、メモリ使用量をさらに最適化するための食料が手に入ります。 DIY Javaプログラミング(Roman Elizarov、ADD-2011).pdf 問題は、この方法で、現在使用されていないものも含めて、すべてのオブジェクトに関する情報をゴミ箱に入れることです。



したがって、jmapには特別なオプション「ライブ」があります。これは、ヒストグラムを作成する前にガベージコレクションを行い、使用済みのオブジェクトのみを残し、その後ヒストグラムを作成します。



問題は、すでにこのオプションでは、10ギガバイトのメモリで動作するシステムのガベージコレクションに数十から2秒かかるため、多くのギガバイトのメモリで動作する大規模なライブシステムのプロファイルを作成できないことです。システムは、システムが3秒以上応答しない有限の人々と連携して動作します。実際、人と一緒に働く生命システムを1秒以上停止することは不可能です。たとえ1秒でも人にはすでに気づいていますが、まだ災害ではありませんが、10秒間停止するツールを接続すると、災害になります。したがって、多くの場合、それらのオブジェクトのjmapのリビングシステムに満足する必要があり、一般に、それがゴミであるかどうかは関係ありません。

DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdfJavaマシンの追加オプションを知ることも役立ちます。たとえば、スレッドダンプ→「PrintClassHistogram」を実行すると、Javaマシンがクラスヒストグラムを印刷するように要求される場合があります。



Javaマシンにメモリを使用して状態をディスクに書き込むように依頼できます。これは非常に便利です。通常、人々は何らかの理由でメモリ消費が終了したときにのみメモリ消費の最適化を開始します。すべてが問題ない場合、プロファイリングに従事する人はいませんが、プログラムがメモリ不足になるとクラッシュし、そのように最適化する方法を考え始めます。したがって、常にこのオプションを有効にしておくと便利です。その後、悪い場合には、Javaマシンがバイナリダンプを書き込みます。バイナリダンプは、ライブシステム上ではなく、ツールを使用して後で分析できます。同時に、このダンプは、「-dump」オプションを使用して、同じjmapでJavaマシンからいつでも取得できますが、これもJavaマシンを長時間停止するため、ライブシステムにはほとんどアクセスできません。する。



聴衆からのコメント:この「HeapDumpOutOfMemory」は、メモリがすでに不足している場合に最適化されるというプロパティがあります。



はい、もちろんです。「HeapDumpOutOfMemory」は非常に便利なオプションであり、「-XX」ですが、これらのオプションを恐れてはいけません。ただし、この「XX」はメガスペシャリティを強調しますが、これらは実験的なオプションではなく、Javaマシンの通常の本番オプションであり、安定性、信頼性、ライブの実際のシステムで使用できます。



これらは実験的なオプションではありません! Javaマシンには明確な区分がありますが、実験的および非実験的オプションへの区分はXの数に依存しません。



聴衆からのコメント:ダンプはこのオプションを延期しない場合があります...



まあ、Javaマシンにもバグがあります、それはすべて依存しています...メモリが不足する理由はさまざまです。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdf残りの時間、つまりメモリ割り当てのプロファイルについて、非常に重要な点について説明します。



それは一つのことです-メモリが何であるか、あなたがそれを使用する方法。コードのどこかに一時メモリの過剰な割り当てがある場合、つまりあなたはそれを分離します...それで何かをします、このメソッドはそれを忘れて、ガベージに入り、ガベージコレクタがそれを拾いますそして、何度も何度もそれを行うと、プログラムはこれで動作するよりも遅くなります...しかし、Javaメモリマシンの割り当て操作は素晴らしく速く、速く動作するため、CPUプロファイラでこのコードの場所は見つかりませんJavaでは、メモリの割り当ては単一のポインタをインクリメントするのに簡単なので、非管理言語であるC / C ++よりも。それだけですこれらはいくつかの組み立て手順であり、すべてが非常に迅速に行われます。すでにゼロにリセットされており、すべてがすでに割り当てられ準備されています。コードのホットスポットを分析する場合、今回は見つかりません。スレッドダンプやプロファイラーで、ホットスポットであることは決して表示されません。それはすべてあなたと一緒ですが、あなたの時間を使い果たしてしまいます、なぜあなたのアプリケーションですか?そのため、ガベージコレクタはこのガベージを収集するために時間を費やします。したがって、アプリケーションがガベージコレクションに費やす時間の割合を調べてください。



これは便利なオプション「-verbose:gc」、「+ PrintGC」、「+ PrintGCDetails」であり、アプリケーションがガベージコレクションに費やす時間を把握できます。時間のかなりの部分がガベージコレクションに費やされていることがわかった場合、プログラムのどこかに多くのメモリを割り当てると、この場所が見つからないため、誰がメモリを割り当てるかを探す必要があります。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdf検索方法Javaマシンには、「-Xaprof」キーというメソッドが組み込まれています。残念ながら、プロセスの最後にのみ、いわゆる割り当てプロファイルが表示されます。これは、メモリの内容についてではなく、割り当てられたオブジェクトの統計→どのオブジェクトとどのくらいの頻度で割り当てられたかを示します。



これが本当に頻繁に発生する場合は、非常に頻繁に目立つ一時的なクラスがどこかにあることがわかります。すぐにaprofを作成してください-すぐに問題が見つかるかもしれません。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdfしかし、事実ではありません。多数の文字配列、一部の文字列、または何かの選択が表示されることが判明する場合がありますが、どこにあるかは明確ではありません。



疑いがあるかもしれないことは明らかです-どこで。おそらく最近の変更が行われる可能性があります。最終的に、atomis longでコードを変更する同じ手法を使用して、メモリが頻繁に割り当てられる場所に追加し、この場所で割り当てが行われる回数をカウントします-統計を見て、疑わしい場所を自分で開始して見つけることができます。



しかし、これがどこで起こっているのかわからない場合はどうでしょうか?さて、メモリが割り当てられているすべての場所で、どこかで統計のコレクションを追加する必要があります。アスペクト指向プログラミング、またはバイトコード操作の直接使用は、この種のタスクに最適です。



残りの時間は、バイトコード操作手法に焦点を当てます。これは、「今、この場所で、これがすべての場所で発生する回数を計算したい」などの問題を解決するのにちょうどいい方法です。何らかの理由で多くのint配列を割り当てるまさにその場所を見つけるためのコード。」つまりそれらの多くが際立っていることがわかりますが、私はどこで見つけたいだけです。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdfバイトコード操作を使用すると、これらの問題を解決できるだけでなく、コンパイル後に、機能しないコードに変更を加えることができます。したがって、ビジネスロジックからプロファイリングを分解するこの方法。冒頭で、プロファイリングが機能の論理的な部分であることが多いと言った場合、それを必要としない場合、問題を見つけて解決する必要があり、何も残さない場合があります。この場合、バイトコード操作などの素晴らしいテクニックが適しています。



そして、これは、コードレイアウトのポストコンパイルとコードの両方で実行できます。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdf私が知っている最善の方法は、ASMライブラリObjectWebを使用することです。これは、バイトコードの操作が非常に簡単なオープンソースのライブラリであり、非常に高速です。アプリケーションのロード時間を遅くすることなく、コードをその場で操作できます。



ASMは非常に単純です。彼は.classファイルを読み取り、Visitorテンプレートを使用してバイトを「メソッドを見る」、「このクラスにそのようなフィールドを持つフィールドを見る」などの一連の呼び出しに変換するclass-readerというクラスを持っています。さらに。メソッドを見ると、MethodVisitorを使用して、そこにどんなバイトコードがあるかを報告します。



そして、反対に、クラスをバイトアレイに変換する「ClassWriter」などがありますが、これはJavaマシンに必要です。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdfたとえば、ASMの助けを借りて、配列のすべての割り当てを追跡するには...一般的に、これは基本的に行われます。いくつかのクラスを実行するだけです。アダプタクラスを定義する必要があります。アダプタクラスは、このメソッドで何が行われているのかを知るために、メソッドが表示され、オーバーラップし、独自のビジターメソッドを返すと通知されます。



そして、メソッド内で、配列割り当てのバイトコード(「NEWARRAY」)を持つ整数命令があることを彼に伝えると、その瞬間、彼は自分のバイトコードを上流に挿入する機会があります。そして、配列が割り当てられているすべての場所を追跡し、対応するバイトコードを変更しました。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdfさらに-これらの変更をオンザフライで行いたい場合の対処方法。



コンパイルされたクラスのセットがある場合、それは簡単です→このツールを処理したので、それだけです。



オンザフライでこれを行う必要がある場合は、Javaマシンに素晴らしいオプション-javaagentがあります。マニフェストでオプション「Premain-Class」を指定する特別なjarファイルを作成し、そこにクラスの名前を指定します。次に...特定のテンプレートによる「premain」メソッド。したがって、mainメソッドを使用してメインコードを実行する前であっても、制御を取得し、インターフェイスインスツルメンテーションへのポインタを取得します。このインターフェースは素晴らしいもので、Javaマシンのクラスをオンザフライで変更できます。これにより、Javaマシンがクラスをロードするたびに呼び出す独自のクラスファイルトランスフォーマーを配置できます。



そして、クラスを置き換えることができます。つまり実際に存在するクラスだけでなく、同じObjectWebASMを使用して、何かを分析し、変更し、それらをオンザフライで置き換える...選択したオブジェクトのサイズを確認できます。



特定の問題を解決する必要がある場合に、ひざのプロファイリングを行うためのすばらしいツール。DIY Javaプロファイリング(Roman Elizarov、ADD-2011).pdf結論として、プロファイリングの問題を解決したり、ツールを所有したりするのに、バイトコード、Javaマシンのオプション、標準のJavaライブラリ(同じjavalangツール)を知っていれば十分です。これにより、発生する膨大な数の特定の問題を解決できます。当社では10年間、特定のプロファイラーでは解決できない特定の問題ではない問題を解決するいくつかの自社開発ツールを開発してきました。重量がありますが、スレッドダンプを分析して統計情報を提供するシンプルなツールであるという事実から始まりますが、それでもツールとは言えないシンプルなユーティリティです。統計を収集し、美しい方法で表示するいくつかのページの古典。非常に有用プロファイラをプロダクションシステムに接続する必要はなく、スレッドダンプを接続するだけです。



そして、私たち自身のメモリプロファイリングツールがあるという事実で終わりますが、これもまた小さいですが、どこに何が割り当てられているかを追跡するツールと呼ぶことは難しく、プログラムをほとんど減速させることなくこれを行います。さらに、商用プロファイラとオープンプロファイラの両方で、メモリ割り当てを追跡する方法も知っていますが、より複雑で普遍的な問題を解決しようとしています。彼らは、完全なスタックトレースでメモリ割り当てが発生する場所を見つけようとしています。これは長い時間で、かなり遅くなります。同じサンプリングを使用しないでください。常に収集されるわけではないため、すべての統計を受信するわけではありません。



ある種の妥協を行います。これは、対象分野では必要ありません。システムのパフォーマンスを分析するときに解決したいタスクがいくつかあります。



次に、質問に回答します(30:06からの質問への回答)。


また、アプリケーション開発者の日からの他のトランスクリプトを視聴したり、トレント([2011][2010])を使用した過去の会議からすべてのビデオをダウンロードしたり、http経由でフォルダー全体をダウンロードしたりできます
免責事項:私はレポートの著者ではありません。私はこの会議のPC議長であり、ビデオ編集者であり、トランスクリプトです。著者にはhabraaccountがありません。たぶん、あなたの質問にコメントするために彼を招待することができます。レポートの作成者であるエリザロフは、コメントを求められ、質問に答えます。また、著者の日記での議論



ところで、Elizarov会議で講演、ADD-2012のレポートで「データをキャッシュするための最速のハッシュを書きます。」



All Articles