見出し画像

DTMer向けメモリと仮想メモリとスワップの説明

本職のSEやプログラマでもメモリについて誤解をしている方々を見かけることがあります。実は仮想メモリの消費量と、実装するべき物理メモリ量は必ずしもイコールでは無いのです。DTMはCPUとメモリを潤沢に必要とするアプリケーションなので、メモリのことは気になると思います。本稿では、DTMerの皆さん向けに、メモリについてのご説明をしようと思います。

仮想メモリ≠スワップ

たとえば16GBの物理メモリを実装している計算機で、あるアプリケーションが32GBytesの仮想メモリを要求したとします。仮想メモリ=スワップという理解をしていると、スワップが多発して大量のディスクアクセスが起きてしまい、使い物にならないのでは?と考えてしまいます。

もちろんそういう結果になる可能性もあります。ただし、常にそのような結果になるとは限りません。というのは仮想メモリというのは、アプリケーションがOSに要求したメモリの総量であって、実際に消費しているメモリの量ではないからです。

仮想メモリとはアプリケーションが要求したメモリの総量

studio:~ hiro$ ps -ecO vsz,rss
  PID      VSZ    RSS   TT  STAT      TIME COMMAND
    1  4329296  16488   ??  Ss     0:05.78 launchd
   54  4305804   1272   ??  Ss     0:00.36 syslogd
   55  4334232  18824   ??  Ss     0:00.59 UserEventAgent
(省略)
  698  7406112 601628   ??  S      5:22.10 Cubase 11

これはmac OS で、Cubase Pro 11を起動してからpsというコマンドを叩いたところです。VSZという列とRSSという列に注目してください。VSZがアプリケーションがOSに要求したメモリ量。RSSが実際に物理メモリにアサインされているメモリ量です。単位はキロバイトです。このVSZが仮想メモリに当たると思ってください。

Cubase Pro 11は7Gバイトもの仮想メモリを要求しています。しかし実際に物理メモリを消費しているのはわずか600Mバイトです。

mac OSであれば、アクティビティモニタからも上記の情報にアクセスできます。アクティビティモニタを起動し、詳細を知りたいアプリをクリックして選択してから、画面上部の (i)ボタンを押します。

画像2

画像1

アクティビティモニタでは、1Mバイト=1024Kバイトで計算しているので、psコマンドの出力と見た目にずれてしまいますが同じ値を示しています。

仮想メモリのサイズと、実際に消費した物理メモリの量が一致しないというをご確認いただけたと思います。

メモリを机の広さ・ディスクを資料棚の大きさに例えるなら

ある種のパソコンの入門書ではメモリを(実作業を行うための)机の広さ、ディスク容量を資料棚の大きさに例えることがあります。この例えを使うなら、仮想メモリの量というのは、机の発注書〜ただしまだ納品されていないものを含む〜に記載のメモリ量なのです。

画像3

C言語などに詳しい方に向けて言うと、malloc()をかけるというのは、この発注書をOSに出すということなのです。OSのメモリ管理が充実していなかった時代では、メモリを有効活用にするべく、アプリケーションがmalloc()をかける量を抑えて、自前でメモリ(利用)管理をするということがありました。現在ではOSのメモリ管理が高性能であるため、メモリの利用について遠慮したりすることがなくなったのです。あらかじめ大量のメモリを確保しておくと、それらを連続した領域として使えるのでコーディングも楽になるのです。

どきどきのページフォールト

さて、要求した仮想メモリはどこかのタイミングで必要になるかもしれません。OSはこの動作を常に監視しています。発注された(納品されたことになっている)机の利用がいつされるか、、、どっきどきです。

画像4

実際には納品されていない机(メモリの領域)に対してアプリケーションがアクセスをしようとした場合、OSは割り込み(インタラプト)というのを発生させます。アプリケーションの動作に割り込んで、アプリケーションを時間停止させちゃうわけです。このようにして、まだ物理メモリへの割当をしていない仮想メモリへのアクセス要求を受けたとき、ページフォールトが発生したと言います。

ページフォールトは2つのストーリーで解決されます。

未使用の物理メモリが余っているとき

1つ目は未使用の物理メモリが余っているとき、この未使用の物理メモリをアプリケーションに割り当てることでメモリを補充します。

画像5

このように、アプリケーションが要求したときにはじめてOSがメモリを提供することをオンデマンドページングと言います。

未使用の物理メモリが在庫切れのとき1−バッファ・キャッシュの開放

もう一つの方法は・・・誰か他の人からメモリを奪ってくることです。まずターゲットにできるのは、バッファやキャッシュと呼ばれるメモリ領域です。

OSはメモリをアプリケーションだけに割り当てているわけではありません。ファイルの読み書きを高速化することを目的に、バッファやキャッシュという呼び方でメモリを利用しているのです。誰かが読んだファイルの内容を他の誰かが読むかもしれないのでメモリに残しておこうとします。また、誰かが書き込んだファイルに書き込んだ内容は、すぐにディスクに書き込まれるわけではありません。メモリの中に書き込むべき内容が溜め込まれ、ある程度データが溜めてからディスクにまとめて書き出すようにしているのです。

画像6

このようにして利用されているバッファやキャッシュは、メモリから追い出してやってもよさそうです。実際にまだ書き込まれていないキャッシュの内容はdirtyと呼ばれていて、これはもちろんディスク装置に書き出されてからメモリが再利用されることになります。

バッファやキャッシュとして利用されているメモリのうち、どのファイルに対応するバッファ・キャッシュを開放するかの選択は、OSのメモリ管理の実装によります。一般的にはLRU(Least Recently Used)〜最近使ってないヤツをターゲットにするというアルゴリズムが使われており、なるべくアプリケーションプロセスを邪魔しないような工夫をしています。

未使用の物理メモリが在庫切れのとき2−スワップの利用

物理メモリを確保するストーリーはもう一つあります。それは誰か他のプロセスが使っている物理メモリを拝借することです。バッファやキャッシュのときのように単純に開放してしまうと、もともとのメモリの利用者が再度そのメモリを利用しようとしたときに困ったことになりますから、その内容をディスクに書き出して保全しておく必要があります。このように将来の再利用に備えてメモリの内容をファイルに書き出しておくこと、あるいはファイルに書き出されたメモリの内容を物理メモリに読み戻すことをスワップ(交換)というのです。

OSは各プロセスからのメモリの利用状況を常に監視しています。そして、利用頻度の少ないメモリ領域に目をつけておき、スワップの候補としておきます。

画像7

このようにしてOSはなるべくプロセスへの影響を与えないように努力しながら、物理メモリをやりくりしているのです。

スワップに追加してメモリ圧縮も

近代的なOSではスワップに加えてメモリ圧縮の技術も使われています。原理は簡単です。LRUの対象領域をディスクに書き出す(スワップ)のではなく、その内容を圧縮することで物理メモリに空き容量を作ろうとするわけです。

これは特にコア数の多いCPUを実装している計算機で有効な方式です。アプリケーションがすべてのコアを使い切れていないとき、アイドリングしているプロセッサコアを使って未使用領域を圧縮してやることができれば、余計なディスクIO負荷なしに物理メモリの空き容量を作ることができます。

画像8

mac OSのアクティビティモニタでは、使用済みメモリの中に圧縮という項目を確認できます。これは使用頻度の低いメモリの内容が圧縮された状態で保全されていることを意味しています。

このような表示を見たら、ふぅむ、うちの子は賢いなぁと、OSを褒めてあげたら良いんじゃないかと思います←

スワップは0であるべきか?

計算機が市民権を得たのはWindows95のブームが起きた頃であろうと、私は記憶しています。当時は物理メモリの実装量が少なく、かつCPUやOSのメモリ管理能力が洗練されていなかったこともあり、物理メモリの実装量が少ない個体ではスワップを多発していました。ちょっと重たい仕事をさせると、すぐにガリガリガリガリとスワップを発生させ閉口してしまった記憶をお持ちの方も多いと思います。

その当時の記憶をお持ちの方からしたら、スワップというのはなんとしてでも発生しないように、それを回避するべきものという意識があるかもしれません。しかし、必ずしもスワップは悪ではないのです。利用されることの無いデータが物理メモリを長期間に渡って占拠してしまうくらいなら、その内容をスワップアウトして、バッファやキャッシュとして利用した方が全体のパフォーマンスが向上することがあります。

一つの顕著な例がJITコンパイラに関連する技術です。Rosetta/Rosetta 2を思い出してください。(Rosetta 2ではあらかじめAMD64の命令セットをAArch64の命令セットに変換する機能もあるようですが、それはさておき・・・)Rosettaは、PowerPC用の機械語で書かれたアプリケーションバイナリを、実行時にIntel用の機械語に翻訳する機能が提供されていました。このような機能は一般的にJIT コンパイラと呼ばれます。JITはJust In Timeの略です。JITコンパイラはそれ自体が高度なプログラミング技術で構成された、アプリケーションプログラムです。当然のように物理メモリを消費しながら、機械語の翻訳を行ってくれるわけです。大変優秀なJITコンパイラですが、プログラムの翻訳があらかた完了してしまえば(この表現に私の妥協を感じてもらえると嬉しいです←)自分自身を物理メモリに残しておく必要はなくなります。そこでJITコンパイラは、自分自身のプログラム本体を保持するメモリ領域(code segment/text section)がスワップアウトされるのをOSにまかせてしまうのです。

というわけでスワップの利用があることは、必ずしも悪ではないのです。むしろスワップアウトすることで、メモリが有効に活用されるようになることが多いのです。スワップちゃんの事を嫌いにならないであげてください。本当に注目するべき問題はスワップの頻度なのです。

そもそも仮想メモリとは

仮想メモリがスワップと同じ意味の言葉でないことはご納得いただけたと思います。仮想メモリという言葉に空間という言葉を補って、仮想メモリ空間と考えてもらったほうが良いと私は考えています。

Window95よりも前の世界、そこにはMS-DOSというOSが世界を支配していました←言い過ぎ💦 ここではMS-DOSを引き合いに出すことで、仮想メモリ空間という言葉の意味合いをご説明させてください。

MS-DOSというOSはマルチタスクのOSではありません。同時に起動できるアプリケーションの数は一つだけです。WORDを文章を書きながら、EXCELで表計算をするということはできないのです。OSが同時に実行することができるアプリケーションは一つだけです。そのためアプリケーションは、PC本体のメモリ空間をある程度自由に使うことができました。自分以外のアプリケーションの存在を意識する必要は無かったのです。

しかし、Windows95以降の世界では、マルチタスクが当たり前になりました。マルチタスクのOSでは、複数のアプリケーションを同時に実行することができます。ということは、アプリケーションは計算機本体のメモリを自由に使うことができなくなったのです。

画像9

図に示したように、アプリケーションのメモリが物理メモリ上に連続して存在している保証はありません。あるアプリケーションが触っている物理メモリ領域のすぐ隣は、別のアプリケーションが使っているかもしれません。マルチタスクを実現するOSでは、CPUやMMU(Memory Management Unit)の力を使って、互いのアプリケーションの物理メモリ領域を保護してあげているのです。これをメモリ保護(memory protection)と言います。さらにOSは、アプリケーションから見たときに、個々のアプリケーションがあたかもひとつながりのメモリ領域が確保されているかのように、仮想的なメモリ空間を提供してくれるのです。ひとつながりの秘宝はこんなところにあったんですね。びば。わんぴーす。

一般保護違反とは

以下、蛇足です。ここでメモリ保護という言葉が出てきました。あるアプリケーションが、他のアプリケーションのメモリを保護する仕組みのことでした。それでは、この禁を破って(笑)あえて自アプリケーションが確保しているメモリ以外の場所にアクセスをしたらどうなるでしょうか。このようなときにOSが発生させるのがGenral Protection Fault(一般保護違反)、Segmentation FaultあるいはSegmentation Violationと呼ばれるエラーなのです。CやC++といった、メモリに対する直接指定アクセスを行うことのできる言語で発生しやすい問題です。

とはいえこのようなメモリアクセスについてのエラーは、ソフトウェア的な理由からだけで起こるものではありません。ハードウェアとの通信がmmapを介して行われている場合(説明無しですみません。そろそろ子供をお風呂に入れないと・・・)メモリにアクセスできなかった=ハードウェアが適切に動作しなかったという意味になるのです。ですから、特定のハードウェアを利用しているときにこのようなエラーが頻出する場合には、ハードウェアの故障も疑ってください。

おわりに

DTMerに限らず、いえIT業界で仕事をしている専門家たちでも、仮想メモリのことをふんわりと理解したままでいる人が沢山いらっしゃいます。むしろ仮想メモリの事を強く意識しなくても計算機を使うことができるというのは、OSを中心とした仮想メモリについての技術の優秀さがあればこそ、です。

とはいえスワップと仮想メモリを混同したままにしてしまうと、今後のPC/macの購入時に適切なスペックのものを選べなくなるかもしれません。特に新しいM1 (Apple Silicon)ではRosetta 2が稼働することもあり、アプリケーション本体が必要とするメモリ量がわかりにくい状況がしばらく続くものと思われます。いろんな思惑を持った人が、いろんな色の解説記事を出す状況がしばらく続くのだと思いますが、懐疑的になりすぎず、しかし、DAWソフトウェアベンダーの正式サポート発表を待って(ここ重要)新しい選択肢が増えたことを喜んでいけたら良いのではないかと思うのです。

以下投げ銭です。本文に続きはありません。



ここから先は

0字

¥ 100

期間限定 PayPay支払いすると抽選でお得に!

この記事が気に入ったらサポートをしてみませんか?