数日前、1つのWebサービスアリクラウドサーバ上で見つかったは使用できません。SSHリモートログインには、いくつかの試みが、アップログコマンドの表示を実行した後、オンになっていません
-bash:フォーク:メモリーを割り当てることができません。
メモリリークがオーバーフローを起こしている表情。それは任意のコマンドを実行することはできませんので、サービスは、サーバーコンソールを再起動して復元することができます。
下調べ
サービスの復旧後、システムログ、Linuxのシステム・ログのパスを表示し/var/log/messages
、できjournalctl
のような、コマンドを表示
journalctl --since = "2019年6月12日午前6時00分00秒" --until = "2019年6月12日午前10時00分00秒"
閲覧した後、以降の時間帯の前にログまで。発見に加えて、crond[14954]: (CRON) CAN'T FORK (do_command): Cannot allocate memory
エラーログ、およびなしその他の異常を(下のsshd[10764]: error: fork: Cannot allocate memory
名前のSSHログイン失敗ログを実行する必要があります)
クラウドモニタリング - - アリの雲によって、この期間内のホストの監視ビューのメモリ使用量の指標、メモリ使用量は、40%を下回るメモリオーバーフローの可能性が出て基本的なルールとなっています。
検索によって、オペレーティングシステムは、プロセスの数が生じ得る制限超えbash: fork: Cannot allocate memory
エラー(:参考 https://blog.csdn.net/wangshuminjava/article/details/80603847 )。
ps -eLf|wc -l
プロセススレッドの現在の数を表示する(ps -ef
だけのプロセス印刷ps -eLf
終了ランタイムシステムの障害は、多くのスレッドが唯一のフォローアップモニタリングを持続させることができるかを知る方法がない、唯一のより多くの1000年より、プリントすべてのスレッドを)。
ポジショニングの問題
数日後、再びにより、ps -eLf|wc -l
外観やスレッドの数が16,000以上に達していました。直接の実行は、ps -eLf
多数のスレッドが未完成でハングアップされているデッドロックスレッドされていない憶測につながる、このプロセスによって生成されるtomcatに多数のスレッドを見ることができます。
実行 jstack 进程号 > ~/jstack.txt
印刷実行スレッドの状況分析を処理するコマンドをし、多数のことがわかったWAITING
スレッドの状態は、次のように
"プール19スレッド1" #254 PRIO = 5 os_prio = 0 TID = 0x00007f0b700a6000 NID = 0x29a9条件[0x00007f0b274df000]で待機 java.lang.Thread.State:WAITING(パーキング) (sun.misc.Unsafe.parkでネイティブメソッド) - <0x00000006ce3d8790>(java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObjectの)を待つ駐車 java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)で java.util.concurrentので.locks.AbstractQueuedSynchronizer $ ConditionObject.await(AbstractQueuedSynchronizer.java:2039) java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)で java.util.concurrent.ThreadPoolExecutor.getTaskで(ThreadPoolExecutor.java:1074) java.util.concurrent.ThreadPoolExecutor.runWorkerで(ThreadPoolExecutor.java:1134) java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)で java.lang.Thread.runで(Thread.java:748)
以上のことから、それは、スレッドのような条件で見ることができ、かつ行われるLinkedBlockingQueue.take
方法は、キューが空の場合、すべての要素が利用可能になるまで、プロセスが待機する、メソッドのJavaドキュメントを参照してくださいとき。
/ ** *取得し、必要な場合はこのキューの先頭を削除する 要素が利用可能になるまで*。 * *このキューの先頭@return *中断した場合に待機している間に例外:InterruptedExceptionを@throws * / Eテイク()が例外:InterruptedExceptionがスローされます。
スレッドプールは閉じていない - LinkedBlockingQueue使用同僚を掲載し、同僚は、追加機能の仕方によってOSSアリクラウドアップロードファイルをサービスする問題やレビューコードを識別するために、最近実装スレッドプールを思い出しました。混乱を存在しないの断片ファイルを保存するためには、ファイルを保存するたびに、新しいスレッドプールの対象となります、
ThreadPoolExecutor saveImgThreadPool = 新しい ThreadPoolExecutor(1、1、0、TimeUnit.SECONDS、新しい LinkedBlockingQueue <>());
しかし、スレッドプールの方法は、キューは、このように多数のスレッドにつながる、時空を待つ必要があります待って、未完成がある場合は待機中のスレッドのタスクキューを介して取得するのにかかるように、スレッドプールオブジェクトをクローズしていない、に対処(実質的に長いメソッドが一度調整されているとして、それはライブハングスレッドを生成します)ここに電話を切りました。
延ばします
-
スレッドの状態は、「モニタエントリ待ち」である:
重要な領域に入るのを待っているので、それは「エントリーセット」キューを待っていることを意味します。このとき、スレッドの状態は、一般的にブロックされている:
java.lang.Thread.State:(オブジェクトのモニター上)BLOCKED -
スレッドの状態は「状態で待機中」である:
彼らの航跡を置くために、他の条件が発生するのを待っている、または単にそれがスリープ(N)と呼ばれていること。このとき、スレッドの状態は、おおよそ以下の通りです:
java.lang.Thread.State:WAITING(駐車場):その条件を待っては、(この記事では、そのようなシーンの場合あり)が発生し、java.lang.Thread.State:TIMED_WAITING(駐車または睡眠):タイミングは、することができない条件が、それは定期的に自分自身をウェイクアップします。 -
「モニタエントリ待ち」内のスレッド数場合:グローバルロックはライブスレッドの多くを阻止することができます。時間がより多くのスレッドのモニタエントリを待って、経つにつれて、スレッドダンプファイルは、反映するために短い時間を印刷する場合は、トレンドに減少していないことへのために、あまりにも長い間滞在する重要な領域でのいくつかのスレッドを意味するかもしれませんより多くの新しいスレッドとして、彼らは、クリティカル領域に入ることができませんでしたので。
-
もし内のスレッド数「の状態で待機中」:彼らが行くと、より少ない応答を取得待機状態にスレッドが多数になるには、サードパーティのリソース、特にサードパーティ製のネットワークリソース、遅延を得ることができていること。あなたは多数のスレッドがスレッド・スタックを参照して、条件に待ちにある見つけるのであれば、ネットワークの輻輳がスレッドを実行できない原因となるので、これは、ネットワークのボトルネックの兆候かもしれない、読み書きするためにネットワークを待っています。本明細書で使用される場合、それはまた、言及した不適切なプログラミングさせてもよいです。
私の個人的なブログのアドレス:http://blog.jboost.cn
私の見出しスペース: https://www.toutiao.com/c/user/5833678517/#mid=1636101215791112
私のgithubのアドレス:HTTPS:// githubの.COM / ronwxy
私のマイクロチャネル公共数:jboost-ksxy
--------------------------------------
私は、マイクロチャネルパブリック番号、最新の共有へのタイムリーなアクセスに注意を歓迎します