Java性能調優之操作系統

首先講述下操作系統層面的性能監控工具。


在性能調優的工作中通常可見三個必不可少的步驟: 性能監控=》性能分析=》性能調優。

性能監控(perfomance monitoring):在沒有任何可用性能數據的情況下,先進行性能的監控。

性能分析(performace profiling):收集應用的性能數據,進行分析。

性能調優(performance tunning): 修改源代碼,配置文件等來改善性能。


性能調優中很重要的是CPU的利用率。這個需要在操作系統層面來觀察。

在大多數操作系統中,CPU利用率分爲用戶級CPU利用率和內核(系統)級CPU利用率。用戶級CPU利用率表示應用程序花在應用程序代碼上的CPU時間比例。內核級CPU利用率表示應用程序花在內核級代碼上的CPU時間比例。高的內核級CPU利用率意味着存在共享資源的競爭或大量的IO操作。理想的情況是0%的內核級CPU利用率,這樣所有的CPU時鐘週期可以被應用程序代碼利用。

對於那種計算密集型的應用,不僅僅要關注以上的部分。還需要關注IPC(Instructions per clock)和CPI(cycles per instruction)。這裏需要注意一個stall現象。因爲大多數操作系統工具在統計CPU利用率的時候並不會統計那些沒有執行任何指令的CPU時鐘週期,這意味着當CPU在等待數據的時候也被統計爲CPU在被利用。通常一個 stall 會浪費幾百個CPU週期。所以對計算密集型的應用來說,得減少stall現象的發生。


現在介紹Linux的CPU性能監控工具:

1.vmstat    可以看到操作系統的用戶cpu使用時間,內核CPU使用時間,空閒時間等

2. pidstat  可以查看指定進程 以及其內部線程的相關CPU和IO信息。


內存利用率: paging or swapping activity

JVM的垃圾回收器在系統swapping的時候會嚴重影響性能,因爲垃圾回收器在回收無用對象的時候會遍歷很大一部分已經被交換出去的內存。這部分內存需要先被交換進內存,才能被垃圾回收期掃描,這會大大延長垃圾回收的時間。如果你發現垃圾回收的時間很長,很可能是因爲系統正在進行swap。

vmstat可以看內存的使用率。

在top命令中也可以查看內存的使用率。其中有buffer跟cached兩列,這兩者是不同的。

我的理解是buffer是操作系統讀寫塊設備的時候的緩衝區,並且它也保存了一些文件系統的元數據。而cache保存的是swap file的cache的,linux使用這些cache來定位需要swap in的page 的信息,以及在linux需要swap out的一些page的時候判斷這些page是否需要寫入swap file中。這些cache是保存在內存中的,並且可以在內存不夠用的時候來佔用這部分內存,所以在linux使用時間很長之後,因爲緩存的page變多,所以linux中free(空閒)內存很少。

Buffers are associated with a specific block device, and cover caching of filesystem metadata as well as tracking in-flight pages. The cache only contains parked file data. That is, the buffers remember what's in directories, what file permissions are, and keep track of what memory is being written from or read to for a particular block device. The cache only contains the contents of the files themselves.

The buffer

Buffers are in-memory block I/O buffers. They are relatively short-lived. Prior to Linux kernel version 2.4, Linux had separate page and buffer caches. Since 2.4, the page and buffer cache are unified and Buffers is raw disk blocks not represented in the page cache—i.e., not file data. The Buffers metric is thus of minimal importance. On most systems, Buffers is often only tens of megabytes.

The Swap Cache

When swapping pages out to the swap files, Linux avoids writing pages if it does not have to.There are times when a page is both in a swap file and in physical memory.This happens when a page that was swapped out of memory was then brought back into memory when it was again accessed by a process.So long as the page in memory is not written to, the copy in the swap file remains valid.

Linux uses the swap cache to track these pages.The swap cache is a list of page table entries, one per physical page in the system.This is a page table entry for a swapped out page and describes which swap file the page is being held in together with its location in the swap file.If a swap cache entry is non-zero, it represents a page which is being held in a swap file that has not been modified.If the page is subsequently modified (by being written to), its entry is removed from the swap cache.

When Linux needs to swap a physical page out to a swap file it consults the swap cache and,if there is a valid entry for this page, it does not need to write the page out to the swap file.This is because the page in memory has not been modified since it was last read from the swap file.

The entries in the swap cache are page table entries for swapped out pages.They are marked as invalid but contain information which allow Linux to find the right swap file and the right page within that swap file.

"How come there is only so few free memory on my Linux PC?"

Come to same question? No matter how much you put RAM in your motherboard, you quickly notice the free RAM is reduced so fast. Free RAM miscalculation? No!

Before answering this, first check the memory summary located on top's display.There, you will find two fields: buffers and cached. "Buffers" represent how much portion of RAM is dedicated to cache disk block. "Cached" is similar like "Buffers", only this time it caches pages from file reading. For thorough understanding of those terms, refer to Linux kernel book like Linux Kernel Development by Robert M. Love.

It is enough to understand that both "buffers" and "Cached" represent the size of system cache. They dynamically grow or shrink as requested by internal Linux kernel mechanism.

Besides consumed by cache, the RAM itself is also occupied by application data and code. So, to conclude, free RAM size here means RAM area that isn't occupied by cache nor application data/code. Generally,you can consider cache area as another "free" RAM since it will be shrunk gradually if the application demands more memory.


鎖競爭的監控

監控java程序的鎖競爭不是那麼容易,工具也很有限。在java5之前,HotSpotVM 幾乎將所有的鎖有關的邏輯代碼依賴於操作系統原語實現,所以一些操作系統工具如Solaris的mpstat可以很好的監控java程序的鎖競爭。然而java5 之後,HotpotVM進行了優化,將很多鎖邏輯相關的代碼用用戶程序代碼實現。所以我們得換個方式來監控java的鎖競爭。

我們通過操作系統上下文的切換情況來側面瞭解java程序鎖競爭的情況。上下文的切換分爲兩種 voluntary context switch and involuntary context switch

一個鎖競爭很多的java程序意味着很多的voluntary context switch 。而voluntary context switch 是很大的,大約8000個時鐘週期。

經驗說法是 一個java程序如果花費了5%以上的時鐘週期在voluntary context switch 上,表明這個程序有可能鎖競爭太多。

使用pidstat -w 命令可以看到voluntary context switch (cswch/s列)。

計算的公式是使用這個值除以CPU的核數。然後再乘以8000再除以CPU的主頻。


網絡監控

分佈式的java程序需要監控網絡的IO情況如帶寬等。

使用nicstat工具。

在java程序中避免大量的網絡讀寫,儘量將更多的數據放在一次讀寫中。使用java nioframework, 如https://grizzly.java.net/


磁盤IO利用率

使用iostat -xm

如果發現很高的磁盤利用率,那麼你可能需要這麼做:

在硬件很操作系統層面:

   1.購買一個更快的設備

   2.將文件分佈在不同的磁盤中

  3.調優操作系統使之擁有更大的磁盤緩存。(有的操作系統默認是沒有磁盤緩存的,開啓的話有可能會出現其他問題如corrupted data)

在應用程序層面:

  1.使用buffed input和output(減少內核級CPU的使用)

   2.實現一個應用程序層面的緩存

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章