メモリ
#メモリ #チューニング #os
参考
https://qiita.com/sasakiki/items/e0f21556f45f5b4376a9#dbサーバーのメモリ設定
概要
メモリはシステム全体の共有リソースなので、各プロセスが勝手にいじっていい代物ではない。
カーネルの機能によってしっかり管理されてる。
メモリを利用するのは誰か?
基本的にはプロセスとカーネル自身が利用することになる。
なので、メモリの利用についてもカーネル利用領域とユーザープロセス利用領域に分かれてる。
プロセスが作られる度に、そのプロセス用のメモリ領域が作られることになるだろう。
メモリ利用関連の指標
メモリについて知っていくために覚えておくべき指標。
freeコマンドで得られる指標たちを一旦覚えておくと良い。
-> メモリ#63c1371ab3641f00001a1d76
仮想記憶(メモリ)
Linuxでは、ハードウェアとソフトウェアの間を上手く取り持つための仮想記憶という概念が存在する。
物理メモリだけでいいやん!て思いたいところだが、それだけだと防げない3つの課題がある。
1. メモリの断片化
前提として、プロセスのメモリの確保・解放を繰り返す。
これを様々なプロセスが物理メモリ上で行ってしまうと、次第にプロセス毎に管理する領域がメモリ上に断片的に散りばってしまう。
こうなるとプログラム側としてはメモリからデータを探したりするのが大変になる。
また、メモリ側としてもより大きなメモリ領域を一気に取りにくくなる。
2. マルチプロセスの実現困難
各プロセスは作成される際にメモリ領域を確保するわけだが、物理メモリで動作する場合、いちいち他プロセスが利用してるメモリ領域を知る必要がある。
「ここは既に使ってるんか...じゃあここは?ここも使ってるんか!...」っていう面倒なことになる。
3. 不正領域へのアクセス
各プロセスが物理メモリを把握するということは、メモリ上の全領域にアクセスできるということ。
これができてしまうと、プロセスAがプロセスBのメモリ領域を変更することも可能になる。
また、もっとやばいことにカーネル管理のメモリ領域もアクセスできちゃうやばい状態に。
仮想記憶の仕組み
プロセスに物理メモリのアドレスに直接アクセスさせるのではなく、仮想メモリのアドレスにアクセスさせる。
プロセス毎に連続的な仮想領域が作られることから、上記の3つの課題を解決できるようになる。
https://scrapbox.io/files/63c1541e00a9bf001e5805ae.png
「ページ」
カーネルはアドレスを1:1で毎回変換させるのではなく、ページ単位でまとめて変換しよる
DBのページと同じ概念だと思えばOK。
ていうかOSのこの制約があるから、DBもレコード単位でデータ取得とかしないのでは??
ちなみに...物理アドレスが紐づけられてない仮想アドレスにアクセスするとページフォールトが発生する。
ページフォールトとかダリィわ、その時に動的に紐付けしてくれよ!!ってな時はこれ
デマンドページング
デマンドページングとは (demand paging): - IT用語辞典バイナリ
スワップ的な文脈でも同じ言葉出てくるから勘違いに気をつけて。文脈大事。
q.icon プロセスが途中で仮想メモリ領域を増やしたいとなったらどうするの?
a.icon 「増やします!」って宣言する必要がある。「これだけメモリ確保します!」と。
みんな大好き、mmapシステムコールがその機能。
バッファ部分の回収処理
システム負荷が高まってくると、freeなメモリ容量が少なくなってくる。
こうなってくると新しいプロセスにメモリを割り当てれなくなってしまうので...
カーネルは必要ないバッファ領域(buff/cacheの部分)をfreeのために解放する。
OOM Killer
「buff/cacheを解放しても足りない!」てなると、いよいよカーネルは稼働中プロセスを無理やり停止させて、メモリの空き容量を作ろうとする。
この足りない!て状態をOut of Memory(OOM)と呼ぶ。
このOOMを打開し、メモリを無理やりこじ上げる機能のことをOOM Killerと呼ぶ。
参考:LinuxにおけるOOM発生時の挙動
メモリリーク
あるプログラムがメモリを確保したにも関わらず、解放しないまま稼働することにより、システム全体の利用可能なメモリ容量が徐々に減っていく状態のこと。
基本的にプログラムは、必要無くなったメモリを解放してあげないといけない。システム上でOOMが発生しやすくなってしまう。
プロセスがメモリリークを起こしてるかどうかは、psコマンドでプロセスごとの使用メモリ量を逐一確認してあげると良い。
プロセスのメモリ性能
プロセスのメモリ使用に関する主な指標
VSS(Virtual Set Size)
プロセスが確保してる仮想メモリ上の領域サイズ。
そのプロセスが現在実際に使用してる物理メモリ量を表すわけではない。
RSS(Resident Set Size)
そのプロセスが使用してる物理メモリの領域サイズ。
PSS(Proportional Set Size)
プロセス間で共有してるライブラリのサイズを等分した上で、各プロセスの物理メモリサイズを合算した値。
USS(Unique Set Size)
別プロセスと共有してるサイズを省いた上での各プロセスの使用中物理メモリの領域サイズ。
Linux上での確認方法
topコマンド or psコマンドを利用する。
メモリ関連Linuxコマンド
ps:現在実行中のプロセスを一覧表示する。プロセスが利用中のメモリ量も表示可能。
free:メモリの利用状況を調べる
Linuxのfree コマンドの見方とオプション ~availableやbuff/cacheの定義~ | SEの道標
code: sample
root@CENTOS7 ~# free
total used free shared buff/cache available
Mem: 1014820 184368 684116 6928 146336 683684
Swap: 1679356 0 1679356
table:
項目 内容
total 合計メモリ量
free 基本的なメモリ空き容量。
used ユーザープロセス、カーネル両方が使用中のメモリ容量。used = total - free。
buff/cache バッファキャッシュ、ページキャッシュ。freeの値が減少してきたら、カーネルによって一部解放される。
available freeにカーネル内の一部領域を足したもの。実質利用可能なメモリ容量。
shared 共有メモリで使用しているメモリ。
used
usedはもちろん、プロセスが使用するメモリ容量によって上限する。
buff/cache
ページキャッシュ、バッファキャッシュとは?
アクセスが遅いストレージ上にあるファイルデータをメモリに載せる仕組みのこと。
カーネルが勝手に管理してる。
https://scrapbox.io/files/63c1387cbc6c4d001ee3edf5.png
これwriteしたタイミングで普通ならページフォルトが起こるのでは?
デマンドページングでカーネルが動的に物理メモリを確保してくれてるのかな
sar:CPUの動作状況を確認できたりするコマンド
こいつの-rを利用すれば、メモリの使用状況を統計で間隔決めて取得可能。