阿里妹導讀:Java能成爲應用最普遍的語言,和他的內存託管機制是分不開的。不少人眼中,Java虛擬機是透明的,只需知道核心api的用法,即可以專一於實現具體業務,而後依賴Java虛擬機運行甚至優化應用。你是否有過這樣的經歷,跑得好好的Java進程,忽然就癱瘓了。過於依賴Java虛擬機致使咱們對問題無從下手,問題反覆出現影響開發效率。其實,多數Java進程癱瘓的緣由能夠從java虛擬機層面找到緣由,本文列舉出致使Java進程癱瘓的一些共性緣由,供你們交流和學習。java
用Java沒法作出相似Redis這樣的產品。java的內存回收機制使咱們在編寫代碼時不須要關注對象的回收,同時加大了內存回收的消耗,標記複製須要作內存拷貝,標記清除算法則須要stop the world。因此咱們在使用緩存的時候,量稍微大一些就須要藉助相似Redis這樣的中間件幫咱們處理了。做爲Javaer,咱們享受了自動內存回收的安逸,同時也須要多瞭解下內存優化的方法。程序員
1.什麼狀況下會gc算法
爲了瞭解咱們的系統爲何會不停fgc,咱們須要先了解一下系統什麼狀況下會gc。在jvm層面,當咱們new一個對象的時候,jvm會先在堆區分配對象須要的內存,這個時候若是內存不夠的話,就須要gc了,gc的返回結果就是對象的空間地址。jvm會先進行ygc,也就是咱們一般說的標記複製,若是ygc以後依然申請不到空間,就會進行fgc了。同理,若是fgc以後依然沒有足夠的空間,就會循環的進行fgc,直到申請到足夠的空間。數據庫
2.致使不停的fgc的緣由編程
如上文所講,fgc有可能發生在你的每一行代碼。若是fgc以後依然沒有足夠的空間,就會不停的fgc,直到申請到足夠的空間。同時JVM會限制在拋出OutOfMemory錯誤以前在GC中花費的VM時間的比例。系統頻繁FGC大體有五種狀況:api
1w,正常狀況下處理一個請求的時間是1ms,那同一時刻並行的請求數量僅爲10。若是性能發生抖動,每一個請求處理的時間增長到100ms,那同一時刻並行的請求數量就會增長到100個。每一個線程在處理請求的時候都會new一些對象出來,長時間存活的線程會形成相似內存泄漏的效果,將系統的內存耗盡。同時fgc也會加重系統性能的開銷,使系統變得更慢,產生雪崩。緩存
1.杜絕內存泄漏服務器
內存泄漏形成系統癱瘓的頻率很高,有些系統定時從數據庫拉取配置信息緩存到集合中,可是set不當心寫成了list,最終在新增元素的時候內存溢出了。養成良好的編程習慣,多關注些細節,就能避免不少未知的問題。併發
2.併發限制:防止系統被撐死jvm
每臺服務器都有並行處理請求的上限,無論請求處理的多快,超過上限以後就會被撐死,對高併發的請求作好併發數限制是保持系統穩定的必要條件。須要注意的是,有一些系統在拒絕過多的請求時,也會作一些降級邏輯,降級邏輯也是有性能開銷的,一樣須要作併發限制,若是降級的請求超過併發限制,將不進行降級邏輯直接拋出異常。咱們可以使用的限流組件有不少,推薦咱們阿里自研的Sentinel 和 Netflix開源的Hystrix。
3.自適應限流:防止系統被摸死
咱們須要自適應限流有兩個緣由:
a. 每臺服務器所處的環境是不同的
有些服務器和離線計算的vm混部在一塊兒,有些部署在實體機,有些部署在新老型號的機器上,每臺服務器能承受的qps並不徹底同樣。統一配置分佈式系統中每臺服務器限流閥值,要麼發揮不出每臺服務器應有的做用,要麼在高qps的狀況下一些比較慢的服務器宕機,因此用服務器做爲限流粒度是最合適的。
b.設置了正確的限流閥值,也可能被摸死
當單機承受的QPS 6~20倍於限流的流量時,拒絕一次請求的開銷就沒法忽略不記了。譬如春晚活動有些系統設置了正確的限流也被6~20倍於限流的流量沖垮。這種死法稱爲被摸死。應對這種狀況,咱們能夠作的是在受到6~20倍的大流量時,動態減小限流的閥值。好比系統最開始接受1000qps,5000的拒絕流量過來會把系統摸死,這個時候咱們調整系統的閥值,限流設置到100,被摸死的閥值就能夠高一些,這樣就算有6000個請求進來,咱們系統也能夠保證活下來。
4.異常流量監控:防止長尾請求拖垮系統
咱們盯系統監控的時候一般會關注99分位的數據,但若是設置了合理的限流,系統依然被流量打掛,就要從那百分之一的長尾數據入手了。有些長尾數據對系統的影響會很是大。想象若是一個put請求傳過來幾十兆的數據,對java是極爲不友好的,頗有可能產生fgc,讓請求變慢,致使一系列問題。
總之,磨刀不誤砍柴工,當咱們的系統由於fgc一次又一次重啓的時候,不如花時間瞭解下系統產生性能問題的緣由,將產生問題的那根針拔掉,晚上睡個安穩覺,白天更加充滿活力的挖新坑。但願每一個程序員手裏都是一個穩定的系統。
參考資料:
jvm調優總結:
https://hllvm-group.iteye.com/group/wiki/?category_id=301
諾亞(Noah)自適應限流 穩定性利器 :
https://www.atatech.org/articles/149208
本文做者:通木
本文來自雲棲社區合做夥伴「阿里技術」,如需轉載請聯繫原做者。