JVM Code Cache空間不足,致使服務性能變慢

有業務反饋,線上一個應用運行了一段時間以後,在高峯期以後,忽然發現處理能力降低,接口的響應時間變長,可是看Cat上的GC數據,一切都很正常。java

經過跳板機上機器查看日誌,發現一段平時不多見到的日誌:面試

Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=.
...
「CompilerThread0」 java.lang.OutOfMemoryError: requested 2854248 bytes for Chunk::new. Out of swap space?

其中CodeCache is full,說明Code Cache已經滿了,致使Compiler失效,這是爲何?算法

首先,咱們得了解什麼是Code Cache。緩存

什麼是Code Cache

Java代碼在執行次數達到一個閾值會觸發JIT編譯,一旦代碼塊被編譯成本地機器碼,下次執行的時候會直接運行編譯後的本地機器碼。因此這本地機器碼必須被緩存起來,而緩存這個本地機器碼的內存區域就是Code Cache,它並不屬於Java堆的一部分,除了JIT編譯的代碼以外,Java所使用的本地方法代碼(JNI)也會存在codeCache中。架構

Code Cache 調優

因爲Code Cache是一塊內存區域,那麼確定有大小的限制,可是不一樣版本的JVM、不一樣的啓動方式,Code Cache的默認大小也不一樣,可經過jinfo -flag ReservedCodeCacheSize 進行查看。性能

服務啓動以後,隨着時間的推移,確定會有愈來愈多的方法被JIT編譯成本地機器碼,並存放到Code Cache,因爲Code Cache大小是固定的,那麼就存在被用完的風險。學習

一旦Code Cache被填滿,就會出現下面狀況:spa

  • JVM的JIT功能會被中止,將不會編譯任何額外的代碼。
  • 被編譯過的代碼仍然以編譯方式執行,可是還沒有被編譯的代碼只能以解釋方式執行了。

這種狀況下,若是應用中還有不少代碼以解釋方式執行,其性能會大大下降。爲了不這種狀況,就須要對Code Cache比較深刻的理解。線程

JVM啓動的時候,Code Cache所需內存會被單獨初始化,這時候Java堆還會被初始化,因此Code Cache和Java堆是兩塊獨立內存區域。調試

codeCache.cppCodeCache::initialize()方法中,實現了Code Cache的初始化

Code Cache包含了3種數據:

  • NonNMethodCode
  • ProfiledCode
  • NonProfiledCode

經過SegmentedCodeCache參數能夠選擇按照總體初始化,仍是分段初始化。

經過-XX:ReservedCodeCacheSize參數能夠指定Code Cache的初始化大小,這個默認值在不一樣的JDK版本也不一樣,目前我這邊調試的是OpenJDK11,默認大小是240M,這個已經夠用了。

能夠看下其它版本的默認大小:

對於那些只有32M、48M的就可能存在Code Cache不足的隱患,增長ReservedCodeCacheSize能夠是一個解決方案,但這一般只是一個臨時的解決方案。

幸運的是,JVM提供了一種比較激進的codeCache回收方式:Speculative flushing。

在JDK1.7.0_4以後這種回收方式默認開啓,而以前的版本須要經過一個參數來開啓:-XX:+UseCodeCacheFlushing。

在Speculative flushing開啓的狀況下,當Code Cache不足時:

  • 最先被編譯的一半方法將會被放到一個old列表中等待回收;
  • 在必定時間間隔內,若是old列表中方法沒有被調用,這個方法就會被從Code Cache清除;

很不幸的是,在JDK1.7中,Speculative flushing釋放了一部分空間,可是從編譯日誌來看,JIT並無恢復正常,而且系統總體性能降低不少,出現了大量超時。

在Oracle官網上看到這樣一個Bug:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8006952 因爲算法問題,當Code Cache不足以後會致使編譯線程沒法繼續,而且消耗大量CPU,致使系統運行變慢。

以爲不錯請點贊支持,歡迎留言或進個人我的羣855801563領取【架構資料專題目合集90期】、【BATJTMD大廠JAVA面試真題1000+】,本羣專用於學習交流技術、分享面試機會,拒絕廣告,我也會在羣內不按期答題、探討。

相關文章
相關標籤/搜索