JVM 코드 캐 시 영역 CodeCache 원리 및 용법 분석

5810 단어 JVMCodeCache
1.CodeCache 소개
말 그대로 코드 캐 시 영역 입 니 다.캐 시 는 JIT(Just in Time)컴 파일 러 가 컴 파일 한 코드 입 니 다.쉽게 말 하면 codeCache 는 JIT 가 생 성 한 기계 코드(native code)를 저장 합 니 다.물론 JNI(Java 로 컬 인터페이스)의 기계 코드 도 codeCache 에 놓 여 있 지만 JIT 컴 파일 로 생 성 된 native code 가 주요 부분 을 차지한다.
대략 JVM 의 분 포 는 다음 과 같다.

자바 c 컴 파일 러 는 자바 코드 를 클 라 스 바이트 코드 로 컴 파일 한 다 는 것 을 잘 알 고 있 습 니 다.JIT 컴 파일 러 와 의 차 이 는 자바 c 는 전단 컴 파일(전기 컴 파일)일 뿐 jvm 은 기계 코드 와 바 텀 인 터 랙 션 을 통 해 작 성 된 업무 코드 가 유효 합 니 다.그래서 바이트 코드 클 라 스 를 로 컬 플랫폼 과 관련 된 기계 코드 로 컴 파일 해 야 합 니 다.이 과정 은 바로 백 엔 드 컴 파일 입 니 다.
백 엔 드 컴 파일 은 구체 적 인 실행 방식 에 따라 두 가지 로 나 뉜 다.
1.해석 집행
한 줄 한 줄 은 기계 코드 로 해석 하고 실행 하 며 호출 할 때마다 다시 한 줄 씩 설명 하고 실행 해 야 한다.
2.컴 파일 실행(JIT)
자주 호출 되 는 방법 이나 순환 체 를 기계 코드 로 컴 파일 한 후 다 중 최적화 한 다음 codeCache 에 캐 시 하여 중복 컴 파일 을 피한다.
두 가지 실행 방식 의 차 이 는 매우 뚜렷 하 다.첫 번 째 는 자주 호출 되 는 방법 이나 코드 블록 을 만 났 을 때 실행 효율 이 매우 낮 지만 실행 을 설명 하면 메모리(codeCache 에 저장 되 지 않 음)를 절약 하고 즉시 실행 할 수 있다.그 다음 에 프로그램 이 한 동안 실 행 된 후에(일정한 컴 파일 횟수 에 도달)컴 파일 집행 은 JIT 최적화 로 더욱 높 은 집행 효율 을 얻 을 수 있다.
그 러 니까 둘 이 상부 상조 하 는 거 야.
현재 자바 가상 머 신 은 두 가지 방식 이 모두 포함 되 어 있 습 니 다(명령 행 자바-version 을 통 해 보기).
//mixed mode 해석+컴 파일
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
사실 JIT 컴 파일 은 하나의 통칭 일 뿐 jvm 이 client 단 인지 server 단 인지 구체 적 으로 봐 야 한다.서로 다른 단 은 C1,C2 컴 파일 러 로 나 눌 것 이다.이 두 컴 파일 러 의 차 이 는 다음 편 에서 설명 할 것 이다.여 기 는 먼저 전개 되 지 않 는 다.
2.JIT 컴 파일 최적화
위 에서 말 했 듯 이 JVM 은 자주 사용 하 는 코드,즉 핫 이 슈 코드(Hot Spot Code)를 일정한 한도 값 에 도달 하면 로 컬 플랫폼 과 관련 된 기계 코드 로 컴 파일 하고 각 단계 의 최 적 화 를 실시 하여 집행 효율 을 높 인 다.
핫 이 슈 코드 도 두 가지 로 나 뉜 다.
  • 여러 번 호출 된 방법
  • 여러 차례 실 행 된 순환 체
  • 그 한도 값 은 어떻게 판단 합 니까?
    방법 계수 기 는 여러 번 호출 된 방법 횟수 를 통계 한다.이 계수 기 는 방법 이 호출 된 절대적 인 횟수 가 아니 라 한 동안 방법 이 호출 된 횟수 를 통계 한다.server 모드 에서 기본 값 은 10000 회 입 니 다.-XX:CompileThreshold 를 통 해 설정 할 수 있 습 니 다.(client 모드 는 일반적으로 거의 사용 되 지 않 습 니 다.기본 값 은 1500 입 니 다.)
    리 턴 카운터,하나의 방법 에서 순환 체 코드 가 실 행 된 절대 횟수 를 통계 합 니 다.바이트 코드 에서 흐름 을 제어 한 후에 뛰 는 명령 을 리 턴 이 라 고 하 는데 주로 OnStack Replace Percentage 를 통 해 설정 합 니 다.
    컴 파일 한 후에 최 적 화 를 한다.JIT 의 최 적 화 는 여러 가지 가 있다.예 를 들 어:
  • 방법 에 대한 최적화,방법 내 연
  • 여러 번 호출 된 순환 체 에 대한 최적화:스 택 에서 OSR(On-Stack Replace)
  • 을 교체 합 니 다.
  • 무용 코드 제거
  • 복사 전파
  • 탈출 분석
  • 더 많은 JIT 최적화 기술 은 jvm 홈 페이지 소개
  • 참조
    3.codeCache 사용 주의사항
    위 에서 주로 codeCache 의 역할 과 JIT 의 관 계 를 말 했 습 니 다.codeCache 는 주로 JIT 컴 파일 된 기계 코드 를 저장 하고 codeCache 의 크기 는 주로 아래 의 매개 변 수 를 통 해 설정 합 니 다.
  • -XX:Initial CodeCacheSize 는 codeCache 초기 크기 를 설정 합 니 다.기본 값 은 48M
  • 입 니 다.
  • -XX:Reserved CodeCacheSize 는 codeCache 가 예약 한 크기 를 설정 합 니 다.기본 값 은 240 M 입 니 다.
  • codeCache 의 메모리 가 가득 차 면 회수 합 니 다.그러나 jdk 1.8 이전의 jvm 회수 알고리즘 에 문제 가 있 습 니 다.codeCache 가 가득 차 면 컴 파일 스 레 드 가 계속 되 지 못 하고 대량의 CPU 를 소모 하여 시스템 운행 이 느 려 집 니 다.현상 은 시스템 응답 이 증가 하 는 것 입 니 다.만약 에 이 문제 가 발생 하면 jdk 8 로 직접 업그레이드 하거나 codeCache 메모 리 를 확대 하 는 것 을 권장 합 니 다.
    codeCache 의 크기 설정 은-XX:+PrintCodeCache 매개 변 수 를 통 해 조정 을 볼 수 있 지만 이 매개 변 수 는 JVM 이 멈 출 때 만 codeCache 사용 상황 을 인쇄 하기 때문에 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      codeCache    
     * @author    :Java K
     */
    public class CodeCacheTest {
      public static void main(String[] args) throws Exception {
        String pid = getPid(); //    java   pid
        String codeCache = getCodeCache(pid); //   pid  codeCache     
        System.out.println(codeCache);
      }
    
      /**
       *   java  id
       * @return
       */
      public static String getPid(){
        String name = ManagementFactory.getRuntimeMXBean().getName();
        return name.split("@")[0];
      }
    
      /**
       *   java   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();
        }
      }
    }
    실행 후 contents 결 과 를 볼 수 있 습 니 다.contents={committed=2555904, init=2555904, max=251658240, used=2395648}로 컬 codeCahe 설정 을 볼 수 있 습 니 다.초기 화 는 2555904 이 고 최대 251658240 이 며 2395648 을 사 용 했 습 니 다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기