仮想メモリは、オペレーティングシステム(OS)を構成する最も重要な要素の1つです。Linuxの仮想メモリは、他のOSとは異なる仕組みで動作します。
Linuxの仮想メモリは、コピーオンライト、デマンドページング、ページエージングなどのさまざまな技術を使用し、冗長または不要な処理をディスクに移すことでパフォーマンスを向上させます。
この記事では、Linuxの仮想メモリの仕組みを解説し、自分のLinuxマシンで仮想メモリを設定する方法を簡単に紹介します。
Linuxで仮想メモリが動作する仕組み
仮想メモリは一般に、システムの物理RAMを拡張するためだけに使われるものだと考えられています。しかし、Linuxの技術と仮想メモリのコンポーネントは、より高度な処理を実行します。
Linuxの仮想メモリを使うと、すべてのプロセスのすべてのアドレスを同時にマッピングできるだけの物理メモリがなくても、各プロセスに独自のプライベートアドレス空間を持たせることができます。
これは「ページング」と呼ばれる技術によって実現されます。ページングは基本的に、使用頻度に応じてメモリを物理メモリからディスクストレージへ、またはその逆へ移動します。
ページングによって、各プロセスには必要な量のメモリだけが割り当てられます。例えば、新しいプロセスが作成されると、OSは仮想アドレス空間を作成します。しかし、このアドレス空間はプロセス自体より「大きい」ため、OSはプロセスに必要なメモリページを特定します。その後、プロセスが必要としないすべてのページは、スワップファイルまたはスワップパーティション内のディスクに保持されます。
Linuxの仮想メモリ技術
Linuxの仮想メモリ技術を使うと、通常なら不可能な数のプロセスを実行したり、複数のプロセスを同時に実行したり、利用可能な物理メモリをすべて使用したりできます。
Linuxの仮想メモリ技術には、コピーオンライト、デマンドページング、ページエージングがあります。
- コピーオンライト:新しいメモリページを作成する際、Linuxはページ用に新しい物理メモリを割り当てず、ページの仮想アドレスを作成して、そのページを「共有」としてマークします。プロセスがページへの書き込みを試みると、OSは、そのページが別のプロセスによってすでに使用されていない場合にのみ物理メモリへ書き込みます。複数のプロセスが同じデータを使用している場合など、物理メモリを大幅に節約できます。
- デマンドページング:Linuxが物理メモリにロードするのは、プロセスが要求またはアクセスしようとするメモリページだけです。この技術には、頻繁に必要とされないページをロードしないことでパフォーマンスを高速化できるという利点があります。
- ページエージング:Linuxの仮想メモリは、使用中のすべてのメモリページを追跡します。非アクティブなページやアクセス頻度の低いページはディスクにスワップアウトされる可能性が高く、最も頻繁に使用されるページは物理メモリに保持されます。
バディアロケーターとスラブアロケーター
Linuxカーネルには、バディアロケーターとスラブアロケーターという2つの主要なメモリアロケーターがあります。
バディアロケーター
バディアロケーターはメモリ管理ユニット(MMU)と直接やり取りし、カーネルから要求されたときに有効なページを提供します。また、ページのリストを管理し、メモリアドレスのさまざまなカテゴリを追跡します。
バディアロケーターは汎用メモリアロケーターであり、任意のサイズのメモリを割り当てるために使用できます。メモリをブロックの二分木に分割して動作します。プロセスがメモリを要求するたびに、要求を満たすのに十分な大きさを持つ最小のブロックを見つけ、そのブロックをプロセスに割り当てます。
スラブアロケーター
スラブアロケーターはバディアロケーターの上位層で、メモリ内にオブジェクトのキャッシュを作成できます。小さなオブジェクト用のメモリを割り当てるために使用されます。
スラブアロケーターは、同じサイズのオブジェクトをスラブにまとめます。プロセスがオブジェクトを要求すると、スラブアロケーターはキャッシュを確認し、そのオブジェクトがすでにメモリ内にあるかどうかを判断します。
オブジェクトがメモリ内にある場合、スラブアロケーターはそのオブジェクトをプロセスに返します。メモリ内にない場合、スラブアロケーターはキャッシュから新しいオブジェクトを割り当て、そのオブジェクトをプロセスに返します。
Linuxのメモリページ
Linuxでは、仮想メモリ内のページを次のように分類します。
- 空きページ:その時点でどのプロセスにも使用されておらず、必要とするプロセスに割り当て可能なメモリページ。
- アクティブページ:1つ以上のプロセスが使用中のメモリページ。使用されなくなるまで、他のプロセスは利用できません。
- 非アクティブページ:どのプロセスにも使用されておらず、最後にディスクから読み込まれて以降変更されていないメモリページ。これらのページは、物理メモリを解放するためにディスクへスワップアウトできます。
- ダーティページ:1つ以上のプロセスが使用中で、最近変更されたページを指します。スワップするには、これらのページを書き込む必要があります。
Linuxカーネルのタスク
Linuxには、仮想メモリ管理の特定の側面を担うカーネルタスクもいくつかあります。
例えば、ページフォールトハンドラーはページフォールトの管理を担い、プロセスが物理メモリにないメモリページへアクセスしようとしたときに起動します。ページフォールトハンドラーはディスクからページを物理メモリに読み込み、プロセスの実行を再開します。
メモリページャーはメモリページをディスクへスワップする役割を担います。物理メモリを解放する必要があるときにOSによって使用されます。メモリページャーは、使用頻度の低いメモリページを特定して、スワップするページを選択します。
同様に、ページリクレーマーはディスクへスワップアウトされたメモリページを物理メモリに戻します。プロセスがこれらのページへのアクセスを要求したときに起動します。
調整可能なパラメーターを使ってLinuxの仮想メモリを設定する
調整可能なパラメーターは、システムのパフォーマンスを向上させるために変更できるカーネル設定です。リアルタイムでsysctlコマンド/etc/sysctl.confファイルを使って変更できます。
パラメーターの変更はシステムに悪影響を及ぼし、パフォーマンスに影響する可能性があることを忘れないでください。
仮想メモリに関する最も重要な調整可能パラメーターを見ていきましょう。
Vm.Swappiness
vm.swappinessは、カーネルがメモリページをどの程度積極的にディスクへスワップアウトするかを制御するパラメーターです。
値を0に設定すると、カーネルはメモリページを一切スワップアウトしません。100に設定すると、カーネルはメモリページが使用されなくなり次第、すぐに、かつ高速にスワップアウトします。デフォルトで設定されている値は60.
例えば、vm.swappinessを10に設定するには、次のコマンドを使用します。
sysctl -w vm.swappiness=10VM.Dirty_Ratio
このパラメーターを使うと、ダーティページをディスクへ書き込み始める前に、カーネルのライトバックキャッシュをどこまで満たせるかを制御できます。
ここでも、vm.dirty_ratioを0に設定すると、カーネルはダーティページをディスクへ一切書き込みません。100に設定すると、ダーティページになった時点ですぐにディスクへ書き込みます。システムのデフォルト値は20.
このパラメーターを80 リアルタイムで、直ちに変更するには、次のコマンドを使用します。
sysctl -w vm.dirty_ratio=80Vm.Dirty_Background_Ratio
vm.dirty_background_ratioは、バックグラウンドでダーティページをディスクへ書き込み始める前に、カーネルのライトバックがどこまで満たされるかを定義します。
を0に設定すると、バックグラウンドではダーティページが書き込まれません。一方、100に設定すると、カーネルはダーティページになった時点ですぐに、バックグラウンドでダーティページをディスクへ書き込みます。デフォルト値は10.
このパラメーターを25 に設定するコードは次のとおりです。
sysctl -w vm.dirty_background_ratio=25これにより、パラメーターは直ちに25に切り替わります。この例では、ライトバックキャッシュが25%満たされた時点で、カーネルはバックグラウンドでダーティページをディスクへ書き込み始めます。これにより、ダーティページがディスクへ書き込まれるのが遅くなりすぎるのを防げます。
ライトバックキャッシュが満杯になりすぎると、カーネルはフォアグラウンドでダーティページをディスクへ書き始める必要が生じ、目立った速度低下を引き起こす可能性があります。
Linuxでメモリを管理するためのベストプラクティスとは?
Linuxシステムで仮想メモリを管理する際には、いくつかの技術と有効な方法があります。
スワップファイルやパーティション、つまりハードドライブの一部を使って、どのプロセスにも使用されていないメモリページを保存できます。これにより物理メモリが解放され、パフォーマンスが向上します。
システムの物理メモリ容量(free -h)、必要なスワップ領域の容量(free -h | grep -i swap)、仮想メモリの状態(free -h | grep -i swap).
を確認することもできます。コンピューターを良好な状態に保つ、使用していないアプリケーションを閉じる、不要なファイルを削除するといった、その他の一般的な対策も仮想メモリの管理改善に役立ちます。
Linuxカーネルは新機能やバグ修正を継続的にリリースしているため、Linux OSを常に最新の状態に保つことが重要です。
まとめ:パフォーマンス向上のためにLinuxの仮想メモリを活用する
Linuxの仮想メモリは優れた機能ですが、その仕組みを理解することがパフォーマンス向上には不可欠です。
この記事で得た、仕組みやページの定義・分類、利用される技術、システムをより適切に設定するために最もよく使われるパラメーターに関する知識があれば、この有用な機能を活用し始められるはずです。
パラメーターをリセットするとシステムに悪影響を及ぼす可能性があり、テストも必要になることを常に覚えておいてください。ただし、注意して適切な手順を踏めば、パフォーマンスを大幅に向上させられます。
サーバーのパフォーマンスをさらに高めるための最適なネットワーク仮想化ソフトウェアを分析・選定・レビューしました。