CodeCache不足導致應用load偏高的問題

2022-09-20 07:33:11 字數 1290 閱讀 8217

codecache 是用來儲存由jit 產生的native code 的記憶體區域,它是獨立於jvm heap的非堆記憶體。

jit(just-in-time)編譯(hotspot),是指在執行時,把頻繁執行的 bytecode 轉換成作業系統相關的機器碼,這樣程式執行時就不需要解釋執行,可以提高程式效能,具體可以看下這個部落格。

問題描述:

我想在應用裡面試用一下greys, 當使用monitor 功能時,發現load飆高,資料庫連線池撐爆,應用立即無法響應,嚇死寶寶了。隨即關掉greys,恢復了應用。之後我聯絡了作者,他說有可能是我們應用codecache不足,導致jit **codecache時,佔滿cpu。

原因定位:

因為集團其他同事也遇到過此類問題,他用的是aliperf來定位熱點**,最後定位到jvm的largest_free_block()函式。簡單的說,jvm在維護codecache時會維護乙個freelist(空閒記憶體塊的鍊錶),當要分配空間時,會遍歷這個freelist。而採用分層編譯時會導致編譯後的**被頻繁的寫入或失效codecache,freelist變的非常碎片化,非常長,而每次jvm進行jit操作時,會持有鎖並且遍歷這個list,看原始碼,可以看到持有了鎖。

1

size_t codecache::largest_free_block() else

10 }

因此load變高,引發了後續一系列問題。jdk官方也有類似bug,在jdk8中修復。

驗證:首先我查了下我們應用預設的codecache大小。

1 jinfo -flag reservedcodecachesize

發現是50m,然後通過jmx檢視了在應用執行中使用的codecache大小,發現用了48m,果然已經接近極限。

greys採用了動態**,在runtime時產生大量**類,被編譯寫入codecache,導致codecache空間不足,成為最後一根稻草。

總結:可以看到真正的原因有兩部分組成,

1. codecache 空間不足,引發jvm**空間,呼叫largest_free_block()。

2. jvm 採用了分層編譯,編譯器採用了c1、c2兩種編譯方式,codecache中會存在c1和c2編譯過的**

不分層編譯就只有c2編譯過的**,使得codecache更容易填滿。

問題解決:

通過新增-xx:reservedcodecachesize=512m 更改codecache大小。

通過新增 -xx:+usecodecacheflushing 使得codecache在接近滿時,釋放一半cache,參考文章。

驅動核心堆疊不足導致藍屏

核心模式堆疊是乙個有限的儲存區域,經常用於儲存從乙個函式傳遞到另乙個函式的資訊以及用於區域性變數儲存。雖然堆疊被對映到系統空間,但是它被視為原始呼叫例程的執行緒上下文的一部分,而不是驅動程式本身的一部分。這意味著只要呼叫執行緒正在執行,就可以保證存在堆疊,但是它可以隨執行緒一起清除。在任何核心模式執...

RAC節點增加導致臨時表空間不足

某次把2節點的rac資料庫遷移到3節點伺服器上,結果某個使用者頻繁報臨時表空間不足 檢視該使用者的臨時表空間有16g,排除開發語句寫得不合理等因素,資料庫切換後經常爆也不太正常 最後分析出應該是切換後節點數變多,應用基本是連線scan ip,節點間的通訊互動資訊會寫在臨時表空間裡,所以佔了更多的空間...

swap空間不足導致的服務無法啟動

openjdk 64 bit server vm warning info os commit memory 0x00000000c0000000,357892096,0 failed。解決方法 執行命令free m檢視記憶體與swap空間。如果沒有交換空間或者交換空間比較小,要先安裝交換空間或者增...