スレッドにメッセージキューがあり、ハンドラーがランナブルまたはメッセージをプッシュできることを知っていますが、Androidアプリケーションを使用してAndroid Studioツールを使用して、奇妙なプロセスがあります:
Android.os.MessageQueue.nativePollOnce
他のすべてのプロセスよりもCPUを使用します。それは何ですか、そしてCPUがそれに費やす時間をどのように減らすことができますか?プロファイラーの結果は以下で確認できます。
短い答え:
nativePollOnce
メソッドは、次のMessage
が使用可能になるまで「待機」するために使用されます。この呼び出し中に費やされた時間が長い場合、メイン(UI)スレッドは実行する実際の作業がなく、次のイベントが処理されるのを待ちます。それを心配する必要はありません。
説明:
「メイン」スレッドはUIの描画とさまざまなイベントの処理を担当するため、Runnable
にはこれらすべてのイベントを処理するループがあります。ループは Looper
によって管理され、その仕事は非常に簡単です: MessageQueue
内のすべてのメッセージを処理します。
Message
は、たとえばフレームレンダリングコールバックまたは独自の_Handler.post
_呼び出しとして、入力イベントに応答してキューに追加されます。メインスレッドに実行する作業がない(つまり、キューにメッセージがない)場合があります。 1つのフレームのレンダリングが終了した直後(スレッドは1つのフレームを描画し、次のフレームの準備ができているため、適切な時間だけ待機します)。 MessageQueue
クラスの2つのJavaメソッドは、私たちにとって興味深いものです:Message next()
およびboolean enqueueMessage(Message, long)
。Message next()
、その名前が示すように、キューから次のメッセージを受け取って返します。キューが空の場合(何も返されない場合)、メソッドはnative void nativePollOnce(long, int)
を呼び出し、新しいメッセージが追加されるまでブロックします。この時点でnativePollOnce
がいつ目覚めるかをどのように知るかを尋ねるかもしれません。これはとても良い質問です。Message
がキューに追加されると、フレームワークはenqueueMessage
メソッドを呼び出しますメッセージをキューに挿入するだけでなく、キューをウェイクアップする必要がある場合はnative static void nativeWake(long)
も呼び出します。nativePollOnce
とnativeWake
のコアマジックは- ネイティブ(実際にはC++)コード 。ネイティブMessageQueueは、 epoll
という名前のLinuxシステムコールを利用して、IOイベント。nativePollOnce
は特定のファイル記述子で_epoll_wait
_を呼び出しますが、nativeWake
はIOの1つである記述子に書き込みます=演算、_epoll_wait
_待機します。次に、カーネルはepoll待機スレッドを待機状態から取り出し、スレッドは新しいメッセージの処理を続行します。 JavaのObject.wait()
およびObject.notify()
メソッドに精通している場合は、nativePollOnce
がObject.wait()
およびnativeWake
for Object.notify()
、ただし完全に異なる方法で実装されている場合を除く:nativePollOnce
はepoll
を使用し、Object.wait()
は futex
Linux呼び出し。 nativePollOnce
もObject.wait()
もCPUサイクルを浪費しないことに注意する必要があります。スレッドがどちらかのメソッドに入ると、スレッドスケジューリングの目的で無効になります(Object
のjavadocを引用)クラス)。ただし、一部のプロファイラーは、epoll-waiting(またはObject-waiting)スレッドが実行中であり、CPU時間を消費していると誤って認識する場合がありますが、これは正しくありません。これらの方法が実際にCPUサイクルを無駄にした場合、アイドル状態のアプリはすべてCPUを100%使用し、デバイスを加熱および減速します。
結論:
nativePollOnce
について心配する必要はありません。すべてのメッセージの処理が完了し、スレッドが次のメッセージを待つことを示しているだけです。まあ、それは単にあなたがメインスレッドにあまり多くの仕事を与えないことを意味します;)