121

私は何度もメモリリークに遭遇しました。通常、私がmalloc明日がないように過ごしているとき、またはFILE *汚れた洗濯物のようにぶら下がっているとき。私は一般的に、少なくともプログラムが終了したときにすべてのメモリがクリーンアップされると想定しています(必死に願っています)。プログラムの終了時にリークしたメモリが収集されない、またはクラッシュする状況はありますか?

答えが言語ごとに大きく異なる場合は、C(++)に焦点を当てましょう。

「明日がないように」、「ぶら下がっている...汚れた洗濯物のように」というフレーズの双曲線的な用法に注意してください。安全でない** mallocingは、愛する人を傷つける可能性があります。また、汚れた洗濯物にはご注意ください。

4

9 に答える 9

116

いいえ。オペレーティングシステムは、プロセスが終了するときに、プロセスが保持しているすべてのリソースを解放します。

これは、オペレーティングシステムが維持するすべてのリソース(メモリ、開いているファイル、ネットワーク接続、ウィンドウハンドルなど)に適用されます。

とはいえ、プログラムがオペレーティングシステムのない組み込みシステムで実行されている場合、または非常に単純なオペレーティングシステムやバグのあるオペレーティングシステムで実行されている場合、メモリは再起動するまで使用できない可能性があります。しかし、もしあなたがそのような状況にあったなら、あなたはおそらくこの質問をすることはないでしょう。

オペレーティングシステムは、特定のリソースを解放するのに長い時間がかかる場合があります。たとえば、ネットワークサーバーが接続を受け入れるために使用するTCPポートは、プログラムによって適切に閉じられている場合でも、解放されるまでに数分かかる場合があります。ネットワーク化されたプログラムは、データベースオブジェクトなどのリモートリソースを保持する場合もあります。リモートシステムは、ネットワーク接続が失われたときにこれらのリソースを解放する必要がありますが、ローカルオペレーティングシステムよりもさらに時間がかかる場合があります。

于 2013-03-17T23:00:25.740 に答える
48

mallocC標準では、プログラムの終了時にによって割り当てられたメモリが解放されることは指定されていません。これはオペレーティングシステムによって行われ、すべてのOS(通常は組み込みの世界にあります)がプログラムの終了時にメモリを解放するわけではありません。

于 2013-03-17T23:01:17.627 に答える
29

すべての回答が最新のOSに関する質問のほとんどの側面をカバーしているため、歴史的に、DOSの世界でプログラミングしたことがある場合は言及する価値のあるものがあります。Terminant and Stay Resident(TSR)プログラムは通常、システムに制御を戻しますが、ソフトウェア/ハードウェア割り込みによって復活する可能性のあるメモリに常駐します。これらのOSで作業しているときに、「メモリ不足です。TSRの一部をアンロードしてみてください」などのメッセージが表示されるのは正常でした。

したがって、技術的にはプログラムは終了しますが、プログラムはまだメモリ上にあるため、プログラムをアンロードしない限り、メモリリークは解放されません。

したがって、バグがあるため、または組み込みOSがそうするように設計されているために、OSがメモリを再利用しないことを除けば、これは別のケースと見なすことができます。

もう1つの例を覚えています。主にIBMメインフレーム上で実行されるトランザクションサーバーであるCustomerInformationControl System(CICS)は、疑似会話型です。実行されると、ユーザーが入力したデータを処理し、ユーザー用に別のデータセットを生成し、ユーザー端末ノードに転送して終了します。アテンションキーをアクティブにすると、別のデータセットを処理するために再び復活します。動作方法が技術的には、CICSトランザクションサーバーをリサイクルしない限り、OSは終了したCICSプログラムからメモリを再利用しません。

于 2013-03-18T03:22:37.940 に答える
8

他の人が言っているように、ほとんどのオペレーティングシステムは、プロセスの終了時に割り当てられたメモリ(およびおそらくネットワークソケット、ファイルハンドルなどの他のリソース)を再利用します。

そうは言っても、(raw malloc / freeの代わりに)new / deleteを処理するときに、メモリだけが心配する必要があるわけではないかもしれません。newで割り当てられたメモリは再利用される可能性がありますが、オブジェクトのデストラクタで実行される可能性のあることは発生しません。おそらく、あるクラスのデストラクタは、破棄時に番兵の値をファイルに書き込みます。プロセスが終了したばかりの場合、ファイルハンドルがフラッシュされ、メモリが再利用される可能性がありますが、その番兵の値は書き込まれません。

話の教訓は、常に自分の後に片付けます。物事をぶら下げさせないでください。後のOSのクリーンアップに依存しないでください。自分の後で片付けなさい。

于 2013-03-18T00:53:10.173 に答える
7

これは、言語よりもオペレーティングシステムに依存する可能性が高くなります。最終的には、どの言語のどのプログラムでも、オペレーティングシステムからメモリを取得します。

プログラムが終了/クラッシュしたときにメモリをリサイクルしないオペレーティングシステムについて聞いたことがありません。したがって、プログラムに割り当てる必要のあるメモリの上限がある場合は、割り当てるだけで解放しないことは完全に合理的です。

于 2013-03-17T23:02:10.033 に答える
5

プログラムが別のプログラムのアドレス空間にロードされる動的コンポーネント(「プラグイン」)に変換された場合、適切なメモリ管理を備えたオペレーティングシステムであっても、問題が発生します。コードが機能の劣るシステムに移植されることを考える必要さえありません。

一方、すべてのメモリを解放すると、プログラムのクリーンアップのパフォーマンスに影響を与える可能性があります。

私が取り組んでいた1つのプログラム、特定のテストケースでは、すべての動的メモリのグラフを繰り返し処理し、プログラムを1つずつ解放していたため、プログラムが終了するまでに30秒以上かかりました。

合理的な解決策は、そこに機能を持たせてテストケースでカバーすることですが、アプリケーションがすぐに終了するように、本番コードではオフにします。

于 2013-03-18T01:32:20.590 に答える
5

タイトルに値するすべてのオペレーティングシステムは、終了後に行われたプロセスの混乱をクリーンアップします。しかし、常に予期しないイベントが発生します。何らかの理由でアクセスが拒否され、一部の貧しいプログラマーがその可能性を予測しなかったため、少し後で再試行しない場合はどうでしょうか。メモリリークがミッションクリティカルである場合は、自分自身をクリーンアップする方が常に安全です。それ以外の場合は、IMOの努力に費用がかかる場合、その努力の価値はありません。

編集:ループのように、メモリリークが蓄積する場所にある場合は、メモリリークをクリーンアップする必要があります。私が話すメモリリークは、プログラムの過程全体で一定の時間で蓄積するものです。他の種類のリークがある場合は、遅かれ早かれ深刻な問題になる可能性があります。

技術的には、リークがメモリの「複雑さ」である場合、O(1)はほとんどの場合問題なく、O(logn)はすでに不快(場合によっては致命的)であり、O(N)+は耐えられません。

于 2013-03-17T23:18:34.473 に答える
3

POSIX準拠システムの共有メモリは、shm_unlinkが呼び出されるか、システムが再起動されるまで存続します。

于 2013-03-20T08:12:18.703 に答える
2

プロセス間通信を使用している場合、プロトコルによっては、他のプロセスが完了せず、リソースを消費する可能性があります。

例を挙げると、私はかつてJavaでPDFプリンターへの印刷を試していましたが、プリンタージョブの途中でJVMを終了しましたが、PDFスプーリングプロセスはアクティブなままであり、タスクマネージャーで強制終了する必要がありました。印刷を再試行してください。

于 2013-03-18T11:01:02.163 に答える