2022.03.11
inuxフリーメモリの理解
Linuxフリーメモリの理解
㈱エクセンコンサルティング本部/DBコンサルティングチームイム・ギョンソク
概要
Linux環境でメモリ使用率を監視するために命令を実行してみると、システムを起動したばかりではなく、free領域の指標が急激に減ることを容易に確認することができます。
Linuxアドミンの経験がある人なら、これが何を意味するのかは分かりますが、そうでない場合はよくメモリ使用率が高いと判断できます。
したがって、結果として示す指標が何を意味するのかを正確に理解していない場合は、誤った判断を下すことになります。 この記事では、Linuxでメモリ使用率を監視する方法と、それぞれの指標が何を意味するのかを簡単に見てみましょう。
freeメモリの意味?
Unix系のシステムでメモリ使用率を確認するためにtop、free、vmstat、sar、topasなどの命令を主に使用します。
Linuxでは、単純にfree命令を実行すれば、現在の時点のメモリ状態を簡単に確認することができる。 私のテスト機器は、Oracle Linux 2.6-64bitにOracle 11.2.0.3バージョンでシステムを起動するたびにfreeを実行すると、以下のような結果が確認できます。
[root@ora11 ~]# free -m
total | used | free | shared | buffers | cached | |
Mem: | 2002 | 325 | 1676 | 0 | 22 | 124 |
-/+ buffers/cache: | 179 | 1823 | ||||
Swap: 3843 | 0 | 3843 |
合計メモリサイズは2,002 MBで、サーバーが起動されて使用されたメモリは325 MB、空きメモリは1,676 MBです。
ここで一つ注意して見て欲しいのは、それぞれ22MB、124MBで表されるbuffersとcached部分です。
すでに単語の意味から推測できるように、buffersはメモリに存在するデータ領域のうちディスクにフラッシュされるデータ領域を意味します。
buffers は定期的にbdflushデーモンによってディスクにフラッシュされます。
ランダムにフラッシュしたい場合は、syncコマンドを実行するだけです。
現在のダーティページサイズは、/proc/meminfoのDirtyと表示されている部分で確認できます。
一方、cachedは、既存のプログラムが使用していたメモリで実行中であるか、または新しい起動プログラムが必要に応じてすばやく再利用できるメモリ領域を意味します。
ディスクキャッシュとも呼ばれることがよくあります。キャッシュを維持する理由は、同じデータを要求するプログラムがある場合は、ディスクから読み取るよりもキャッシュされたデータを読み取ることがパフォーマンスにとって有利であるためです。 したがって、Cached領域は、実行中のプログラムがメモリが必要な場合にすぐに使用されるフリーメモリと考えることができます。
Unixシリーズのシステムでのメモリ使用量は、大幅にプロセスが使用するヒープ領域とディスクキャッシュ領域に分けることができます。
aixの場合、ほとんどのメモリをディスクキャッシュに割り当てます。 したがって、一定時間が経過するとフリーメモリが減少することがわかります。
Linuxの場合も同様です。 cached 領域に page cache だけでなく、ファイルのデータ構造である inode と dentry 情報を保存して cached 領域が増加するほど free 領域は減少することになります。
しかし、実際のメモリの余裕がないわけではなく、カーネルが必要なたびにcached領域を調べて調整することになります。 inode と dentry は高速データアクセスのために必要なものであり、カーネルのリソース割り当て者として機能する slab allocator によって保存されます。
cached 領域で slab が占める領域のサイズは/proc/meminfo で確認できます。
[root@ora11 ~]# cat /proc/meminfo MemTotal: 2050780 kB
MemFree: 1715904 kB
Buffers: 22736 kB
Cached: 128476 kB
SwapCached: 0 kB
Active: 91416 kB
Inactive: 120960 kB
Active(anon): 61416 kB
Inactive(anon): 1188 kB
Active(file): 30000 kB
Inactive(file): 119772 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 3936248 kB
SwapFree: 3936248 kB
Dirty: 52 kB
Writeback: 0 kB
AnonPages: 61288 kB
Mapped: 32596 kB
Shmem: 1440 kB
Slab: 92012 kB
SReclaimable: 18520 kB
SUnreclaim: 73492 kB
モニタリング
これまでの内容をまとめると、Linuxの場合、メモリの実使用率を求めるためには、実際のfree
サイズは、free領域にbuffersとcachedを追加して計算する必要があるということです。
これに基づいて実際のfreeとusedサイズを求めると -/+ buffers/cache: に示された値とほぼ一致することが分かります。
[root@ora11 ~]# free -m
-/+ buffers/cache: 179 1823 Swap: 3843 0 3843 |
total used free shared buffers cached Mem: 2002 325 1676 0 22 124
フルメモリtotal = used + free + buffers + cached
実際のフリーメモリ = free + buffers + cached = 1676 + 22 + 124 = 1822
物理メモリ使用量= total-(free + buffers + cached) = 2002-(1676 + 22 + 124) = 179
この状態でOracleを起動すると、メモリ使用量がどのように変化するかを見てみましょう。
SQL> startup
ORACLE instance started.
Total System Global Area 1068937216 bytes Fixed Size 2235208 bytes
Variable Size 281019576 bytes
Database Buffers Redo Buffers Database mounted. Database opened. | 780140544 bytes 5541888 bytes | |||
[oracle@ora11 ~]$ free -m total | used free | shared | buffers | cached |
Mem: 2002 | 733 1268 | 0 | 53 | 416 |
-/+ buffers/cache: | 263 1738 | |||
Swap: 3843 | 0 3843 |
[root@ora11 ~]# ipcs -m
—— Shared Memory Segments ——–
key | shmid | owner | perms | bytes | nattch | status |
0x00000000 | 0 | gdm | 600 | 393216 | 2 | dest |
0x00000000 | 32769 | gdm | 600 | 393216 | 2 | dest |
0x00000000 | 65538 | gdm | 600 | 393216 | 2 | dest |
0x00000000 | 98307 | gdm | 600 | 393216 | 2 | dest |
0x00000000 | 163844 | oracle | 640 | 12582912 | 26 | |
0x00000000 | 196613 | oracle | 640 | 536870912 | 26 | |
0x00000000 | 229382 | oracle | 640 | 524288000 | 26 | |
0x0f98b25c | 262151 | oracle | 640 | 2097152 | 26 | |
0x00000000 | 294920 | gdm | 600 | 393216 | 2 | dest |
SGAサイズが1GBのインスタンスを起動した後、usedは733 MB、cached領域は416 MBに増加したことが確認できます。
これは、Oracleを起動してOracleが所有するshared memoryが2GBであるにもかかわらず、最初からSGAすべてをメモリに生成しないということです。
SQL * Plusで大量のテーブルを選択するクエリを特定のセッションで実行してみましょう。
14:56:21 <SCOTT@DB11G>
1 select count(*) from t;
COUNT(*)
——— 19200000
15:01:16 <SCOTT@DB11G>
1 select segment_name, bytes/1024/1024
15:01:39 | 2 | from dba_segments |
15:01:46 | 3 | where segment_name = ‘T’; |
SEGMENT_NAME BYTES/1024/1024
————– —————–
T 440
[oracle@ora11 ~]$ free -m
total | used | free | shared | buffers | cached |
Mem: 2002 | 1233 | 769 | 0 | 53 | 898 |
-/+ buffers/cache: | 282 | 1720 | |||
Swap: 3843 | 0 | 3843 |
Oracleでセグメントサイズが440 MBのテーブルを選択した場合は、cached 898 MBまで増加したことがわかります。
その結果、フリー領域も769 MBに減少します。
このとき、サイズが1GBのファイルを1つ作成してみましょう。
[oracle@ora11 ~]$ cd /u01
[oracle@ora11 u01]$ dd if=/dev/zero of=test bs=1024K count=1000 1000+0 records in
1000+0 records out
total used free shared buffers cached Mem: 2002 1983 19 0 35 1654 -/+ buffers/cache: 292 1709 Swap: 3843 0 3843 |
1048576000 bytes (1.0 GB) copied, 10.5086 s, 99.8 MB/s [oracle@ora11 u01]$ free -m
[oracle@ora11 sc]$ vmstat 1
0 0 0 806040 54688 922292 0 0 0 32 912 1455 0 3 97 0 0 0 0 0 806048 54688 922292 0 0 0 0 835 1420 0 2 98 0 0 0 0 0 806048 54688 922292 0 0 0 16 919 1433 0 4 96 0 0 0 2 0 482268 54840 1226700 0 0 152 92712 1422 1531 0 26 69 6 0 0 2 0 431056 54840 1277264 0 0 0 38400 1318 1634 1 15 22 63 0 1 1 0 360252 54840 1345448 0 0 0 75460 1437 1881 0 9 0 91 0 1 2 0 300732 54840 1400220 0 0 0 56140 1617 1832 6 13 0 80 0 0 3 0 245428 54840 1454016 0 0 0 49152 1405 1775 0 11 0 89 0 |
procs ———–memory———- —swap– —–io—- –system– —–cpu—– r b swpd free buff cache si so bi bo in cs us sy id wa st
0 | 3 | 0 200912 | 54844 | 1499644 | 0 | 0 | 4 48688 1342 | 1726 | 0 11 0 89 | 0 | |||||
0 | 2 | 0 181940 | 54856 | 1521548 | 0 | 0 | 8 49172 1129 | 1573 | 0 8 2 89 | 0 | |||||
1 | 1 | 0 79268 | 54876 | 1614780 | 0 | 0 | 20 83612 1161 | 1443 | 0 12 42 46 | 0 | |||||
0 | 1 | 0 16268 | 51732 | 1680336 | 0 | 0 | 4 55688 1416 | 1671 | 0 14 4 82 | 0 | |||||
0 | 1 | 0 22156 | 51736 | 1680344 | 0 | 0 | 4 0 1002 | 1440 | 0 2 48 49 | 0 | |||||
1 | 1 | 0 | 16972 | 36584 | 1692260 | 0 | 0 | 1392 266328 2461 1730 | 1 43 16 41 | 0 | |||||
0 | 0 | 0 | 19824 | 36584 | 1693676 | 0 | 0 | 1040 24576 1396 1612 | 1 8 67 23 | 0 | |||||
0 | 0 | 0 | 19832 | 36584 | 1693604 | 0 | 0 | 0 | 0 | 910 | 1447 | 0 | 3 97 | 0 | 0 |
0 | 0 | 0 | 19832 | 36584 | 1693612 | 0 | 0 | 8 | 32 | 880 | 1440 | 0 | 3 96 | 1 | 0 |
0 | 0 | 0 | 19956 | 36584 | 1693612 | 0 | 0 | 0 | 0 | 881 | 1473 | 0 | 2 98 | 0 | 0 |
サイズが 1 GB のファイルを生成する場合、free は 19 MB に急激に減少し、 used 部分は 1,983
MBまで増加しました。 二重1,654 MBがキャッシュ領域に作成され、バッファ領域も一部減少したことがわかります。
もしそうなら、現在のメモリ全体のサイズより大きいファイルを生成する場合、メモリの変化はどうなるかを見てみましょう。
[oracle@ora11 u01]$ dd if=/dev/zero of=test bs=1024K count=4000 4000+0 records in
4000+0 records out
total used free shared buffers cached Mem: 2002 1975 27 0 35 1635 -/+ buffers/cache: 303 1698 Swap: 3843 0 3843 |
4194304000 bytes (4.2 GB) copied, 9.29048 s, 451 MB/s [oracle@ora11 sc]$ free -m
[oracle@ora11 sc]$ vmstat 1
0 0 0 16492 36604 1692316 0 0 959 1217 384 481 1 5 84 10 0 0 0 0 16492 36604 1692316 0 0 0 0 853 1439 0 2 98 0 0 0 0 0 16492 36604 1692316 0 0 0 32 887 1410 0 3 97 0 0 0 0 0 16492 36604 1692316 0 0 0 32 885 1471 0 2 97 0 0 1 0 0 16492 36604 1692316 0 0 0 0 894 1445 0 2 98 0 0 0 0 0 16492 36604 1692316 0 0 0 0 940 1485 0 3 96 0 0 0 0 0 16500 36604 1692316 0 0 0 32 947 1462 0 4 96 0 0 1 0 0 484972 36604 1236120 0 0 12 0 1042 1481 0 7 92 1 0 1 1 0 424444 36604 1288272 0 0 0 393644 2506 1146 0 76 20 3 0 2 0 0 15612 36608 1690140 0 0 0 422540 2469 805 0 88 8 4 0 |
procs ———–memory———- —swap– —–io—- –system– —–cpu—– r b swpd free buff cache si so bi bo in cs us sy id wa st
2 | 0 | 0 | 16604 | 36404 1678424 | 0 | 0 | 72 471500 2786 1629 | 0 73 | 3 24 | 0 |
1 | 1 | 0 | 15612 | 36424 1683244 | 0 | 0 | 20 328764 3023 2026 | 0 73 | 5 22 | 0 |
2 | 3 | 0 | 16852 | 36424 1671024 | 0 | 0 | 0 525444 2687 1473 | 0 82 | 8 10 | 0 |
3 | 1 | 0 | 16728 | 36424 1681788 | 0 | 0 | 0 402584 2778 1483 | 0 75 | 15 10 | 0 |
1 | 1 | 0 | 16852 | 36344 1681964 | 0 | 0 | 4 403584 2889 1850 | 0 82 | 8 10 | 0 |
4 | 0 | 0 | 14000 | 36344 1684544 | 0 | 0 | 0 591664 2876 1213 | 0 90 | 4 7 | 0 |
4 GB サイズのファイルの作成中に vmstat でメモリの変化を見ると、空き領域が 16 MBの状態で、キャッシュされた領域のメモリの一部をフリー状態に切り替えることが分かります。 freeに変換されたメモリは、ファイルが作成された時点で再びcached状態になり、freeおよびcachedサイズが現在の状態に変更されることがわかります。
つまり、freeメモリが不足した場合、cached領域の一部をfree状態に切り替えて使用するということです。 これは、前述のように、キャッシュされた領域が実際にフリーメモリとして使用されていることを示しています。
ここで一つ確認するのは、freeメモリが不足してもswapは発生していないということです。 swap の used はまだゼロのままです。
その後、4GBファイルをすぐに削除すると、以下のようにcached領域の大部分のメモリが再びfree領域に切り替わります。
ファイルの作成中にキャッシュされた領域の大部分を占有するデータが同時に削除されるため、Oracleインスタスだけが生成された時点にメモリ状態が変更されます。
この時、Oracleインスタンスも続いてshutdownさせる場合、以下のようにシステムを初めて起動するときのメモリ状態に変更されます。
total used free shared buffers cached Mem: 2002 664 1338 0 35 357 -/+ buffers/cache: 271 1731 Swap: 3843 0 3843 |
[oracle@ora11 u01]$ rm test [root@ora11 ~]# free -m
[oracle@ora11 ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.3.0 Production on Fri Nov 1 09:28:57 2013 Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> shutdown immediate Database closed.
Database dismounted. ORACLE instance shut down.
[root@ora11 ~]# free -m
total | used | free | shared | buffers | cached | |
Mem: | 2002 | 347 | 1655 | 0 | 35 | 119 |
-/+ buffers/cache: | 192 | 1810 | ||||
Swap: 3843 | 0 | 3843 |
これまでテストのために行われたすべての内容をメモリから削除しても、キャッシュされた領域にはまだ119 MB 残っています。
この部分もfreeに切り替えたい場合はどうすればよいでしょうか? Linux では、メモリの buffers と cached 状態のメモリをフリー領域にランダムに変更するため
/proc/sys/vm/drop_caches ファイルの内容を 0 から 1、2、3 のいずれかの値に変更すればよいのです。
total used free shared buffers cached Mem: 2002 249 1752 0 0 60 -/+ buffers/cache: 189 1813 Swap: 3843 0 3843 |
[root@ora11 ~]# echo 1 > /proc/sys/vm/drop_caches [root@ora11 ~]# free -m
- pagecache 解放
echo 1 > /proc/sys/vm/drop_caches
- dentries, inodes 解放
echo 2 > /proc/sys/vm/drop_caches
- pagecache, dentries, inodes すべて解除echo 3 > /proc/sys/vm/drop_caches
ファイルの値を ‘1’ に変更すると、cached 値が大部分フリー領域に切り替えられたことがわかります。 そのファイルを直接変更することもできますが、命令でも可能です。
[root@ora11 ~]# free -m
total | used | free | shared | buffers | cached | |
Mem: | 2002 | 898 | 1104 | 0 | 26 | 591 |
-/+ buffers/cache: | 280 | 1722 |
Swap: 3843 | 0 | 3843 |
[root@ora11 ~]# sysctl -w vm.drop_caches=3 vm.drop_caches = 3
total used free shared buffers cached Mem: 2002 607 1394 0 2 325 -/+ buffers/cache: 280 1722 Swap: 3843 0 3843 |
[root@ora11 ~]# [root@ora11 ~]# [root@ora11 ~]# [root@ora11 ~]# free -m
結論
UnixシリーズのO / Sでメモリ使用率を正確に監視することは容易ではありません。
その理由は、高速CPU性能にI/O速度を合わせるためにメモリの大部分をディスクキャッシュとして使用するためです。
ディスクキャッシュは、I / Oが発生するたびに流動的に変化し、特定のカーネルパラメータを介してしきい値を設定し、それ以上の増加を防ぐことができます。
これらの機能は各ベンダーにより少しずつ違いがあります。
メモリ使用率を正確な数値で計算することは容易ではなく、メモリを確認する命令語によって若干の違いがあります。
したがって、メモリを監視するときにどれだけ利用可能なメモリが残っているのか、現在のメモリが不足してSWAPを継続的に使用しているかなどを確認することが正しい監視方法と言えるでしょう。
参考文献
http://stackoverflow.com/questions/9724396/understanding-buffers-and-cached-from- free-command ,
