2017-02-15 6 views
3

これは本当に醜い質問です。フォークでメモリリークを緩和する

私はループの中で、次のないC++プログラムがあります。

  • 待機JMSメッセージ
  • については、応答

私をJMSメッセージを送信します

  • いくつかのデータを計算しますプログラム( "Bob"と呼ぶ)はかなり重大なメモリリークを持っています。メモリリークは、他の人が書いた共有ライブラリにあります。私はこれを使用する必要がありますが、私がアクセスできないソースコードです。

    このメモリリークにより、ループの "いくつかのデータを計算する"フェーズでBobがクラッシュします。これは問題です。なぜなら、別のプログラムがBobの応答を待っていて、受信しなければ非常に怒ってしまうからです。

    さまざまな制限(X/Y問題です)のため、唯一実行可能な戦略は、ループ内で次のことを行うようにBobを変更することです:

    JMSメッセージ
  • ため
    • ウェイツが、それは場合は、「あまりにも多くの」メモリ
    • を使用しての危険にさらされますかどうかに応じて
    • 小切手を
    • は、JMSメッセージを送信し、いくつかのデータを計算しますので、フォークとエグゼクティブNotherの自身のコピー、そして優雅に

    を終了し、次のように私の質問は次のとおりです。

    たちは「あまり」のメモリを使用しているかどうかを検出するための最良の(信頼性ではなく、あまりにも非効率的な)方法は何ですか?私の現在の考えは、getrlimit(RLIMIT_AS) rlim_curgetrusage(RUSAGE_SELF) ru_maxrssと比較することです。あれは正しいですか?そうでない場合、より良い方法は何ですか? Bobはさまざまなホストマシン上のLinux VM内で実行されます。すべてのメモリ量は異なります。

  • +4

    "Calculates some data"フェーズでメモリリークが発生したと仮定して、別のプログラムにその部分をリファクタリングし、別のメモリ空間で実行するためにフォークアウトする方が理にかなっていますか?そうすれば、メモリ不足時にプログラムを再起動させるだけで問題を隠すのではなく、問題のコードを分離して、将来置き換えることが容易になります。それは単なる考えです。コードを見ることなく、それがあなたのために実行可能な選択肢であるかどうかは言えません。回避策として –

    +2

    。なぜ計算が終わるたびに終了せずに毎回プログラムを再起動するのですか? –

    +0

    ジーン、実行可能な極端に。厳密に必要なときに再起動するだけで、オーバーヘッドを減らすことが可能かどうか疑問に思っています。 – Arandur

    答えて

    1

    "データを計算する"段階でメモリリークが発生すると仮定すると、その部分を別のプログラムにリファクタリングしてフォークアウトして独自のプロセスで実行する方が理にかなっていると思います。そうすれば、メモリ不足時にプログラムを再起動させるだけで問題を隠すのではなく、問題のコードを分離して、将来置き換えることが容易になります。

    「一部のデータを計算する」の部分は、メインプログラムからの要求を待ち、必要なときに再起動する長期実行プロセスのいずれかでもよいし、(さらに単純でも)単なる完了プログラムでもよいそのデータを*argvに入力し、その結果をstdoutに送信します。その後、メインループは毎回フォークアウトして実行し、復帰時に結果を読み取ることができます。可能であれば私はもっと簡単なオプションを使うつもりですが、それはあなたのニーズが何であるかに依存します。

    0

    プログラム自体を再起動するか、「いくつかのデータを計算する」セクションを別のプロセスにフォークすると、いずれの場合もメモリ消費量を確認する必要があります。あなたがLinux上にいるので、これをチェックする簡単な方法は、関心のあるプロセスのPID番号を取得し、ファイル/proc/$PID/statmの内容を読むことです。 2番目の数字は常駐セットのサイズです。

    これらのprocファイルを読むことは、トップやhtopのようなツールがプロセスに関するデータを取得する方法です。 〜30バイトのメモリ内ファイルを定期的に読み取ってメモリリークをチェックしても、非効率的ではないとは言えません。

    漏れが定期的で、もう少し洗練されたものにしたい場合は、成長率を把握し、それに応じてチェック率を調整することもできます。

    関連する問題