自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

阿里面試:NIO為什么會(huì)導(dǎo)致CPU100%?

開發(fā)
升級 Java 版本:早期的 JDK 版本中(JDK 1.7 之前),這個(gè) bug 較為常見,但后續(xù)的 JDK 更新中,Oracle 和 OpenJDK 團(tuán)隊(duì)已經(jīng)著手解決了這一問題,確保使用最新的 Java 版本可以減少遇到此問題的風(fēng)險(xiǎn)。但網(wǎng)上依然有人發(fā)現(xiàn)即使在 JDK 1.8 中,使用原生的 NIO 依然會(huì)發(fā)生空輪詢的問題,只是發(fā)生的概率變低了而已。

在 Java 中總共有三種 IO 類型:BIO(Blocking I/O,阻塞I/O)、NIO(Non-blocking I/O,非阻塞I/O)和 AIO(Asynchronous I/O,異步I/O),它們的區(qū)別如下:

  1. 在 JDK 1.4 之前,只有 BIO 一種模式,其開發(fā)過程相對簡單,新來一個(gè)連接就會(huì)創(chuàng)建一個(gè)新的線程處理,但隨著請求并發(fā)度的提升,BIO 很快遇到了性能瓶頸。
  2. 所以在 JDK 1.4 以后開始引入了 NIO 技術(shù),NIO 可以在一個(gè)線程中處理多個(gè) IO 操作,提高了資源的利用率和系統(tǒng)的吞吐量。
  3. 而到了 JDK 1.7 發(fā)布了 AIO 模型,它可以實(shí)現(xiàn)當(dāng)線程發(fā)起一個(gè) IO 操作后,可以直接返回,無需等待 IO 操作完成。操作系統(tǒng)會(huì)在整個(gè) IO 操作完成后,通過回調(diào)函數(shù)通知應(yīng)用程序。

1.空輪詢和CPU100%

然而,隨著 NIO 逐漸使用,人們卻發(fā)現(xiàn)了 NIO 的一個(gè)經(jīng)典問題,也就是臭名昭著的 Epoll(多路復(fù)用實(shí)現(xiàn)技術(shù))空輪詢的問題。

空輪詢的問題是指,在 Linux 系統(tǒng)下,使用 Java 中的 NIO 時(shí),即使 Selector(多路復(fù)用器)輪詢結(jié)果為空,也沒有 wakeup 或新消息要處理時(shí),NIO 依舊會(huì)進(jìn)行空輪詢,導(dǎo)致 CPU 一直上升,最終造成 CPU 使用率 100% 的問題。

該 BUG 相關(guān)可以參見以下鏈接:

  • https://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719
  • https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6403933
  • https://github.com/netty/netty/issues/327

2.空輪詢的原因

空輪詢產(chǎn)生的原因可以在 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6670302 上找到答案,例如以下就是一個(gè)經(jīng)典的 bug 復(fù)現(xiàn)場景:

A DESCRIPTION OF THE PROBLEM :
The NIO selector wakes up infinitely in this situation..
0. server waits for connection
1. client connects and write message
2. server accepts and register OP_READ
3. server reads message and remove OP_READ from interest op set
4. client close the connection
5. server write message (without any reading.. surely OP_READ is not set)
6. server's select wakes up infinitely with return value 0

也就說,當(dāng)連接出現(xiàn)了 RST(強(qiáng)制連接關(guān)閉),因?yàn)?poll 和 epoll 對于突然中斷的連接 Socket 會(huì)對返回的 eventSet 事件集合置為 POLLHUP 或者 POLLERR,eventSet 事件集合發(fā)生了變化,這就導(dǎo)致 Selector 會(huì)被喚醒,進(jìn)而導(dǎo)致 CPU 100% 問題,其根本原因就是 JDK 沒有處理好這種情況,比如 SelectionKey 中就沒定義有異常事件的類型,導(dǎo)致異常無法被捕捉和處理,從而一直空輪詢。

3.如何解決空輪詢?

NIO 空輪詢可能會(huì)導(dǎo)致 CPU 100% 的解決方案通常有以下兩種:

  • 升級 Java 版本:早期的 JDK 版本中(JDK 1.7 之前),這個(gè) bug 較為常見,但后續(xù)的 JDK 更新中,Oracle 和 OpenJDK 團(tuán)隊(duì)已經(jīng)著手解決了這一問題,確保使用最新的 Java 版本可以減少遇到此問題的風(fēng)險(xiǎn)。但網(wǎng)上依然有人發(fā)現(xiàn)即使在 JDK 1.8 中,使用原生的 NIO 依然會(huì)發(fā)生空輪詢的問題,只是發(fā)生的概率變低了而已。
  • 使用第三方庫:對于無法升級 Java 版本的情況,或擔(dān)心新版本的 JDK 中依然存在空輪詢問題的團(tuán)隊(duì)可以考慮使用已經(jīng)解決了此問題的第三方庫,如 Netty。Netty 通過主動(dòng)檢測和處理空輪詢情況,當(dāng)檢測到可能的空輪詢時(shí),會(huì)采取措施如臨時(shí)增加 Selector 的等待時(shí)間,或者重建 Selector,以此來避免 CPU 資源的浪費(fèi)。

課后思考

說說 Netty 解決空輪詢的具體實(shí)現(xiàn)細(xì)節(jié)?為什么重建 Selector 可以避免空輪詢呢?

責(zé)任編輯:武曉燕 來源: Java中文社群
相關(guān)推薦

2024-05-27 08:04:41

2024-07-18 20:18:51

2023-03-20 17:27:54

Cpukafka

2022-12-09 14:40:16

CPU進(jìn)程快速定位

2024-05-24 10:15:36

2017-08-19 23:21:14

線上CPU定位

2010-09-03 12:04:52

cpu100%

2023-09-21 10:50:23

MySQL數(shù)據(jù)庫

2017-10-19 12:45:07

PHP

2017-01-05 18:43:58

閏秒Linux服務(wù)器

2021-06-04 15:58:53

CPU排查OOM

2021-07-04 15:16:14

索引B+數(shù)據(jù)庫

2024-02-26 08:21:51

CPUkafka死循環(huán)

2017-04-07 14:00:02

程序猿SQL ServerCPU

2022-10-18 08:38:16

內(nèi)存泄漏線程

2022-09-14 19:50:22

事務(wù)場景流程

2022-06-27 07:23:44

MySQL常量優(yōu)化

2022-09-20 22:27:08

事務(wù)失效public 修飾

2018-12-03 09:42:32

Java程序員阿里面試

2021-04-27 10:53:58

Redis數(shù)據(jù)庫SDS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號