6

組み込み Linux システムで一晩メモリ テストを実行しています。vmstat を使用すると、時間の経過とともに空きメモリが着実に減少することがわかりました。procfsのいくつかのsmaps分析によると、1 つのプロセスのヒープはほぼ同じ割合で増加します。私はメモリ リークを疑い、コード内でとが定期的に使用されている場所をいくつか見つけました。ただし、呼び出しが一致しない呼び出しは表示されませんでした。newdeletenewdelete

メモリテストを再度実行し、今朝、次の呼び出しでメモリキャッシュをクリアしました

echo 3 > /proc/sys/vm/drop_caches

vmstat にリストされている空きメモリは、テストが開始されたときの値に近い値になりました。

カーネルは定期的に未使用のヒープ ページを再利用しますか? もしそうなら、これが行われる上記以外の時間はありますか? おそらく、空きメモリが特定のしきい値を下回ったときですか?

4

4 に答える 4

5

他の人が言ったように、メモリをカーネルに戻すのはプロセスの義務です。

通常、メモリを割り当てるには2つの方法があります。特定のサイズを超えるメモリブロックの場合malloc()newメモリはOSから割り当てられ、mmap()解放されるとすぐに有効になります。sbrk境界線を上にシフトしてプロセスのデータ領域を増やすことにより、より小さなブロックが割り当てられます。このメモリは、特定のサイズを超えるブロックがそのセグメントの最後で解放された場合にのみ解放されます。

例:(擬似コード、C ++についてはよくわかりません)

a = new char[1000];
b = new char[1000];

メモリマップ:

---------------+---+---+
end of program | a | b |
---------------+---+---+

今解放aすると、真ん中に穴が開いてしまいます。解放できないので解放されません。解放するbと、プロセスのメモリが削減される場合と削減されない場合があります。未使用の残りはシステムに戻されます。

と同じくらい簡単なプログラムでのテスト

#include <stdlib.h>

int main()
{
    char * a = malloc(100000);
    char * b = malloc(100000);
    char * c = malloc(100000);
    free(c);
    free(b);
    free(a);
}

strace次のような出力につながります

brk(0)                                  = 0x804b000
brk(0x8084000)                          = 0x8084000
brk(0x80b5000)                          = 0x80b5000
brk(0x809c000)                          = 0x809c000
brk(0x8084000)                          = 0x8084000
brk(0x806c000)                          = 0x806c000

isは、brk値が最初に増加し(for malloc())、次に再び減少する(for free())ことを示します。

于 2012-08-29T14:04:42.480 に答える
1

カーネルは、キャッシュされたメモリページを必要なときに、つまりシステムがメモリを使い果たしたときに、それらを再利用します。プロセスのヒープ(フリーストア)からのメモリページがOSに返されるかどうかは、プロセスのメモリマネージャ(この場合はC ++ライブラリのnew/実装)の裁量に委ねられています。deleteこれは完全に自発的な操作であり、カーネルは何の関係もありません。

トリックを実行したという事実から、drop_cachesメモリをいっぱいにしたのはプロセスのヒープではなく、カーネルキャッシュであったと推測できます。コマンドを使用してfree、アプリケーションで実際に使用できるメモリの量を確認します。-/+ buffers/cacheそれが報告する行。

于 2012-08-29T13:31:14.803 に答える
1

プログラムで呼び出すdeleteと、プログラム ランタイムの一部であるメモリ マネージャーにメモリが返されます。原則として、これは解放されたメモリを OS に戻すように記述できますが、そうなったら驚くでしょう。むしろ、再利用されたメモリは、以降の への呼び出しのために確保されますnew

これはプロセスの仮想メモリであることに注意してください。プログラムの実行中に実際に物理メモリに存在する量は、システム全体の負荷に依存し、オペレーティング システムによって処理されます。

于 2012-08-29T13:55:57.033 に答える
0

ユーザーがmallocを呼び出して無料(または新規および削除)を行うと、私の知る限り、使用されなくなったページがO/Sに戻されることはありません。代わりに、解放されたメモリを記憶しているだけなので、以前に解放されたメモリで満たすことができるサイズのmalloc / newを実行すると、O / Sに移動してsbrkを使用して取得するのではなく、それを使用します。より多くのメモリ。

したがって、このコード:

for (;;)
{
    struct { char data[200 * 1024 * 1024] } HugeBuffer;
    HugeBuffer *buff = new HugeBuffer;
    delete buff;
}

200Mbを一度割り当ててから、そのメモリを永久に着実に使用します。元の割り当てで一度O/Sに移動し、ユーザースペースでループします。

于 2012-08-29T14:45:14.317 に答える