メモリ管理【Linux 入門】

Linux

メモリとは

メモリとは、CPU が直接読み書きできるものです。電源を切るとメモリ上のデータは失われます。※本記事では不揮発性メモリ(SSD, HDD など)をストレージデバイスと表現します。

CPU がプロセスを実行する場合、ストレージデバイスにあるプログラムをメモリ上に移動してから実行します。

メモリには以下の2種類がありますが、本記事のメモリは”メインメモリ”を意味します。

  • メインメモリ
    • みんなが想像するメモリ。
  • キャッシュメモリ
    • CPU についていることが多いキャッシュメモリ。メインメモリより CPU から高速にアクセスできるため、よく利用するデータを置くことで処理を高速化するために利用します。

free コマンドでメモリ使用率を確認

free コマンドを利用することで以下のようにメモリ使用率の内訳を確認することができます。

free
              total        used        free      shared  buff/cache   available
Mem:        8063684      358512     7180624         652      524548     7473952

メモリを実際に使用をしてみる

今回は /dev/shm にマウントされた共有メモリを利用します。

df -Th
ファイルシス   タイプ   サイズ  使用  残り 使用% マウント位置
devtmpfs       devtmpfs   3.9G     0  3.9G    0% /dev
tmpfs          tmpfs      3.9G     0  3.9G    0% /dev/shm
tmpfs          tmpfs      3.9G  420K  3.9G    1% /run
tmpfs          tmpfs      3.9G     0  3.9G    0% /sys/fs/cgroup
/dev/nvme0n1p1 xfs         64G   20G   45G   30% /
tmpfs          tmpfs      788M     0  788M    0% /run/user/1000

メモリを2GiB 利用してみます。

free
              total        used        free      shared  buff/cache   available
Mem:        8063684      358512     7180624         652      524548     7473952
dd if=/dev/zero of=/dev/shm/tempfile bs=1M count=2048
2048+0 レコード入力
2048+0 レコード出力
2147483648 バイト (2.1 GB) コピーされました、 0.899953 秒、 2.4 GB/秒
free
              total        used        free      shared  buff/cache   available
Mem:        8063684      362620     5043644     2097804     2657420     5370028

free と Available が 2GiB 減少し、shared, buff/cache が 2GiB 増加したことがわかります。

電源を切るとメモリの内容が消えることを確認

再起動し、メモリの内容が消えることを確認します。

df -Th
tmpfs          tmpfs      3.9G  2.0G  1.9G   53% /dev/shm
sudo reboot
df -Th
tmpfs          tmpfs      3.9G     0  3.9G    0% /dev/shm

OOM (Out Of Memory)

OOM はメモリが足りないことです。(プロセスを実行する際に free コマンドの available が足りない状態。)

スワップ:メモリが不足する場合の対処その1

メモリが足りない場合は、使っていないプロセスをメモリから追い出します。これをスワップと言います。なお、追い出す先はストレージデバイス(SSD や HDD など)です。

スワップされたプロセスを実行する場合は、再びメモリに戻す必要があります。ストレージデバイスの読み書きはメモリと比較してクッッッッッッッソ遅いので、スワップが発生するとプロセスの処理が遅くなります。

OOM killer:メモリが不足する場合の対処その2

メモリがいっぱいになった。スワップ領域もいっぱいになった。でも新しくプロセスを立ち上げたい。この時、OS によるプロセス kill 祭りが始まります。これが OOM Killer です。

いわゆる「何もしていないのに、アプリが落ちた」が発生します。

仮想メモリ

プロセスにメモリを割り当てる際には、以下の方式を利用してメモリを管理します。

ページング方式

ページング方式とは、プロセスごとにページテーブルと呼ばれる仮想アドレスと物理アドレスのマッピング表を持つ方法です。

なお、ページサイズは getconf PAGESIZE コマンドで確認可能です。

getconf PAGESIZE
4096

この場合は、ページサイズは 4Bytes であることがわかりますね。以降の例ではわかりやすいようにページサイズは 100Bytes で説明します。

ちなみに、上記のページテーブルで仮想アドレス 300-400 にアクセスした場合、ページフォールトが発生します。そのまま、新しく割り当てる物理アドレスが見つからない場合はセグメンテーションフォールトが発生します。

セグメント方式

セグメント方式とは、メモリでプロセスを管理する際に、以下のようにセグメント(プロセスやデータの属性)ごとに分けて領域を分けて管理する方法です。

  • テキストセグメント
    • プログラムの命令コードを格納
  • データセグメント
    • 初期化済みのグローバル変数を格納
  • bss セグメント
    • 初期化されていないグローバル変数を格納
  • ヒープセグメント
    • malloc 関数などで動的に確保するメモリ
  • スタックセグメント
    • ローカル変数を格納

ページ化セグメンテーション

ページング方式 + セグメント方式でメモリを管理する方法です。

物理メモリに直接プロセスを割り当てる場合以下のような問題が発生するため、ページ化セグメンテーションを利用して仮想メモリにプロセスを割り当てます。

  • メモリの断片化
  • 別のプロセスやカーネルのメモリに無断アクセス可能
  • マルチプロセスが困難

メモリの断片化

ページ化ページ化セグメンテーションが無い時

以下のようにメモリの空き容量が断片化すると、合計空き容量は 200Bytes あるのに、個別の空き容量が 100Bytes しか無いので、200Bytes のプロセス4が起動できない。

ページ化ページ化セグメンテーションがある時

ページテーブルにより、バラバラの物理メモリを1つの大きなメモリと見なせるため、プロセス4が起動可能。

別のプロセスやカーネルのメモリに無断アクセス可能

ページ化ページ化セグメンテーションが無い時

物理メモリ番号を指定するだけでアクセス可能な場合、以下のように勝手にメモリを書き換えられる。

ページ化ページ化セグメンテーションがある時

ページテーブルにアクセス権限があるため、許可のあるメモリにしかアクセスできない。

マルチプロセスの扱いが困難

ページ化ページ化セグメンテーションが無い時

同じアドレスが使えないので、先着順になる。無理やり上書きすると既存のプロセス2が破壊される。

ページ化ページ化セグメンテーションがある時

セグメント(プロセス)ごとにページテーブルを持つことで、同じ仮想アドレスを利用できます。

参考書籍

以下の書籍がとてもわかりやすかったです。

0

コメント

タイトルとURLをコピーしました