Linuxがスワップをメモリに再読み込みできるようにする

Linuxがスワップをメモリに再読み込みできるようにする

16GB の物理メモリを大部分使用するアプリケーションを実行すると、Linux カーネルはメモリのページの大部分をスワップします。アプリケーションが完了したら、各タスク(コマンド入力、ワークスペースの切り替え、新しいWebページを開くなど)を完了するのに長い時間がかかります。なぜなら、関連ページをまず交換で再度読まなければならないからです。

各アプリケーションに手動で触れて待つ必要なく、Linuxカーネルにページをスワップから物理メモリにコピーするように指示する方法はありますか?私は多くのアプリケーションを実行しているので、待つのはいつも痛いです。

私はしばしばswapoff -a && swapon -aシステムが再応答するためにこれを使用しますが、これはスワップページをクリアするので、次回スクリプトを実行するときに書き直す必要があります。

カーネルがスワップからすべてのページを読み取るように指示するカーネルインタフェース(おそらくsysfsを使用)はありますか?

編集:実際にすべてのスワップをキャッシュ可能にする方法を探しています。 (DeRobertに感謝!)

[PS serverfault.com/questions/153946/…そしてserverfault.com/questions/100448/…これは関連トピックですが、Linuxカーネルにスワップを消去せずにスワップからメモリにページを再コピーさせる方法に関する問題は扱いません。 ]

答え1

役に立つかもしれません/proc/sys/vm/page-cluster(デフォルト:3)。

カーネルドキュメントで(sysctl/vm.txt):

ページクラスタ

ページクラスタは、1回の試行でスワップから読み取られる連続ページ数を制御します。これはページキャッシュ先読みのスワップ対応です。言及された連続性は、仮想/物理アドレスではなく、スワップ空間の連続性を意味します。つまり、互いにスワップされるという意味です。

ログ値です。 0に設定すると「1ページ」を意味し、1に設定すると「2ページ」を意味し、2に設定すると「4ページ」を意味します。 0 はスワップ先読みを完全に無効にします。

デフォルトは3(一度に8ページ)です。ワークロードがスワップ集約的である場合、それを別の値に調整することにはいくつかの利点があります。

値が小さいほど初期エラーの待ち時間は短くなりますが、先読み連続ページの一部である場合は、追加エラーと後続エラーのI / Oレイテンシが犠牲になります。

ドキュメントに制限は記載されていないため、すべてのスワップを非常にすばやく再読み込みできるように、非常に高く設定できます。もちろん、その後は再び通常値に戻してください。

答え2

魔法のように「システムを再反応させる」ことはできないようです。すぐにペナルティを受け取ったり、ページをスワップ領域からメモリに読み込んだり、後でペナルティを受け取ったり、どちらかを選択したりする必要があります。しかしどちらも原因になります。実際、似たようなことをしたらswapoff -a && swapon -a感じるかもしれません。もっと不要になった特定のページをメモリにコピーするように強制し、読み取らずに削除されるため、あまり苦痛ではありません。 (考えてみてください。ほとんどのヒープが交換されている間にアプリケーションを終了します。ページはメモリに読み込まれることなく完全に破棄される可能性があります。

ただし、これによりスワップページが消去されるため、次回スクリプトを実行するときにスワップページを再作成する必要があります。

さて、スワップからメインメモリにコピーされたほぼすべてのページは変更されるので、後でスワップに戻す必要がある場合は、とにかくスワップで書き直す必要があります。スワップ領域は、読み取り専用ページ(通常はファイルとしてサポートされています)ではなく、主にヒープメモリであることを覚えておいてください。

私はあなたのswapoff -a && swapon -aトリックがあなたが思い出すことができるのと同じくらい素晴らしいと思います。

答え3

に基づいてメモリダンパー最初に発見ここ指定されたアプリケーションを選択的にメモリに読み込むスクリプトを作成しました。remember:

#!/bin/bash
declare -A Q
for i in "$@"; do
    E=$(readlink /proc/$i/exe);
    if [ -z "$E" ]; then
        #echo skipped $i;
        continue;
    fi
    if echo $E | grep -qF memdump; then
        #echo skipped $i >&2;
        continue;
    fi
    if [ -n "${Q[${E}]}" ]; then
        #echo already $i >&2;
        continue;
    fi
    echo "$i $E" >&2
    memdump $i 2> /dev/null
    Q[$E]=$i
done | pv -c -i 2 > /dev/null

使用法: 類似

# ./remember $(< /mnt/cgroup/tasks )
1 /sbin/init
882 /bin/bash
1301 /usr/bin/hexchat
...
2.21GiB 0:00:02 [ 1.1GiB/s] [  <=>     ]
...
6838 /sbin/agetty
11.6GiB 0:00:10 [1.16GiB/s] [      <=> ]
...
23.7GiB 0:00:38 [ 637MiB/s] [   <=>    ]
# 

スワップされていないメモリ(1秒あたりギガバイト)をすばやくスキップし、スワップが必要なときに速度が遅くなります。

答え4

ここには非常に良い議論がありますhttp://rudd-o.com/en/linux-and-free-software/tales-from-反応性ランド-why-linux-feels-slow-and-how-to-fix-that これは最終的に交換可能性を減らすことにつながります。つまり、システムの認識された応答性を向上させるには、コードが交換されるのを防ぐ必要があるという考えです(これが起こります)。これは実際にあなたの質問に対する答えではありませんが、問題を防ぐことができます(アプリケーションは交換されず、未使用のデータとページキャッシュのみが置き換えられます)。

関連情報