フリーズ
フリーズ(英: freeze)は、コンピュータまたはソフトウェアが何らかの原因によって応答しなくなる状態を示す。Linux カーネルや macOS におけるカーネルパニックもフリーズの一種である。
同義語
[編集]日本語では「固まる」という言い換え方もある。また、ハングアップ(英: hang[1])やストール(英: stall)とも言う。
モバイルオペレーティングシステムのAndroidでは、ANR (Application Not Responding) と呼ばれる[2]。
概要
[編集]フリーズの原因は様々である。例えばソフトウェアやデバイスドライバのバグ、物理メモリのエラーやCPUの熱暴走などの物理的な問題[注釈 1]が挙げられる。ユーザーからの入力に対してコンピュータが何らかの反応はするが、それが期待されたものではない(間違っている)ときには「不具合」「バグ」「誤動作」というのが普通であり、「フリーズする」とは言わない。ただし、ソフトウェアのバグによって無限ループやデッドロックに陥ることで処理が先に進まなくなり、フリーズしてしまうことはありえる。
オペレーティングシステム (OS) やデバイスドライバやハードウェアなどのシステムの重要な部分で問題が発生した場合、システム全体がフリーズすることがある。システム全体のフリーズから復旧するにはコンピュータの再起動が必要となる。プリエンプティブなマルチタスクOSの場合には、アプリケーションがフリーズしてもシステム全体や他のアプリケーションに影響は発生しない。フリーズしたアプリケーションは、OSの機能を利用して強制終了させることができる。MS-DOSやWindows 3.xやClassic Mac OSなどのプリエンプティブマルチタスクではないOSの場合にはシステムに制御を戻せないため、アプリケーションがフリーズするだけでもコンピュータの再起動が必要となることがある[注釈 2]。
Microsoft Windowsではアプリケーションがフリーズすると、通例アプリケーション名などが表示されているウィンドウのタイトルバー部分の文字列末尾に「(応答なし)」と表示される[注釈 3]。Windowsに限らず、GUIアプリケーションのメインスレッド(ユーザーインターフェイススレッド)はイベントループ(メッセージループ)を持ち、マウスボタンのクリックやキーボード押下といったユーザー入力イベントに対する応答をできる限り速やかに返すことが求められるが、このメインスレッドで定期的なイベント処理をせずに長時間かかる別の処理を実行したり、ロジックミスによって無限ループやデッドロックに陥ったりすると、フリーズが容易に発生する。長時間「応答なし」のままであればアプリケーションに回復不可能な問題が発生していると推測できるが、単に内部的な処理に時間がかかっているだけで問題なく動作している場合は、処理が完了するまで一定時間待機することで応答が回復し、ユーザーが再び操作できるようになる可能性がある。ただし、そのような内部事情はエンドユーザーには分からず、アプリケーションが頻繁に応答不能になるとユーザーのストレスが増大するため、そのような動作は避けるべきである。もし回復の見込みがないとユーザーに判断された場合、タスクマネージャーなどからアプリケーションのプロセスを強制終了されてしまい、処理の途中で無理やり中断されたことによって重要なファイルが破損してしまうなどの重篤な問題が起きる可能性もある。
対策
[編集]アプリケーションの場合、ユーザー応答をつかさどるメインスレッドで長時間かかる処理を直接実行することは避けるべきである。特にストレージI/Oやネットワーク接続・通信といった処理は、完了までにかかる時間が予測できず、他のプロセスによってハードウェアリソースが先に占有されている場合は、リクエストが後回しにされてしまい、完了までに想定以上の時間を要することもある。何らかのサブルーチンを呼び出し、処理結果を戻り値などで直接受け取るブロッキング処理や同期処理はプログラミングが簡単になるが、フリーズを引き起こしやすい。タイムアウト時間指定付きのブロッキング処理を用いる方法もあるが、これだけでは根本的な解決策にはならない。フリーズを避けるために、処理に時間がかかる場合は否定応答を即座に返すノンブロッキング処理や、いったんリクエストを発行して後からコールバックにより結果を受け取る非同期処理を利用する必要がある。例えばI/Oやネットワーク処理はサブスレッド(ワーカースレッド)や別のサービスプロセスなどに委譲し、メインスレッドは結果通知を受けてその後の処理を再開・続行するなどすべきである。長時間かかる処理はバックグラウンドで実行することにより、アプリケーションのメインスレッドは応答性を維持したままにすることができる[5]。
従来、非同期処理はプログラミングが難しくなりがちだったが、モダンなプログラミング言語やプログラミング環境では、Future パターンやasync/await構文を使って簡潔に記述できるようになっている。
サブスレッドでの非同期処理の結果が返ってくるまでの間、メインスレッドは自由になるが、処理の進捗状況を示すプログレスバーを画面上に表示するなどして、アプリケーションの動作状況をユーザーに知らせるべきである[6][7]。複数のデータを処理したり、ファイルを読み書きしたりする場合、全体のうちどのくらいが処理できたのかという進捗率や、完了までにかかるおおよその見積もり時間を画面上に何らかの形態で適宜示すことによって、アプリケーションがフリーズしておらず処理を続行中であることが明確になり、ユーザーのストレスを軽減し、体感的な待ち時間を減らすことができる。途中でキャンセルが可能な処理であれば、ダイアログなどの上にキャンセルボタンを用意し、ユーザーからキャンセルが指示された場合はできる限り速やかに処理を中断して応答を返すべきである。
脚注
[編集]注釈
[編集]- ^ ファミリーコンピュータのように衝撃に弱いゲーム機では接触不良によってゲームがフリーズしてしまうことがある。この場合、通例ゲーム機をリセットするしか回復手段がなく、バッテリーバックアップなどによる進行状況のデータ保存機能を持たないゲームでは最初からやり直しになってしまう。CDなどの光学メディアを採用したゲーム機は、ピックアップレンズの劣化により読み取り不良が多発してゲームがフリーズしてしまうこともある。いずれもゲームプログラムのソフトウェア的なバグとは無関係に発生しうる。
- ^ Microsoft Windows 95はプリエンプティブマルチタスクに対応した32ビットOSだったが[3]、互換性維持のために16ビットモジュールが残されており、32ビットコードはプリエンプティブに動作していたものの、16ビットコードは協調的マルチタスクのままだった[4]。Windows 9x系は純然たる32ビットOSとして設計されたWindows NT系よりも安定性に劣り、アプリケーションのフリーズやクラッシュがOS全体を巻き込んだフリーズやクラッシュ(ブルースクリーン)につながることもよくあった。
- ^ 英語版では「(Not Responding)」と表示される。
出典
[編集]- ^ Preventing Hangs in Windows Applications - Win32 apps | Microsoft Learn
- ^ ANR | App quality | Android Developers
- ^ Windows 95とは - 意味をわかりやすく - IT用語辞典 e-Words
- ^ ASCII.jp:マルチコアCPUを賢く使いこなす スケジューリングの秘密 (1/3)
- ^ 非同期プログラミング - UWP applications | Microsoft Learn
- ^ Progress Bars - Win32 apps | Microsoft Learn
- ^ アプリの応答性を維持する | App quality | Android Developers