【衝撃の事実】再起動しないと、コンピュータがおかしくなる原因

校長
校長
Cover Image for 【衝撃の事実】再起動しないと、コンピュータがおかしくなる原因

はじめに

どうも私立YouTube高専校長です。

普段、何気なく、パソコンやスマートフォンを使っていると、 なんか調子悪いなぁとか、遅いなぁとか、感じることがあると思います。

こういうユーザー体験って、はっきり言って、めちゃくちゃ、ストレスですよね。 私の友人は、MacBook Proを殴って、拳を画面に貫通させていました。

しかし、経験的に、このような症状は、再起動すると直るということも、ご存知だと思います。

これは、まるで、コンピュータが定期的に睡眠を要求するかのような出来事です。

私たち人間は、長時間労働すると、パフォーマンスが落ちていきますが、 睡眠をとると、頭がリフレッシュして、パフォーマンスが戻ります。

しかし、コンピュータは人間でもありませんし、生物ですらありません。 彼らは、本質的には、電気回路です。

コンピュータは、ChatGPTだの、AIだの、色々な呼ばれ方がありますが、 どれだけソフトウェアが発達しても、結局は電気回路に過ぎません。 そして、電気回路の動きを支配する物理法則は、何時間稼働させようとも、不変のはずです。 例えば、オームの法則は、何億年経とうが、オームの法則です。

それでは、なぜ、コンピュータでは、このような不思議な現象が起きるのでしょうか? コンピュータのような、複雑な電気回路には、思考が宿るんでしょうか? いいえ、そんなオカルト話ではありません。

コンピュータが再起動が必要としてしまう理由は、技術的に明確で、 それは実は、ハードウェアというよりも、メモリリークと呼ばれるソフトウェアバグに由来しています。 これは、ソフトウェアエンジニアを、長年悩ませている問題で、現在でも、それを根本的に解決する手段はありません。

これは、サーバーのような、長時間安定して稼働させる事を要求されるシステムにおいては、特に、致命的な課題です。

そして、ソフトウェアを開発するエンジニアは、このような、課題を理解しておかないと、 知らず知らずのうちに、コンピュータに負荷をかけ、再起動を必要とさせてしまうような、 悪影響を及ぼすソフトウェアを開発してしまいます。

そこで、本日は、コンピュータが再起動を必要としてしまう理由と、 それを防ぐために、ソフトウェアエンジニアが注意すべき点をご紹介したいと思います。

再起動しなくても、動き続けるような高信頼性のシステムを作りあげるためには、 全てのソフトウェアが、今日ご紹介する、注意点に従って作られている必要があるので、 現在、あるいは将来、ソフトウェアを世に出す人には、例外なく、全員見ておいて頂けたらと思います。

また今回ご紹介する情報以外にも、我々は、日本の技術者の技術力向上に向けて、 5年後も10年後も役立つ、有益な技術情報を日本語で分かりやすく発信しているので、 そういった動画を見逃したくない方は、今のうちにチャンネル登録しておいて貰えればと思います。

今後は、もっと組織化して、コンピュータ科学だけでなく、 古今東西あらゆる分野のテクノロジーを解説していきたいと思うので、 是非、応援よろしくお願いします。

それでは、本編どうぞ。

再起動が必要な理由

それでは、再起動が必要な理由を説明する上で、 そもそも、パソコンやスマートフォンを長時間稼働させていると、 遅くなったり、調子が悪くなったりする理由をざっくりと解説したいと思います。

基本的な前提として、CPUやメモリ等のハードウェアは、適切な電源や温度で動かす限り、相当な時間、連続運転できるように、設計・検証されています。 つまり、ハード的には、たった数日や数週間で、再起動が必要となるような制約はありません。

では、なぜ、たった数日稼働させるだけでこのような不思議なことが起きてしまうのでしょうか?

それは、ずばりメモリの状態にあります。

メモリの状態を決めるのは、ソフトウェアなので、要は、ソフトウェアのバグが根本的な原因なのです。

ここで言及しているメモリは、いわゆるSRAMやDRAMのことで、揮発メモリの事です。 揮発メモリは、再起動することで、メモリの内容がリセットされるので、再起動すると、コンピュータの調子が戻るのです。

これがあたかも、人間が睡眠によって、パフォーマンスが向上するように見える理由です。 記憶がリセットされるという意味では、あながち睡眠というのも、間違った比喩ではないのです。

逆に、コンピュータには、スリープモードというものもありますが、あれで直らない理由は、 スリープモードでは、メモリの状態がリセットされないからです。 電源を落とすことが、コンピュータにとっての睡眠です。 なので、たまには電源を落として上げてください。

それでは、次は、具体的にどのようなバグを作り込むと、このような再起動しない限り、 復旧できないようなメモリの状態に陥ってしまうのか、技術者目線で、より深く説明したいと思います。

話の流れ

ここからは、ちょっと話が複雑なので、事前に話の流れを共有して置こうと思います。 まずは、物理メモリの使用率が上がると、コンピュータは遅くなるという話をしたいと思います。 そのうえで、なぜ物理メモリの使用率が上がるとコンピュータが遅くなるかということで、 キャッシュ、スラッシング、仮想メモリというキーワードをご紹介します。

そのあとで、では一体なぜ、それが、再起動しない限り、復旧できないような状態になってしまうのか、ということで、 メモリリークについて、解説したいと思います。

そして最後に、長時間稼働でコンピュータの挙動がおかしくなる理由ということで、宇宙線によるメモリ化けの話も面白いので、ついでにご紹介したいと思います。

遅くなる原因

それでは、先ほどメモリの状態がリセットされるので、コンピュータが直るという話をしましたが、 そもそも、メモリがどのような状態になると、コンピュータのパフォーマンスが落ちてしまうのか、考えてみましょう。

結論から言うと、物理メモリの使用率が高くなると、コンピュータのパフォーマンスというのは、落ちます。

この話を聞いても、ああ、なるほど、と腑に落ちる人は少ないんじゃないかと思います。 それは、これがCPUとメモリだけに、着目していると、非直感的な現象だからです。

素朴に考えると、たとえ、物理メモリの使用率が高かったとしても、メモリのアクセスするスピードは変わらないので、パフォーマンスは落ちないはずです。 例えば、あなたが机の引き出しから物を取り出すとき、引き出しが1個だろうが、2個だろうが、引き出しを1つ開けて物を取り出す速さは変わらないはずです。

では、なぜ物理メモリの使用率がパフォーマンスに影響するのでしょうか?

それは、キャッシュというハードウェアの存在に依存します。 実は、CPUがメモリからデータを取り出すとき、直接メモリから取り出すのではなく、一度キャッシュという、 より高速な記憶素子に置いてから、取り出します。 これは、キャッシュは、メモリより高速にアクセスできるので、次に、同じデータにアクセスが必要になったときに、より速くアクセス出来るようにするためです。

これは、あなたが引き出しから物を取り出すときに、一旦、机の上に置いてから、取り出すようなものです。 そうすると、次にその物を使いたい時は、机の上に置いてあるので、もう一度、引き出しを開けて、取り出すより、速く取り出すことができます。

ちなみに、先ほど一瞬名前を出した、SRAMというのは、このキャッシュの事です。CPUの近いところにあります。

そして、ここで重要なのは、実は、このキャッシュの大きさというのは、 メモリに比べて非常に小さいです。これは、ハードウェアの設計上の制約です。 なので、キャッシュに置けるデータの数には、限りがあります。 したがって、一般的に、キャッシュは、使用頻度の高いデータを置くような仕組みになっています。

これが、一番効率がいいキャッシュの使い方であることは、経験的に理解できると思います。 使用頻度の低いものを、わざわざ、机の上には置いては、おかないですよね?

はい、それでは、今の説明で、キャッシュの仕組みがなんとなくわかったと思うので、 物理メモリの使用率が高いと、なにが起きるのか想像してみましょう。

物理メモリの使用率が高いという事は、沢山の引き出しから、物を出し入れする必要があるということです。 しかし、沢山の引き出しで、物を出し入れしなればならないにもかかわらず、机の上には、使用頻度の高いものしか置けません。

そうすると、自然と、欲しい物が、机の上に置いてある可能性というのは、どんどん低くなっています。

結果的に、物理メモリの使用率が高いときは、引き出しを開け閉めする回数が増えてしまいまい、パフォーマンスが大幅に悪化します。 これを専門用語で、キャッシュヒット率の低下といいます。

たかが、キャッシュが使えないだけで、そんなに遅くなるものかと思うかもしれませんが、メモリのアクセスというのは、キャッシュに比べて数十倍遅いです。 したがって、キャッシュが効かなくなると、コンピュータのパフォーマンスは非常に悪くなります。

これが、物理メモリの使用率が高いことによって生じる、パソコンやスマートフォンが遅くなる現象で、スラッシングと呼ばれます。

ちなみに、設定にもよりますが、さらに物理メモリの使用率が上がり、物理メモリが足りなくなると、仮想メモリという機能が働き、ストレージをメモリとして使うようになります。 そして、ストレージは、メモリより、さらに遅いです。 これは、机の引き出しでは、足りなくなったので、足りない分を、歩いて、棚に収納するようなものです。

この、ストレージとメモリの間で、データを出し入れする行為をスワップといい、これは、パフォーマンスをさらに悪化させます。 特に、ストレージがハードディスクの場合はアクセスがめちゃくちゃ遅いので、ハードディスクでスワップをすると、目も当てられません。

ちなみに、スワップは、キャッシュをメモリ、メモリをストレージに置き換えて、抽象化して考えれば、 先ほど説明したスラッシングと全く同じ現象なので、これも、スラッシングと呼ばれます。

このように物理メモリの使用率やスワップの使用状況はシステムのパフォーマンスに大きな影響を与えるので、Linuxのコマンドで監視することができます。

監視方法は、いろいろなノウハウがありまして、 今回の動画の準備で、下記の記事を読みましたが、非常に面白かったので、興味があれば、是非読んでみて下さい。

https://atmarkit.itmedia.co.jp/ait/articles/0810/01/news134.html

リクエストがあれば、他の動画で紹介したいと思います。

再起動が必要な理由

ここまでの、説明で、物理メモリの使用率が上がると、スラッシングという現象が発生し、 コンピュータのパフォーマンスに悪影響を与えるという事が理解できたと思います。

しかし、これだけでは、なぜ再起動しない限り、物理メモリの使用率が下げられないのか、分からないと思います。

パソコンやスマートフォンでは、多数のプロセスが1つの物理メモリを共有して使っています。 それぞれが、勝手にメモリを使うことはできないので、OSが仮想アドレスという機能によって、メモリをうまく管理してくれています。

いずれにせよ、プロセスが増えれば増えるほど、物理メモリの使用率は高くなります。 しかし、通常、プロセスを殺せば、メモリは解放されるので、再起動の必要は無いはずです。

ところが、ある種の状況では、物理メモリの使用率がどんどんどんどん、上がっていってしまうのです。 それは、一体どのような状況なのでしょうか?

それが、本日のメインテーマである"メモリリーク"です。

メモリリークとは、ソフトウェアが確保したメモリを、解放し忘れるというポカミスによるバグです。 このバグを作ってしまうと、実質的なメモリ容量がどんどん小さくなっていってしまいます。 これが、リーク(漏洩)と呼ばれる所以です。

具体的にどのようなバグかというと、例えば、C++言語で、new演算子で、インスタンスを作ると、ヒープ領域にメモリを確保して、インスタンスが生成されます。 そして、本来ならば、インスタンスを使い終わったら、インスタンスを破棄して、ヒープ領域を解放しなければなりません。そうでないと、確保されたメモリが使用不可となり、メモリ容量を実質的に減らしてしまいます。

例えば、あなたが、ブラウザを実装していたとします。 ブラウザで新しいタブを開いたら、タブの制御に必要なメモリがヒープ領域に確保されます。 タブを閉じたら、そのメモリを解放しないといけないのに、それを忘れてしまうと、 そのメモリ領域は使用不可になります。 そして、それが解放されることは、プロセスを殺さない限り、基本的に期待できません。

特に、そのソフトを常駐させていて、殺す訳にはいかないプロセスであった場合や、 OSでメモリリークがあると、再起動しない限り、絶対に解放されることはありません。

これが、コンピュータが再起動を必要としてしまう、致命的なバグである理由です。 メモリリークは、長い間、ソフトウェアエンジニアを悩ませる種になっているので、 多くのプログラミング言語が、これを解決する手段を提案しています。

例えば、C++では、インスタンスを明示的に破棄する必要がありますが、PythonやJavaでは、ガバージコレクションという機能があるため、明示的にインスタンスを破棄しなくても、自動でメモリを解放してくれます。 しかし、その場合ガベージコレクターという、複雑なランタイムが必要になる上、パフォーマンスのオーバーヘッドも生じます。

また、Rustという近年注目の言語では、所有権とライフタイムという概念によって、コンパイル時にメモリリークを検知します。

メモリリークは、今後もソフトウェアエンジニアリング上の課題として残り続けるでしょう。銀の弾丸は、おそらくないです。

メモリリークが起きる原因は、他にもあります。 それは、ゾンビプロセスと呼ばれるものです。 ゾンビプロセスというのは、その名の通り、死に損なったプロセスです。

通常、プロセスが終了すると、メモリが全て自動的に解放されるのですが、 なんらかの原因によって、プロセスの終了に失敗すると、メモリを確保したまま不要なプロセスが残って、メモリリークが発生します。

このようなゾンビプロセスも、メモリの使用率を増大させる原因となり、再起動しない限り、解放されることはありません。 ちなみに、プロセスが殺すだの死ぬだと、乱暴な表現は、私の言葉遣いの問題ではなく、一般的な用語で、 POSIX準拠のLinuxコマンドでも、プロセスを終了させる時は、killというコマンドを使います。

以上が、コンピュータが、長時間稼働によって、パフォーマンスが落ちて、再起動が必要になってしまう理由でした。 メモリの監視や、メモリリークを起こさない事を、世にソフトウェアを出す人や、システムを運営する人は、常に注意するようにしてください。

次は、長時間稼働で挙動が"おかしくなる"原因を考えていきたいと思います。

おかしくなる原因

最後に、長時間稼働でコンピュータの挙動がおかしくなる理由についても、解説して置こうかなと思います。 これも、再起動で直るということは、結局はメモリの状態が原因ではありますが、 これまでに、説明した遅くなる理由とは、すこし根本的な原因が異なります。

まず、単純に、連続運転を続けると、バグを踏む確率がどんどん上がります。

そして、そういったバグを踏んだことで、変な一時ファイルが、残った場合、電源を落とすまで、おかしな挙動は直りません。

例えば、Linuxの/tmpディレクトリは、アプリケーションの一時ファイルの置き場として、よく使われますが、 このディレクトリの中身は、再起動すると、すべて消えるので、それによって直る事があります。

また、確率は低いですが、実は、メモリのデータは、宇宙線という空から来た電磁波によって、化ける可能性があります。 これは、ソフトエラーと呼ばれる不具合で、知っていると得することがあるネタなので、少し紹介しておきます。

宇宙線は宇宙から来る電磁波なので、エネルギーを持ちます。 そして、稀に電磁波がDRAMのコンデンサーに影響を与えて、ビットを反転させてしまうのです。

ソフトウェアにとって、データが化けるというのは、前提条件を崩されるような出来事なので、どんな不都合でも発生し得ます。

この、ソフトエラーの特徴は、、再起動すると、メモリがリセットされるので、何事も無かったかのように、コンピュータが復活すると言うことです。 つまり、何も証拠が残らないことです。そのうえ、宇宙線は再現できないので、不具合も再現できません。

したがって、ソフトウェアエンジニアの間では、バグを再現出来ない時は、 宇宙線を言い訳として使うというしょうもないジョークがあったりします。

皆さんも、バグを再現出来ない時は、是非、このネタを使ってみてください。 同僚に殴られるかもしれませんが、自己責任でお願いします。

と、冗談はさておき、実際には、宇宙線で、メモリのデータが化ける可能性は、それほど高くないです。 しかし、単純に、連続運転を続けると、宇宙線によってメモリが化ける確率はどんどん上がっていきます。

このトピックに関しても、それだけで動画が出来るくらいの濃い内容になるので、 リクエストがあれば、また動画にしようと思います。 以上が、長時間稼働するとコンピュータの動作がおかしくな原因の紹介でした。

ここまで、話を聞いていただけたら、コンピュータから、再起動の必要性を無くす、という、 一見簡単そうな、要件ですら、実は、技術的な課題が沢山詰まっているという事が分かって頂けたと思います。 したがって、多くのメーカーでは製品を出荷する前に、メモリを監視しながら、長時間稼働させる試験を行っています。

コンピュータのような、複雑なシステムは、一人では作る事ができません。 色々な人が、力を合わせて、1つのシステムが成立しています。 しかし、一つでも、メモリをリークするソフトウェアがあったら、どんどんコンピュータのパフォーマンスは落ちてしまうのです。

したがって、再起動しなくても、動き続けるような高信頼性のコンピュータシステムを作りあげるためには、OS、標準ライブラリ、ランタイム、アプリケーション、つまり、全てのソフトウェアが、正しく作られている必要があるのです。

だからこそ、そのような正しい知識を持った技術者が、あらゆる開発現場にいて欲しい。 そういう願いから、今日の動画を作りました。

私は、これからも、日本がもう一度、偉大な電子立国として立ち上がれるように技術者の教育に力を入れていきたいと思います。

これからも、こういった有益な技術情報を日本語で分かりやすく発信しているので、 そういった動画を見逃したくない方は、今のうちにいいねとチャンネル登録しておいて貰えればと思います。

今後は、もっと組織化して、コンピュータ科学だけでなく、 古今東西あらゆる分野のテクノロジーを解説していきたいと思うので、 是非、応援よろしくお願いします。

アンチコメントでも、無視されるより、マシなので、是非どしどし、コメントください。 今のところは、何とか全て返信しているはずです。 いずれは、これを学習データにして、ChatGPTをチューニングするのも、おもしろいかなと思います。 ぜひ、学習データの提供にご協力ください。

本日の動画の内容は以上になります。ここまでご視聴ありがとうございました。

リンク

Linuxトラブルシューティング探偵団 番外編