《Java程式效能優化 讓你的Java程式更快、更穩定》閱讀筆記
一.Linux中常用的監控CPU整體效能的工具有:
§ mpstat: mpstat 不但能檢視所有CPU的平均資訊,還能檢視指定CPU的資訊。
mpstat [-P {|ALL}] [internal [count]] -P {|ALL} 表示監控哪個CPU, cpu在[0,cpu個數-1]中取值
§ vmstat:只能檢視所有CPU的平均資訊;檢視cpu佇列資訊;
vmstat和sar類似也可指定取樣週期和取樣數量
§ iostat: 只能檢視所有CPU的平均資訊,快速定位系統是否產生大量I/O操作
§ sar: 與mpstat 一樣,不但能檢視CPU的平均資訊,還能檢視指定CPU的資訊。
sar [-u,-r,-b] [<interval> <count>] -u cpu利用率,-r記憶體利用率,-b I/O利用率,interval表示取樣週期,count表示取樣數量
§ top:顯示的資訊同ps接近,但是top可以瞭解到CPU消耗,可以根據使用者指定的時間來更新顯示。
pidstat linux效能檢測工具
在Debian/Ubuntu系統中可以使用下面的命令來安裝
# apt-get install sysstat
CentOS/Fedora/RHEL版本的linux中則使用下面的命令:
# yum install sysstat
二.RPC和Http的區別:
目前有很多Java的RPC框架,有基於Json的,有基於XML,也有基於二進位制物件的。
論複雜度,RPC框架肯定是高於簡單的HTTP介面的。但毋庸置疑,HTTP介面由於受限於HTTP協議,需要帶HTTP請求頭,導致傳輸起來效率或者說安全性不如RPC。
現在問題是,遇到怎樣的瓶頸了才需要或者說更適合用RPC(比如像阿里這麼大的請求併發量,簡單的HTTP肯定達不到預期),但問題是大家所在的公司,要有像阿里這麼大的量是比較少的,甚至說1/1000的量可能都沒有,那我們還需要使用RPC嗎?
技術應該不是為了使用新技術而去使用,而應該是舊技術存在某些瓶頸,存在難以支撐或者擴充套件性越老越差等問題暴露出來之後,用新技術來進行解決。
http介面是在介面不多、系統與系統互動較少的情況下,解決資訊孤島初期常使用的一種通訊手段;優點就是簡單、直接、開發方便。利用現成的http協議進行傳輸。但是如果是一個大型的網站,內部子系統較多、介面非常多的情況下,RPC框架的好處就顯示出來了,首先就是長連結,不必每次通訊都要像http一樣去3次握手什麼的,減少了網路開銷;其次就是RPC框架一般都有註冊中心,有豐富的監控管理;釋出、下線介面、動態擴充套件等,對呼叫方來說是無感知、統一化的操作。第三個來說就是安全性。最後就是最近流行的服務化架構、服務化治理,RPC框架是一個強力的支撐
三.NIO的理解
3.1NIO和BIO的區別和各自適用的場景
區別:BIO:同步阻塞式IO,伺服器實現模式為一個連線一個執行緒,即客戶端有連線請求時伺服器端就需要啟動一個執行緒進行處理,如果這個連線不做任何事情會造成不必要
的執行緒開銷,當然可以通過執行緒池機制改善。
NIO:同步非阻塞式IO,伺服器實現模式為一個請求一個執行緒,即客戶端傳送的連線請求都會註冊到多路複用器上,多路複用器輪詢到連線有I/O請求時才啟動一個執行緒
進行處理。
各自應用場景:
NIO適合處理連線數目特別多,但是連線比較短(輕操作)的場景,Jetty,Mina,ZooKeeper等都是基於java nio實現。
BIO方式適用於連線數目比較小且固定的場景,這種方式對伺服器資源要求比較高,併發侷限於應用中。
3.2給我們帶來了些什麼
避免多執行緒
單執行緒處理多工
非阻塞I/O,I/O讀寫不再阻塞,而是返回0
基於block的傳輸,通常比基於流的傳輸更高效
更高階的IO函式,zero-copyIO多路複用大大提高了Java網路應用的可伸縮性和實用性
NIO一個重要的特點是:socket主要的讀、寫、註冊和接收函式,在等待就緒階段都是同步非阻塞的,真正的I/O操作是同步阻塞的(消耗CPU但效能非常高)。
解釋的比較清楚的文章:
四常用的集合
ArrayList的內部實現是基於基礎的物件陣列的,因此,它使用get方法訪問列表中的任意一個元素時(random-access),它的速度要比LinkedList快
LinkedList基於連結串列的資料結構,沒有同步辦法。若是多個執行緒同時接見一個List,則必須本身實現接見同步。一種解決辦法是在建立List機會關一個同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
Vector是同步的。由Vector建立的Iterator,固然和ArrayList建立的Iterator是同一介面,然則,因為Vector是同步的,當一個Iterator被建立並且正在被應用,另一個執行緒改變了Vector的狀況(例如,新增或刪除了一些元素),這時呼叫Iterator的辦法時將丟擲ConcurrentModificationException,是以必須捕獲該異常。
總結特點如下:
型別 | 內部結構 | 順序遍歷速度 | 隨機遍歷速度 | 追加代價 | 插入代價 | 刪除代價 | 佔用記憶體 |
ArrayList | 陣列 | 高 | 高 | 中 | 高 | 高 | 低 |
LinkedList | 雙向連結串列 | 高 | 低 | 低 | 低 | 低 | 中 |
所以:
- 一般順序遍歷情況下使用ArrayList,但注意建構函式中設定初始大小
- 儘量不對ArrayList進行插入或刪除操作(刪除尾部除外),若有多次刪除/插入操作又有隨機遍歷的需求,可以再構建一個ArrayList,把複合條件的物件放入新ArrayList,而不要頻繁操作原ArrayList
- 經常有刪除/插入操作而順序遍歷列表的情況下最適合使用LinkedList
五鎖
只在REPEATABLE
READ或以上的隔離級別下的特定操作才會取得gap lock或nextkey lock。