私たちの仕事では、ddagentver。 5収集ツールとして、ホスティングサーバーのパフォーマンスインジケーターを収集して報告し、ddagentをある程度カスタマイズします。多くの機能を繰り返した後、実行時間が長いオンラインホスティングサーバーのバッチがメモリを大量に消費することがわかりました。問題のあるマシンのプロセスツリーの各ノードの占有率を分析すると、ddagent収集プロセスのメモリ占有率がまだ高いことがわかります。
次のような最も基本的なプロセス制御ツールについて学習します。
ループwhileループの条件付き判断の場合
ビジネスシステムの安定した運用を保証する監視コンポーネントとして、当然のことながら非常に深刻なメモリリークが発生するため、「トラブルシューティングの旅」を開始しました。
if-elif-else判断
分析
Pythonプログラムのメモリステータスを分析してエクスポートするためのツールはたくさんあります。ここでは、実行中のPythonプログラムにアタッチし、メモリスナップショットを生成し、現在どのオブジェクトタイプがどのくらいのメモリを占有しているかを確認し、それらを最大から最小に並べ替えることができるピラサイトを使用します。
コマンドは非常に単純です:pyrasite-memory-viewer <PID ,同时会生成一份快照文件: /tmp/pyrasite-<PID -objects.json。
実際の本番データを提供できないため、以下に記載されているすべてのデータは、テスト環境で12時間実行した後の問題のあるバージョンのサンプリングからのものです。
ピラサイトが提供するCuiビューでは、辞書タイプのオブジェクトインスタンスが最も多くのメモリを占有し、3.4 MBに達し、6621インスタンスであることがはっきりとわかります。
whileループ
whileループも一般的なループ方式です。この種のループは通常、ループ本体または条件付きの方法で終了します。それは無期限に続くことはできません。
漏えいに関しては、以下の事実と推測があります。
1つ以上の場所が空の辞書オブジェクトを作成し続け、それらを再利用できないため、メモリリークが発生し、メモリリークが時間の経過とともに増加します。インデックス収集ビジネスでは、リークは各収集プロセス中に発生する可能性があり、間隔の後に繰り返しトリガーされます。現在依存しているddagentバージョンに、カスタマイズプロセスにある可能性のある未解決の関連する問題があることはわかりません。で導入されたエラー
[[["... /embedded/lib/python2.7/threading.py",774,"__bootstrap","self.__bootstrap_inner()"],[".../embedded/lib/python2.7/threading.py",801,"__bootstrap_inner","self.run()"],[".../modules/monitor/bot/schedule.py",51,"run","task.run()"],[".../modules/monitor/bot/task.py",50,"run","super(RepeatTask, self).run()"],[".../modules/monitor/bot/task.py",18,"run","self.check()"],[".../modules/monitor/checks/collector.py",223,"wrapper","_check.run()"],[".../modules/monitor/checks/__init__.py",630,"run","self._roll_up_instance_metadata()"],[".../modules/monitor/checks/__init__.py",498,"_roll_up_instance_metadata","dict((k, v) for (k, v) in self._instance_metadata))"],[".../modules/monitor/tracer.py",33,"__init__","self.trace_info = traceback.extract_stack()"]],[[".../embedded/lib/python2.7/threading.py",774,"__bootstrap","self.__bootstrap_inner()"],[".../embedded/lib/python2.7/threading.py",801,"__bootstrap_inner","self.run()"],[".../modules/monitor/bot/schedule.py",51,"run","task.run()"],[".../modules/monitor/bot/task.py",50,"run","super(RepeatTask, self).run()"],[".../modules/monitor/bot/task.py",18,"run","self.check()"],[".../modules/monitor/checks/collector.py",223,"wrapper","_check.run()"],[".../modules/monitor/checks/__init__.py",630,"run","self._roll_up_instance_metadata()"],[".../modules/monitor/checks/__init__.py",498,"_roll_up_instance_metadata","dict((k, v) for (k, v) in self._instance_metadata))"],[".../modules/monitor/tracer.py",33,"__init__","self.trace_info = traceback.extract_stack()"]],[[".../embedded/lib/python2.7/threading.py",774,"__bootstrap","self.__bootstrap_inner()"],[".../embedded/lib/python2.7/threading.py",801,"__bootstrap_inner","self.run()"],[".../modules/monitor/bot/schedule.py",51,"run","task.run()"],[".../modules/monitor/bot/task.py",50,"run","super(RepeatTask, self).run()"],[".../modules/monitor/bot/task.py",18,"run","self.check()"],[".../modules/monitor/checks/collector.py",223,"wrapper","_check.run()"],[".../modules/monitor/checks/__init__.py",630,"run","self._roll_up_instance_metadata()"],[".../modules/monitor/checks/__init__.py",498,"_roll_up_instance_metadata","dict((k, v) for (k, v) in self._instance_metadata))"],[".../modules/monitor/tracer.py",33,"__init__","self.trace_info = traceback.extract_stack()"]],...
リプレイ
「設計レビューと仕様レビューで良い仕事をしている」や「実験段階で品質検査作業を強化する」などの古い決まり文句については言及していませんが、これも私たちの反省に値します。
メモリリークを完全に防止および制御することはほとんど不可能であり、rustのような安全なプログラミング言語では、プログラムがメモリをリークしないことを保証できません。
範囲外のアレイアクセス、解放されたメモリへのアクセスなど、メモリの不安定さを引き起こす多くの動作は、より厳密なプログラミングモデル(錆によって提案された所有権+ライフサイクルルールなど)やデータ競合の問題を定式化することで回避できます。
ただし、レース条件などのメモリリークを引き起こす動作では、開発者は開発コンポーネントをビジネスルールと組み合わせる必要があります。手動で更新する必要があるデータキューを想像してみてください。その結果、データをプッシュするときに呼び出すのを忘れていました。このメモリリークは、従来の検査ルールでは特定できません。
キーワード機能は、着信パラメータの場所と特定の使用法をより鮮明に説明することです。関数に4つまたは5つのパラメーターがあり、一度に渡されるパラメーターが多すぎる場合、人々を魅了することは困難です。 key = valueを使用して渡す場合。
総括する
このセクションの調査を通じて、コードフローを制御し、さまざまな条件下でさまざまなコードを実行する方法を学びました。 for / whileと関数の定義方法には、関数の戻り値とパラメーターの受け渡し方法、位置パラメーターの受け渡し、およびパラメーターを関数に渡すときのkey = valueパラメーターの受け渡しの2つの異なるループメソッドがあります。
以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。
Recommended Posts