Linuxシステムでは、我々は多くの場合、システムメモリの使用を表示する無料のコマンドを使用します。システム上のRHEL6、コマンドは状態のようなものを自由に内容を表示します。
[root@tencent64 ~]# free
total used free shared buffers cached
Mem: 132256952 72571772 59685180 0 1762632 53034704
-/+ buffers/cache: 17774436 114482516
Swap: 2101192 508 2100684
ここに私のサーバーは、128Gメモリなので、数字が比較的大きいと思われる、デフォルトの表示単位キロバイトです。このコマンドは、ほとんどすべての人は、Linuxコマンドを使用する必要がありますされていますが、より多くのようにコマンドは、あまりそれは本当に(私はあまりの割合を意味する)の人々を理解しているようです。一般的には、このコマンドの出力を理解することは、いくつかのレベルに分けられます。
- 理解していません。多くのメモリ、70以上のGで、神が、私はほとんど大きなランニングああを持っている:最初の反応は、このような人ですか?なぜこれがそうですか?Linuxは、良い思い出を占め!
- 私は非常に理解と思います。一般的に評価されるような人々は言うだろう:ああ、私のプロの目は17G程度のメモリで、それを見るために、空きメモリの多くが利用可能です。使用するとき、アイドル、このメモリをバッファは/キャッシュは、システムは、プロセスがファイルを読み書きするために使用されたことを示す、大きな占有が、それは問題ではありません。
- 本当に理解しています。そのような人々の反応が、人々はほとんどがLinuxを理解していないと感じ、彼らの反応は:この無料のショーがあり、よく私が知っています。神の馬?あなたは十分にこれらのメモリを私に尋ねる、私は確かにそれを知りません!私はそれがどのようにあなたのプログラムの書き方を特別知っていますか?
Web上の現在の技術文書の内容によると、私はほとんどの人は、Linuxが第2レベルであることを理解すべきであると考えています。これは、広く使用された場合、バッファとキャッシュされたメモリ占有スペースがより大きなメモリ圧力の空き領域として解放することができ、感じました。しかし、実際の場合?この問題を示す前に、我々は最初に簡単にバッファを記述し、それが何を意味するか、キャッシュされました:
バッファ/キャッシュとは何ですか?
バッファキャッシュとコンピュータ技術に二つの異なる意味があるだろうが、異なる状況下に置かれ、虐待の観点から使用されています。Linuxのメモリ管理では、ここでのバッファは、Linuxのメモリを参照:バッファ・キャッシュを。ページのキャッシュ:ここでのキャッシュは、Linuxのメモリを指します。中国語に翻訳呼び出すことができ、バッファ・キャッシュとページキャッシュ。他の(キャッシュ)は、リードキャッシュデバイスとして使用されている間、歴史的に、それらは(バッファ)は、主に、ブロック・デバイス・ファイルを参照し、ここで、IO装置をioを、IO装置を書き込むためにキャッシュとして使用されるとファイルシステム上の通常のファイル。しかし、今、彼らは同じ意味を持っていません。現在のカーネルでは、名前はそれがメモリページ割り当て管理がある場合、あなたはその使用を管理するためのキャッシュとしてページキャッシュを使用できることを意味し、キャッシュページのキャッシュ・メモリ・ページのためにあることを示唆しています。もちろん、すべてではないメモリがページにページを管理している、と多くはブロックのブロックのために管理されていますが、キャッシュ機能を使用したい場合は、このメモリは、使用するバッファキャッシュに集中しています。(このような観点から、ブロック・キャッシュ・バッファ・キャッシュは、より良い改名呼び出されない?)しかし、すべてのブロックのブロックは固定長を有していない、システムのメインブロックの長さは、使用されるブロックデバイスに基づいて決定される、長さが一方のページは32ビットまたは64ビットが4KであるかどうかX86。
システムキャッシュのこれらの2つのセットの間の違いを理解し、我々は、彼らが行うために使用することができます正確に理解することができます。
ページキャッシュとは何ですか
ページキャッシュは、主にプロセスがファイルの読み取り/書き込み操作のための時間がある場合は特に、使用するファイルシステム上のキャッシュファイルのデータとして使用されています。あなたはそれについて考える場合は、システムコールとしてメモリにファイルをマップすることができます。mmapのは非常に自然ではありませんまた、ページキャッシュを使用する必要がありますか?ページキャッシュはまた、使用するファイル・キャッシング・デバイスの別のタイプであるので、実際にはキャッシュページキャッシュは、作業ブロックデバイスファイルのほとんどに責任があるとして、現在のシステムの実装では。
バッファキャッシュとは何ですか
システムは、読み取りおよび書き込みデバイスをブロックするように設計されている場合、バッファキャッシュが主に使用され、ブロックデータキャッシュシステムを使用します。これは、操作のいくつかは、そのような私たちは、ファイルシステムのフォーマットであるときのように、バッファキャッシュ・ブロック・キャッシュを使用することを意味します。通常の状況下では、2つのキャッシュ・システムは、このような私たちは、ファイルに書き込むときのように、使用されているとともに、コンテンツページのキャッシュが変更され、バッファ・キャッシュが異なるページバッファをマークするために使用することができ、その変更されたレコードバッファです。この方法では、カーネルあなたは汚れたデータの書き戻し、その後の実行を書くとき、あなたはページ全体を書き戻す、とだけ修正部分を書き戻す必要はありませんがすることができます。
キャッシュをリサイクルする方法?
メモリは、プロセスによって使用されるメモリに大いに必要なメモリを解放するためにガベージコレクションの仕事をトリガー、枯渇されるLinuxカーネル。一般的には、この操作は、リリース・バッファ/キャッシュのリリースにメインメモリから来ています。特に、より多くのキャッシュスペースを使用します。それは主にキャッシュに使用されているので、ちょうど十分なメモリの時にスピードを読み書きファイルのプロセスをスピードアップし、より大きなメモリ圧力で、もちろん、キャッシュの解放を空にし、空き領域として使用される関連プロセスを与える必要があります。だから、通常の状況下では、我々は/キャッシュ領域を解放することができ、このような理解が正しいバッファと信じています。
しかし、この明確なキャッシュ作業はコストがないわけではありません。キャッシュは、キャッシュのクリアがリリースされるキャッシュのために、ファイルに対応するキャッシュデータのデータと一致している必要があります理解することができますやっている理解します。だから、行動のクリアキャッシュと一緒に、一般的にIOが急上昇システムです。対応するデータとハードディスクのファイルと比較してどうかカーネルキャッシュ上のデータ、そしてあなたが回復することができます前に書き戻す必要はありませんかのため。
メモリはキャッシュをクリアすることができます外部に排出されている場合を除き、我々は手動でトリガするために、次のファイルシステムキャッシュのクリア動作を使用することができます。
[root@tencent64 ~]# cat /proc/sys/vm/drop_caches
1
方法は次のとおりです。
echo 1 > /proc/sys/vm/drop_caches
もちろん、このファイルの値は、それぞれ、1,2,3を設定することができます。彼らが表現されていることを意味:
1> / proc / sys / vm / drop_cachesとエコー:ページのキャッシュをクリアします。
エコー2> / proc / sys / vm / drop_cachesと:(キャッシュ・ディレクトリ・エントリとiノードキャッシュを含む)スカベンジスラブアロケータオブジェクトを表します。スラブアロケータは、キャッシュデータをページキャッシュで使用されているの多くを達成するために、カーネルのメモリ管理のメカニズムです。
3> / proc / sys / vm / drop_cachesとエコー:ページキャッシュとキャッシュオブジェクトスラブディスペンサーをクリアします。
キャッシュは、それを再利用することができますか?
私たちは、状況キャッシュを回収することができ、分析、キャッシュそれが回復することはできませんか?もちろん。のは、最初のケースを見てみましょう:
tmpfsの
Linuxはtmpfsのいわゆる「一時的な」ファイルシステムを提供し、それはファイルシステムとして使用されるメモリ空間の一部とすることができることを知っている私たちは皆、メモリ空間は、カタログファイルとして使用することができます。今、Linuxシステムの大半は、ディレクトリは、そのような存在であるの/ dev / shmはtmpfsは呼ばれています。次のようにもちろん、我々はまた、手動で、独自のtmpfsのを作成することができます。
[root@tencent64 ~]# mkdir /tmp/tmpfs
[root@tencent64 ~]# mount -t tmpfs -o size=20G none /tmp/tmpfs/
[root@tencent64 ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 10325000 3529604 6270916 37% /
/dev/sda3 20646064 9595940 10001360 49% /usr/local
/dev/mapper/vg-data 103212320 26244284 71725156 27% /data
tmpfs 66128476 14709004 51419472 23% /dev/shm
none 20971520 0 20971520 0% /tmp/tmpfs
だから我々は新しいtmpfsの作成スペースは20Gで、我々は中に/ tmp / tmpfsのに20Gファイル内で作成することができます。私たちは実際のスペースを作成したファイルがメモリによって占められている場合、どのようなこれらのデータは、それを占有メモリ空間の一部である必要がありますか?それは、ファイルシステムのいくつかの種類であるので、達成するために、ページキャッシュ機能から理解することができるので、自然にスペースを使用すると、ページキャッシュを管理すること。我々はそれではありませんしてみてください?
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 36 89 0 1 19
-/+ buffers/cache: 15 111
Swap: 2 0 2
[root@tencent64 ~]# dd if=/dev/zero of=/tmp/tmpfs/testfile bs=1G count=13
13+0 records in
13+0 records out
13958643712 bytes (14 GB) copied, 9.49858 s, 1.5 GB/s
[root@tencent64 ~]#
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 49 76 0 1 32
-/+ buffers/cache: 15 110
Swap: 2 0 2
私たちは、13G tmpfsのディレクトリにファイルを作成し、前と比較することによって発見され、freeコマンドの後に、キャッシュされたが、この文書は、メモリ上で行い、カーネルをキャッシュメモリとして使用されている説明、13Gの増加となりました。その行/ +バッファ/キャッシュ - :私たちは気にメトリックを見てください。私たちは、このような場合には無料のコマンドは、私たちはまだ110Gメモリを用意してプロンプトが、本当にそう何ことがわかりましたか?私たちは、手動でガベージコレクションを回復することができますどのくらいのメモリを参照して終わりに今あるトリガできます。
[root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 43 82 0 0 29
-/+ buffers/cache: 14 111
Swap: 2 0 2
スペースの13GはまだTMP / tmpfsのファイル/占有され、我々はスペースが占有キャッシュされ、見ることができる、と私たちは完全に解放思っていないよう。もちろん、私のシステムだけでなく、キャッシュメモリ空間の他の非リリースは16Gの残りの部分によって占められます。それがリリースされる際にtmpfsのは、キャッシュ・スペースを占有しましたか?それは、ファイルを削除したとき。あなたはファイルを削除しない場合は、メモリのうちどの程度に関係なく、カーネルは自動的に空きキャッシュスペースへのtmpfs内のファイルを削除する助けにはなりません。
[root@tencent64 ~]# rm /tmp/tmpfs/testfile
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 30 95 0 0 16
-/+ buffers/cache: 14 111
Swap: 2 0 2
これはリサイクルできない我々の分析の最初のキャッシュの場合です。以下のような他の例は、あります。
共有メモリ
共有メモリは、共通のプロセス間通信(IPC)の方法の間、私たちに利用できるシステムですが、この通信手段がために適用され、シェルを使用することはできませんので、我々は簡単なテストプログラムコードを必要とする次のとおりです。
[root@tencent64 ~]# cat shm.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#define MEMSIZE 2048*1024*1023
int
main()
{
int shmid;
char *ptr;
pid_t pid;
struct shmid_ds buf;
int ret;
shmid = shmget(IPC_PRIVATE, MEMSIZE, 0600);
if (shmid<0) {
perror("shmget()");
exit(1);
}
ret = shmctl(shmid, IPC_STAT, &buf);
if (ret < 0) {
perror("shmctl()");
exit(1);
}
printf("shmid: %d\n", shmid);
printf("shmsize: %d\n", buf.shm_segsz);
buf.shm_segsz *= 2;
ret = shmctl(shmid, IPC_SET, &buf);
if (ret < 0) {
perror("shmctl()");
exit(1);
}
ret = shmctl(shmid, IPC_SET, &buf);
if (ret < 0) {
perror("shmctl()");
exit(1);
}
printf("shmid: %d\n", shmid);
printf("shmsize: %d\n", buf.shm_segsz);
pid = fork();
if (pid<0) {
perror("fork()");
exit(1);
}
if (pid==0) {
ptr = shmat(shmid, NULL, 0);
if (ptr==(void*)-1) {
perror("shmat()");
exit(1);
}
bzero(ptr, MEMSIZE);
strcpy(ptr, "Hello!");
exit(0);
} else {
wait(NULL);
ptr = shmat(shmid, NULL, 0);
if (ptr==(void*)-1) {
perror("shmat()");
exit(1);
}
puts(ptr);
exit(0);
}
}
プログラムがメモリを共有し、それは2G未満の期間に適用することで、非常に単純な特徴、そしてその後、この共有メモリの初期化動作、共有メモリの内容について子どもと他の親の初期化プロセスが完了した後の出力、終了を作るために子プロセスを開きます。しかし、終了する前に、共有メモリを削除しませんでした。のは、このプログラムの実施前と後のメモリ使用量を見てみましょう:
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 30 95 0 0 16
-/+ buffers/cache: 14 111
Swap: 2 0 2
[root@tencent64 ~]# ./shm
shmid: 294918
shmsize: 2145386496
shmid: 294918
shmsize: -4194304
Hello!
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 32 93 0 0 18
-/+ buffers/cache: 14 111
Swap: 2 0 2
16Gスペースによってキャッシュ18Gに上昇しました。そして、このキャッシュは、それを回復することができますか?テストを続行:
[root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 32 93 0 0 18
-/+ buffers/cache: 14 111
Swap: 2 0 2
結果はまだ回復していません。私たちは、誰もそれが削除されるまで、共有メモリは、まだキャッシュに長期保管になります使用していない場合であっても、これを観察することができます。二つの方法、一方が他方には、ipcrmのコマンドを使用することで、IPC_RMIDにプログラムshmctl()で使用されているがあります削除します。私たちは、削除しよう:
[root@tencent64 ~]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00005feb 0 root 666 12000 4
0x00005fe7 32769 root 666 524288 2
0x00005fe8 65538 root 666 2097152 2
0x00038c0e 131075 root 777 2072 1
0x00038c14 163844 root 777 5603392 0
0x00038c09 196613 root 777 221248 0
0x00000000 294918 root 600 2145386496 0
[root@tencent64 ~]# ipcrm -m 294918
[root@tencent64 ~]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00005feb 0 root 666 12000 4
0x00005fe7 32769 root 666 524288 2
0x00005fe8 65538 root 666 2097152 2
0x00038c0e 131075 root 777 2072 1
0x00038c14 163844 root 777 5603392 0
0x00038c09 196613 root 777 221248 0
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 30 95 0 0 16
-/+ buffers/cache: 14 111
Swap: 2 0 2
共有メモリを削除した後、キャッシュが正常に解放されます。この動作は、論理tmpfsのに似ています。カーネル下地共有メモリ(SHM)、メッセージキュー(MSG)とセマフォアレイ(SEM)これらPOSIX:XSI IPC機構記憶メモリは、使用TMPFSあります。これは、共有メモリとロジックの操作が似てtmpfsの理由です。もちろん、通常の状況下では、より多くのメモリを取るSHMあるので、我々はこの時点では、共有メモリの使用を強調しています。それは、共有メモリになると、Linuxはまた、私たちの共有メモリへの別の方法を提供し、それは次のようになります。
mmap
MMAP()は非常に重要なシステムが唯一自体は明らかでないのmmapの説明からこの関数を呼び出しています。文字通り、MMAPファイルは、プロセスの仮想メモリアドレスにマップされ、その後、あなたは道のメモリを操作することで、ファイルの内容を操作することができます。しかし、実際には呼び出しの目的は、非常に広範です。ときに、アプリケーションのmallocメモリ、メモリの大部分は、MMAPを使用する一方、カーネルsbrkのプロセスによって使用されるメモリの小片。それは本質的に、実行可能ファイルであるため、システムは、実行する機能のEXEC家族を呼び出したときに実行するためにメモリにロードされ、MMAPの方法を用いて処理することができるコアに自然です。ここでは、唯一のも同じキャッシュを使用しています()たshmgetに従わないであろう、共有メモリのmmapの使用が適用されている状況を考えますか?
同様に、我々はまた、簡単なテストプログラムを必要とします:
[root@tencent64 ~]# cat mmap.c
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define MEMSIZE 1024*1024*1023*2
#define MPFILE "./mmapfile"
int main()
{
void *ptr;
int fd;
fd = open(MPFILE, O_RDWR);
if (fd < 0) {
perror("open()");
exit(1);
}
ptr = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, fd, 0);
if (ptr == NULL) {
perror("malloc()");
exit(1);
}
printf("%p\n", ptr);
bzero(ptr, MEMSIZE);
sleep(100);
munmap(ptr, MEMSIZE);
close(fd);
exit(1);
}
我々は単に親と子の道を持っていないこの時間は、プロセスは2Gの期間に適用するためにメモリを共有MMAP、その後、100秒を待って、このスペースを初期化し、そのように私たちは私たちの睡眠でそれをチェックする必要がありほのめかす持ち上げたこれらの100秒システムのメモリ使用量とそれはスペースのために使用されているものを参照してください?もちろん、その前に最初の2Gのファイル./mmapfileを作成します。結果は以下の通りであります:
[root@tencent64 ~]# dd if=/dev/zero of=mmapfile bs=1G count=2
[root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 30 95 0 0 16
-/+ buffers/cache: 14 111
Swap: 2 0 2
そして、テストプログラムを実行します。
[root@tencent64 ~]# ./mmap &
[1] 19157
0x7f1ae3635000
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 32 93 0 0 18
-/+ buffers/cache: 14 111
Swap: 2 0 2
[root@tencent64 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 32 93 0 0 18
-/+ buffers/cache: 14 111
Swap: 2 0 2
私たちは前に2Gを上昇し、この時点では、このキャッシュはまだ回復することができないよりも、キャッシュされたが、18Gされている、プログラムの実行中に、見ることができます。プログラムが終了した後、その後、我々は100秒待ちます。
[root@tencent64 ~]#
[1]+ Exit 1 ./mmap
[root@tencent64 ~]#
[root@tencent64 ~]# free -g
total used free shared buffers cached
Mem: 126 30 95 0 0 16
-/+ buffers/cache: 14 111
Swap: 2 0 2
プログラムが終了した後、キャッシュされた占有スペースが解放されます。私たちが見ることができる。このように、キャッシュMAP_SHAREDメモリ用のmmap要求フラグの状態を使用して、カーネルは、格納するために使用されています。プロセス関連のメモリが解放されていない前に、このキャッシュは正常に解放されません。実際には、メモリMMAPは、カーネルでtmpfsのが実装されていることで、アプリケーションの道をMAP_SHARED。共有ライブラリの読み取り専用の部分は、実際には、彼らはキャッシュを取ることで、解放することができない、MAP_SHAREDへのmmapの方法は、メモリ内で管理されているので、このことから、我々は、推測することができます。
遂に
私たちは見つけ、3つの例をテストした Linuxシステムのメモリキャッシュが使用されるフリースペースとして、すべての場合でリリースすることはできません。そして、それはまた、あなたがいないシステムのためにコストをかけずに、キャッシュを解放することができたとしても、明らかにしました。私たちはこれらの点を忘れてはならない、主なポイントを要約:
- キャッシュはファイルキャッシュとしてリリースされている場合には、支払われるべきファイルのアクセス速度を高速化するキャッシュのコストで増加IO、につながります。
- キャッシュに保存されたファイルは、スペースを取るtmpfsは、そうでない場合は、キャッシュが自動的に解放されることはありませんしない限り、ファイルを削除します。
- 共有メモリの使用がIPC_RMIDへのipcrmまたはshmctlである、またはそれ以外のキャッシュ領域が自動的に解放されることはありませんしない限り、共有メモリキャッシュの使用を申請したshmgetは、スペースを占有します。
- メモリキャッシュはこのメモリのプロセスがと、munmapなり、あるいはキャッシュ領域が自動的に解放されることはありませんしない限り、アプリケーションMAP_SHAREDマークのMMAPの方法を使用してスペースを占有します。
- 確かたshmget、mmapの共有メモリ、tmpfsので、カーネル層で実装tmpfsのが実装されているキャッシュメモリが渡されます。
これらを理解するための時間は、私はあなたが私たちが自由にコマンドを達成することができることを理解してほしい場合は3番目のレベルは語りました。私たちは、メモリ使用量も本当にフリースペースとして使用されていないシンプルなコンセプト、キャッシュではないことを理解すべきです。私たちは本当に最後に使用するようにシステム上のメモリの合理性を深く理解したい場合は、はるかに明確な知識の詳細を理解するために、そして経営判断に関連する詳細を実装するために多くを行うために必要があります。私たちの現在の実験シーンがCentOSに環境6で、Linuxの異なるバージョンの無料の本当の状態は、さまざまな理由を見つける行くことができ、同じではないかもしれません。
もちろん、これはすべてのキャッシュを解放することができない場合ではありません。だから、あなたのシナリオでは、シナリオのキャッシュを解放することができない人たちがあるのですか?
します。https://blog.csdn.net/lqglqglqg/article/details/82313966より転載