亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JVM代碼緩存區(qū)CodeCache原理及用法解析

 更新時(shí)間:2020年11月16日 09:19:07   投稿:yaominghui  
這篇文章主要介紹了JVM代碼緩存區(qū)CodeCache原理及用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

一. CodeCache簡(jiǎn)介

從字面意思理解就是代碼緩存區(qū),它緩存的是JIT(Just in Time)編譯器編譯的代碼,簡(jiǎn)言之codeCache是存放JIT生成的機(jī)器碼(native code)。當(dāng)然JNI(Java本地接口)的機(jī)器碼也放在codeCache里,不過JIT編譯生成的native code占主要部分。

大致在JVM中的分布如下:

大家都知道javac編譯器,把java代碼編譯成class字節(jié)碼,它和JIT編譯器的區(qū)別是,javac只是前端編譯(有的叫前期編譯),jvm是通過執(zhí)行機(jī)器碼和底層交互的,這樣我們編寫的業(yè)務(wù)代碼才能生效。所以還要把字節(jié)碼class編譯成與本地平臺(tái)相關(guān)的機(jī)器碼,這個(gè)過程就是后端編譯。

后端編譯根據(jù)具體的執(zhí)行方式不同又分為兩種:

1.解釋執(zhí)行

一行一行解釋成機(jī)器碼再執(zhí)行,每次調(diào)用時(shí)都需要重新逐條解釋執(zhí)行。

2.編譯執(zhí)行(JIT)

將頻繁調(diào)用的方法或循環(huán)體編譯成機(jī)器碼后,進(jìn)行多層優(yōu)化,然后緩存到codeCache里,避免重復(fù)編譯。

兩種執(zhí)行方式的區(qū)別很明顯,第一種在遇到頻繁調(diào)用的方法或代碼塊時(shí)執(zhí)行效率很低,但是解釋執(zhí)行可以節(jié)省內(nèi)存(不存放到codeCache),立即執(zhí)行。然后當(dāng)程序運(yùn)行一段時(shí)間后(達(dá)到一定的編譯次數(shù)),編譯執(zhí)行即JIT優(yōu)化,可以獲得更高的執(zhí)行效率。

所以說二者是相輔相成的。

現(xiàn)在的Java虛擬機(jī)這兩種方式都包含(通過命令行java -version查看):

// mixed mode 解釋+編譯
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

其實(shí)JIT編譯只是一個(gè)統(tǒng)稱,具體要看jvm是client端還是server端的,不同的端會(huì)分為C1,C2編譯器,這兩種編譯器的區(qū)別下一篇會(huì)講到,這里先不展開。

二. JIT編譯優(yōu)化

上面講到了JVM會(huì)對(duì)頻繁使用的代碼,即熱點(diǎn)代碼(Hot Spot Code),達(dá)到一定的閾值后會(huì)編譯成本地平臺(tái)相關(guān)的機(jī)器碼,并進(jìn)行各層次的優(yōu)化,提升執(zhí)行效率。

熱點(diǎn)代碼也分兩種:

  • 被多次調(diào)用的方法
  • 被多次執(zhí)行的循環(huán)體

那閾值如何判斷呢?

方法計(jì)數(shù)器,統(tǒng)計(jì)被多次調(diào)用的方法次數(shù),該計(jì)數(shù)器統(tǒng)計(jì)的并不是方法被調(diào)用的絕對(duì)次數(shù),而是在一段時(shí)間內(nèi)方法被調(diào)用的次數(shù)。server模式下默認(rèn)是10000次,可以通過-XX:CompileThreshold來設(shè)置(client模式一般很少用到,默認(rèn)是1500)。
回邊計(jì)數(shù)器,統(tǒng)計(jì)一個(gè)方法中循環(huán)體代碼執(zhí)行的絕對(duì)次數(shù),在字節(jié)碼中遇到控制流向后跳轉(zhuǎn)的指令稱為回邊,主要通過OnStackReplacePercentage設(shè)置。

編譯后進(jìn)行優(yōu)化,JIT的優(yōu)化有很多種,比如:

  • 針對(duì)方法的優(yōu)化,方法內(nèi)聯(lián)
  • 針對(duì)多次調(diào)用的循環(huán)體優(yōu)化:棧上替換OSR(On-Stack Replace)
  • 無用代碼消除
  • 復(fù)寫傳播
  • 逃逸分析
  • 更多JIT優(yōu)化技術(shù)可參考jvm官網(wǎng)介紹

三. codeCache使用注意事項(xiàng)

上面主要講了codeCache的作用和JIT的關(guān)系,codeCache主要是存放JIT編譯后的機(jī)器代碼,codeCache的大小主要是通過下面的參數(shù)設(shè)置:

  • -XX:InitialCodeCacheSize 設(shè)置codeCache初始大小,一般默認(rèn)是48M
  • -XX:ReservedCodeCacheSize 設(shè)置codeCache預(yù)留的大小,通常默認(rèn)是240M

如果codeCache的內(nèi)存滿了會(huì)進(jìn)行回收,但在jdk1.8之前的jvm回收算法有點(diǎn)問題,當(dāng)codeCache滿了之后會(huì)導(dǎo)致編譯線程無法繼續(xù),并且消耗大量CPU導(dǎo)致系統(tǒng)運(yùn)行變慢,現(xiàn)象就是系統(tǒng)響應(yīng)增加,如果你也遇到這個(gè)問題建議直接升級(jí)成jdk8,或者調(diào)大codeCache內(nèi)存。

codeCache的大小設(shè)置可以通過-XX:+PrintCodeCache參數(shù)查看調(diào)整,但這個(gè)參數(shù)只在JVM停止的時(shí)候打印codeCache使用情況,所以如果想實(shí)時(shí)監(jiān)控codeCache的使用情況,可以參考如下代碼:

package com.javakk;

import java.io.File;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import com.sun.tools.attach.VirtualMachine;
/**
 * 基于JMX在運(yùn)行時(shí)查看codeCache使用情況
 * @author 公眾號(hào):Java老K
 */
public class CodeCacheTest {
  public static void main(String[] args) throws Exception {
    String pid = getPid(); // 先獲取java程序的pid
    String codeCache = getCodeCache(pid); // 根據(jù)pid獲取codeCache的使用情況
    System.out.println(codeCache);
  }

  /**
   * 獲取java進(jìn)程id
   * @return
   */
  public static String getPid(){
    String name = ManagementFactory.getRuntimeMXBean().getName();
    return name.split("@")[0];
  }

  /**
   * 獲取java應(yīng)用的codeCache使用情況
   * @param pid
   * @throws Exception
   */
  public static String getCodeCache(String pid) throws Exception {
    VirtualMachine vm = VirtualMachine.attach(pid);
    JMXConnector connector = null;
    try {
      String addr = "com.sun.management.jmxremote.localConnectorAddress";
      String property= vm.getAgentProperties().getProperty(addr);
      if (property == null) {
        String agent = vm.getSystemProperties().getProperty("java.home")
            + File.separator
            + "lib"
            + File.separator
            + "management-agent.jar";
        vm.loadAgent(agent);
        property = vm.getAgentProperties().getProperty(addr);
      }

      JMXServiceURL url = new JMXServiceURL(property);
      connector = JMXConnectorFactory.connect(url);
      MBeanServerConnection mbeanConn = connector.getMBeanServerConnection();
      ObjectName obj = new ObjectName("java.lang:type=MemoryPool,name=Code Cache");
      return mbeanConn.getAttribute(obj, "Usage").toString();
    } finally {
      if(connector != null) {
        connector.close();
      }
      vm.detach();
    }
  }
}

運(yùn)行后可以查看contents結(jié)果

contents={committed=2555904, init=2555904, max=251658240, used=2395648}

可以看到我本地的codeCahe配置,初始化是2555904,最大為251658240,已使用2395648

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一文帶你搞懂Java類加載機(jī)制

    一文帶你搞懂Java類加載機(jī)制

    Java?類加載機(jī)制是?Java?運(yùn)行時(shí)的核心組成部分,負(fù)責(zé)在程序運(yùn)行過程中動(dòng)態(tài)加載和連接類文件,并將其轉(zhuǎn)換為可執(zhí)行代碼,接下來小編就來帶大家搞懂面試官老問的?Java?類加載機(jī)制,需要的朋友可以參考下
    2023-08-08
  • SpringBoot3實(shí)現(xiàn)webclient的通用方法詳解

    SpringBoot3實(shí)現(xiàn)webclient的通用方法詳解

    Spring Boot WebClient 是 Spring Framework 5 中引入的一個(gè)新的響應(yīng)式 Web 客戶端,用于異步和響應(yīng)式地與外部服務(wù)進(jìn)行通信,下面我們就來看看SpringBoot3實(shí)現(xiàn)webclient的通用方法吧
    2024-04-04
  • 淺談Maven 項(xiàng)目中依賴的搜索順序

    淺談Maven 項(xiàng)目中依賴的搜索順序

    這篇文章主要介紹了淺談Maven 項(xiàng)目中依賴的搜索順序,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • 一文帶你掌握J(rèn)ava?LinkedBlockingQueue

    一文帶你掌握J(rèn)ava?LinkedBlockingQueue

    LinkedBlockingQueue?是一個(gè)可選有界阻塞隊(duì)列,這篇文章主要為大家詳細(xì)介紹了Java中LinkedBlockingQueue的實(shí)現(xiàn)原理與適用場(chǎng)景,感興趣的可以了解一下
    2023-04-04
  • 基于maven實(shí)現(xiàn)私服搭建步驟圖解

    基于maven實(shí)現(xiàn)私服搭建步驟圖解

    這篇文章主要介紹了基于maven實(shí)現(xiàn)私服搭建步驟圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot異步使用@Async的原理以及線程池配置詳解

    SpringBoot異步使用@Async的原理以及線程池配置詳解

    在項(xiàng)目中當(dāng)訪問其他人的接口較慢時(shí),不想程序一直卡在耗時(shí)任務(wù)上,想程序能夠并行執(zhí)行,我們可以使用多線程來并行的處理任務(wù),也可以使用spring提供的異步處理方式@Async,這篇文章主要給大家介紹了關(guān)于SpringBoot異步使用@Async的原理以及線程池配置的相關(guān)資料
    2021-09-09
  • SpringBoot多種場(chǎng)景傳參模式

    SpringBoot多種場(chǎng)景傳參模式

    傳參是非常常見的,本文主要介紹了SpringBoot多種場(chǎng)景傳參模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • java實(shí)現(xiàn)大文本文件拆分

    java實(shí)現(xiàn)大文本文件拆分

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)大文本文件拆分,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Java單例模式實(shí)現(xiàn)靜態(tài)內(nèi)部類方法示例

    Java單例模式實(shí)現(xiàn)靜態(tài)內(nèi)部類方法示例

    這篇文章主要介紹了Java單例模式實(shí)現(xiàn)靜態(tài)內(nèi)部類方法示例,涉及構(gòu)造函數(shù)私有化等相關(guān)內(nèi)容,需要的朋友可以了解下。
    2017-09-09
  • springboot實(shí)現(xiàn)攔截器之驗(yàn)證登錄示例

    springboot實(shí)現(xiàn)攔截器之驗(yàn)證登錄示例

    本篇文章主要介紹了springboot實(shí)現(xiàn)攔截器之驗(yàn)證登錄示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02

最新評(píng)論