JIT (Just-In-Time) 컴파일러의 기능은 무엇입니까?


528

JIT 컴파일러는 비 JIT 컴파일러와 달리 구체적으로 무엇을합니까? 누군가 간결하고 이해하기 쉬운 설명을 줄 수 있습니까?




2
youtube.com/watch?v=yQ27DjKnxwo 가 유용하다는 것을 알았습니다 .
Adam Zerner 2016 년

답변:


518

JIT 컴파일러는 프로그램이 시작된 실행 되고 코드 (보통 바이트 코드 또는 VM 종류의 명령어)를 즉석에서 또는 일반적으로 호스트 CPU의 기본 형식 인 빠른 형식으로 컴파일합니다 (일반적으로 바이트 코드 또는 VM 명령어) 명령어 세트. JIT는 동적 런타임 정보에 액세스 할 수있는 반면 표준 컴파일러는 자주 사용되는 인라인 함수와 같은 더 나은 최적화를 수행 할 수 없습니다.

이것은 프로그램을 처음 실행 하기 전에 모든 코드를 기계 언어로 컴파일하는 기존 컴파일러와 대조적 입니다 .

다시 말하면, 기존 컴파일러는 프로그램을 처음 실행하기 전에 전체 프로그램을 EXE 파일로 빌드합니다. 최신 스타일 프로그램의 경우 의사 코드 (p-code)로 어셈블리가 생성됩니다. OS에서 프로그램을 실행 한 후에 만 ​​(예를 들어, 아이콘을 두 번 클릭하여) (JIT) 컴파일러가 시작되어 인텔 기반 프로세서 또는 이해할 수있는 머신 코드 (m 코드)를 생성합니다.


16
해석 된 코드와 달리 바이트 코드 또는 VM 명령어는 지연없이 즉시 실행되기 시작하지만 명령어는 기계어보다 느리게 실행됩니다.
Aaron

3
JIT는 종종 해석 된 코드와 함께 사용하여 기계 언어로 변환하지만, 순전히 해석 된 코드 (JITting없이)는 느립니다. JITter가없는 Java 바이트 코드조차도 실제로 느립니다.
Mark Cidade

48
그러나 대상은 기계 코드 일 필요는 없습니다. JRuby에는 몇 번의 호출 후에 Ruby 소스 코드를 Java 바이트 코드로 컴파일하는 JIT 컴파일러가 있습니다. 그런 다음 또 다른 두 번의 호출 후에 JVM JIT 컴파일러가 바이트 코드를 시작하여 원시 코드로 컴파일합니다.
Jörg W Mittag

4
Jörg가 언급했듯이 JIT가 반드시 즉시 호출되지는 않습니다. 종종 코드는 JITting 가치가 있다고 판단 될 때까지 해석됩니다. JITting은 지연을 유발할 수 있으므로, 거의 사용되지 않으면 일부 코드를 JIT 하지 않는 것이 더 빠를 수 있으므로 전체 런타임보다 빠른 응답이 더 중요합니다.
Adam Jaskiewicz 2009

3
@ErikReppen : 새로운 머신이 나오면, 기존 컴파일러를 사용하여 새로운 머신에 대한 프로그램을 컴파일하고 최적화하면 JIT보다 더 빠른 결과를 얻을 수 있습니다. 반면에, 새로운 기계에 최적화 된 JIT 는 새로운 기계가 발명되기 전에 공개 된 코드의 성능을 최적화 할 수 있습니다 .
supercat December

255

처음에 컴파일러는 고급 언어 (어셈블러보다 높은 수준으로 정의 됨)를 객체 코드 (기계 명령어)로 변환 한 다음 링커에 의해 실행 파일에 연결됩니다.

언어 진화의 한 시점에서, 컴파일러는 고급 언어를 의사 코드로 컴파일 한 다음 (통역사가 해석하여) 프로그램을 실행합니다. 따라서 객체 코드와 실행 파일이 제거되었으며 이러한 언어를 여러 운영 체제 및 하드웨어 플랫폼으로 이식 할 수있었습니다. 파스칼 (P-Code로 컴파일 된)은 첫 번째 중 하나였습니다. Java와 C #이 더 최근의 예입니다. 결국 P-Code라는 용어는 대부분의 의사 연산이 바이트 길이이므로 바이트 코드로 대체되었습니다.

JIT (Just-In-Time) 컴파일러는 런타임 인터프리터의 기능으로, 메소드가 호출 될 때마다 바이트 코드를 해석하는 대신 바이트 코드를 실행중인 머신의 머신 코드 명령어로 컴파일 한 다음이를 호출합니다. 대신 객체 코드. 이상적으로 객체 코드 실행의 효율성은 프로그램이 실행될 때마다 프로그램을 다시 컴파일하는 비 효율성을 극복합니다.


5
그러나 "JIT (Just-In-Time) 컴파일러는 런타임 인터프리터의 기능입니다" 라는 문구 가 혼동됩니다. 예 : -stackoverflow.com/questions/16439512/…
Stephen C

11
실제로 JIT는 추가 기능이었으며 여전히 -Xint 매개 변수를 사용하여 Java에 대해 비활성화 할 수 있으므로 기능 일뿐입니다.
Craig Trader

3
나는 완전히 동의하지 않습니다. JIT는 진화가 아니며 클래식 컴파일러의 대안입니다.
i486

1
JIT는 하드 배선 식 기계식 스위치에서 스마트 폰에 "OK Google"이라고 말하여 검색 기준을 지정하는 것까지 진화하는 한 단계입니다. Java 7/8의 일부로 사용할 수있는 현재 JIT는 Java 2의 일부로 사용할 수있는 것보다 뛰어납니다. 그것은 진화입니다.
Craig Trader

1
@ i486-썬 / 오라클 (AFAIK)은 네이티브 코드를 생성하는 Java 용 클래식 ( "한 번에") 컴파일러를 출시하지 않았습니다. JIT가 대안이라고 주장하는 것은 신축 적이다. 그들이 대안이라고 생각 될 때 결코 선적되지 않았다. (GCJ AOT 컴파일러는 Sun / Oracle과 아무런 관련이 없기 때문에 할인되었으며, 완전한 솔루션도 아니 었습니다. 지금은 확실하지 않습니다.)
Stephen C

69

JIT- 제때에 단어 자체가 필요할 때 (요청시) 말합니다

일반적인 시나리오 :

소스 코드는 기계 코드로 완전히 변환됩니다

JIT 시나리오 :

소스 코드는 구조와 같은 어셈블리 언어로 변환됩니다 (예 : C #의 경우 IL (중급 언어), java의 경우 ByteCode).

필요한 코드가 기계 코드로만 변환되어야하는 응용 프로그램이 필요한 경우에만 중간 코드가 기계 언어로 변환됩니다.

JIT와 비 JIT 비교 :

  • JIT에서 모든 코드가 기계 코드로 변환되는 것은 아닙니다. 필요한 코드의 일부가 기계 코드로 변환 된 다음 호출 된 메소드 또는 기능이 기계에없는 경우 기계 코드로 변환됩니다. CPU에 부담이됩니다.

  • 머신 코드가 런타임에 생성 될 때 JIT 컴파일러는 머신의 CPU 아키텍처 실행에 최적화 된 머신 코드를 생성합니다.

JIT 예 :

  1. Java JIT가 JVM (Java Virtual Machine)에 있음
  2. C #에서는 CLR (공용 언어 런타임)에 있습니다.
  3. Android에서는 최신 버전의 DVM (Dalvik Virtual Machine) 또는 ART (Android RunTime)에 있습니다.

7
JIT는 실제 제네릭 형식을 지원하는 프레임 워크에서 특별한 이점을 제공합니다. 제한없는 범위의 유형을 생성 할 수있는 일반적인 방법을 정의 할 수 있으며 각 유형마다 다른 기계 코드가 필요하지만 실제로 생성되는 유형에 대한 JIT 코드 만 생성합니다. 대조적으로, C ++에서는 컴파일러가 프로그램이 사용할 모든 유형의 코드를 생성해야합니다.
supercat December

6
JVM은 처음 실행될 때 JIT 코드를 작성하지 않습니다. 처음 몇 번은 바이트 코드를 해석합니다. 그런 다음 해당 코드가 충분히 자주 실행되면 JITting을 방해 할 수 있습니다.
ninjalj

1
Java의 JIT가 JVM이라고 말하고 있습니다. 그러나 우리는 이미 컴파일 된 코드를 JVM에 제공하지 않습니까? 그런 다음 다시 컴파일합니까?
Koray Tugay

@KorayTugay-바이트 코드를 JVM에 제공하고 JVM은 필요에 따라 그 일부를 기계 코드로 변환하므로 리소스가 절약됩니다.
Durai Amuthan.H

1
Java에서 JIT는 JVM이 아닙니다. 그것은 그것의 일부일뿐입니다.
1

25

다른 언급했듯이

JIT는 JIT (Just-in-Time)의 약자로, 런타임이 아니라 필요할 때 코드가 컴파일됩니다.

위의 논의에 포인트를 추가하기 위해 JVM은 함수가 실행되는 횟수를 카운트합니다. 이 수가 사전 정의 된 한계를 초과하면 JIT가 코드를 기계 언어로 컴파일하여 프로세서가 직접 실행할 수있는 코드를 처리합니다 (일반적으로 javac가 코드를 바이트 코드로 컴파일 한 다음 java와는 달리)-인터프리터는이 바이트 코드를 한 줄씩 해석하여 기계 코드 및 실행).

또한 다음에이 함수가 계산 될 때 코드가 한 줄씩 다시 해석되는 일반적인 해석과 달리 동일한 컴파일 된 코드가 다시 실행됩니다. 이렇게하면 실행이 더 빨라집니다.


14

JIT 컴파일러는 처음 실행될 때 바이트 코드를 동등한 기본 코드로 컴파일합니다. 모든 후속 실행에서 JVM은 성능을 최적화하기 위해 이미 컴파일 된 기본 코드 만 사용합니다.

여기에 이미지 설명을 입력하십시오

JIT 컴파일러가 없으면 JVM 인터프리터는 바이트 코드를 한 줄씩 변환하여 마치 원시 애플리케이션이 실행중인 것처럼 보이게합니다.

여기에 이미지 설명을 입력하십시오

출처


1
JIT에 대한 나의 해석은 자주 사용하는 함수가 '저장'되고 Java 바이트 코드에서 기본 ISA 종속 코드로 컴파일하는 비용이 무시되는 메모 화와 같은 역할을한다는 것입니다. 이것이 맞다면, 왜 자바가 처음부터 원시 코드로 완전히 컴파일되지 않습니까? 이것은 모든 종류의 런타임 컴파일을 줄이고 기계에 자바를 '네이티브'하게 만들 것입니까?
Michael Choi

12

JIT는 JIT (Just-in-Time)의 약자로, 런타임이 아니라 필요할 때 코드가 컴파일됩니다.

이것은 컴파일러가 특정 머신에 최적화 된 코드를 생성 할 수 있기 때문에 유리합니다. 일반적인 C 컴파일러와 같은 정적 컴파일러는 모든 코드를 개발자 컴퓨터의 실행 가능한 코드로 컴파일합니다. 따라서 컴파일러는 몇 가지 가정을 기반으로 최적화를 수행합니다. 사용자의 프로그램 실행 속도가 느려지지 않기 때문에 컴파일 속도가 느리고 최적화가 더 많이 수행 될 수 있습니다.


컴파일 된 코드가 사용자의 컴퓨터 어딘가에 저장되지 않아서 다음에 응용 프로그램을 실행할 때 JIT가 다시 컴파일 할 필요가없는 이유는 무엇입니까?
omerfarukdogan

좋은 관찰. 이 작업을 수행하는 것이 가능하지만 실제로 유리한지 여부는 플랫폼과 앱 사용에 따라 다릅니다. JIT 최적화는 오프라인 또는 사전 최적화와 반드시 같을 필요는 없으므로 이점은 'JITting이 아님'일뿐, 그다지 도움이되지 않을 수 있습니다.
Brian Lyttle

9

Java 컴파일러가 바이트 코드 (아키텍처 중립적)를 생성 한 후에는 JVM (Java)이 실행을 처리합니다. 바이트 코드는 로더에 의해 JVM에로드 된 다음 각 바이트 명령이 해석됩니다.

메소드를 여러 번 호출해야하는 경우 동일한 코드를 여러 번 해석해야하며 필요한 것보다 시간이 더 걸릴 수 있습니다. 따라서 JIT (Just-In-Time) 컴파일러가 있습니다. 바이트가 JVM에로드되면 (실행 시간) 전체 코드가 해석되지 않고 컴파일되므로 시간이 절약됩니다.

JIT 컴파일러는 런타임 중에 만 작동하므로 바이너리 출력이 없습니다.


2
컴파일 방법에 대한 정보 (읽기 : 안내서)가 거의 없기 때문에 전체 코드는 JVM에로드 될 때 컴파일되지 않습니다. 성능은 궁극적 인 목표입니다. JIT는 선택적입니다. 최적화를 위해 가장 많이 사용되는 방법을 모니터링하고 선택합니다. 그리고 개별 방법에 대해 최대 수준의 최적화에 도달 할 때까지이 작업을 계속 수행합니다.
Yaw Boakye

7

JIT (Just In Time Compiler) :
특정 바이트의 기계 명령어로 Java 바이트 코드를 컴파일합니다.

예를 들어, 자바 코드에 loop 문이 있다면 :

while(i<10){
    // ...
    a=a+i;
    // ...
 }

위의 루프 코드는 i 값이 0 인 경우 10 회 실행됩니다.

동일한 명령어가 10 회 실행되므로 바이트 코드를 10 번 반복해서 컴파일 할 필요는 없습니다. 이 경우 해당 코드를 한 번만 컴파일해야하며 필요한 횟수만큼 값을 변경할 수 있습니다. 따라서 JIT (Just In Time) 컴파일러는 앞서 언급 한대로 이러한 명령문과 메소드를 추적하고 성능 향상을 위해 이러한 바이트 코드를 기계 코드로 컴파일합니다.

또 다른 유사한 예는 문자열 / 문장 목록에서 "정규 표현식"을 사용하여 패턴을 검색하는 것입니다.

JIT 컴파일러는 모든 코드를 기계 코드로 컴파일하지 않습니다. 런타임에 유사한 패턴을 가진 코드를 컴파일합니다.

자세한 내용은 JIT 이해에 대한Oracle 문서를 참조하십시오 .


"동일한 명령어가 10 번 실행될 때마다 바이트 코드를 10 번 반복해서 컴파일 할 필요는 없습니다"– 일반 컴파일러는 어떻습니까? 이 조각을 여러 번 컴파일합니까?
TT_

4

일부 IL (중급 언어)로 컴파일 된 코드가 있습니다. 프로그램을 실행할 때 컴퓨터는이 코드를 이해하지 못합니다. 네이티브 코드 만 이해합니다. 따라서 JIT 컴파일러는 IL을 네이티브 코드로 즉석에서 컴파일합니다. 메소드 레벨에서이를 수행합니다.


2
"방법 수준"이란 무엇입니까?
Koray Tugay

4

나는 이것이 오래된 스레드라는 것을 알고 있지만 런타임 최적화는 여기서 논의되지 않은 JIT 컴파일의 또 다른 중요한 부분입니다. 기본적으로 JIT 컴파일러는 실행을 향상시키는 방법을 결정하기 위해 프로그램이 실행될 때 프로그램을 모니터링 할 수 있습니다. 그런 다음 런타임 중에 즉시 변경을 수행 할 수 있습니다. 구글 JIT 최적화 (자바 월드에 대한 좋은 기사가있다. )


3

JIT (Just In Time Compiler)는 실행 불가능한 입력을 받아 실행되는 적절한 기계 코드를 반환하는 소프트웨어입니다. 예를 들면 다음과 같습니다.

Intermediate representation    JIT    Native machine code for the current CPU architecture

     Java bytecode            --->        machine code
     Javascript (run with V8) --->        machine code

그 결과 특정 CPU 아키텍처의 경우 적절한 JIT 컴파일러를 설치해야합니다.

차이 컴파일러, 인터프리터 및 JIT

소스 코드를 기계 코드로 변환하려는 경우 일반적으로 예외가있을 수 있지만 다음을 사용할 수 있습니다.

  1. 컴파일러 : 소스 코드를 가져와 실행 파일을 반환
  2. 통역사 : 명령으로 프로그램 명령을 실행합니다. 소스 코드의 실행 가능한 세그먼트를 가져와 해당 세그먼트를 기계 명령어로 바꿉니다. 이 프로세스는 모든 소스 코드가 기계 명령어로 변환되어 실행될 때까지 반복됩니다.
  3. JIT : JIT의 다양한 구현이 가능하지만 JIT는 일반적으로 컴파일러와 인터프리터의 조합입니다. JIT는 먼저 해석을 통해 중개 데이터 (예 : Java 바이트 코드)를 기계 언어로 변환합니다. JIT는 종종 코드의 특정 부분이 자주 실행될 때를 감지하고 더 빠른 실행을 위해이 부분을 컴파일합니다.

2

Jit은 제 시간에 컴파일러를 나타냅니다. jit는 java 바이트 코드를 프로세서로 직접 보낼 수있는 명령어로 바꾸는 프로그램입니다.

특정 시스템 플랫폼에서 Java (Just-In-Time) 컴파일러 (실제로 두 번째 컴파일러)를 사용하면 바이트 코드를 특정 시스템 코드로 준수합니다. 코드가 jit 컴파일러에 의해 다시 컴파일되면 일반적으로 컴퓨터에서 더 빨리 실행됩니다.

JIT (Just-In-Time) 컴파일러는 가상 머신과 함께 제공되며 선택적으로 사용됩니다. 바이트 코드를 즉시 실행되는 플랫폼 별 실행 코드로 컴파일합니다.


2

JIT (Just-In-Time) 컴파일 (동적 변환 또는 런타임 컴파일) 은 실행 전에가 아니라 프로그램을 실행하는 동안 (런타임에) 컴파일 하는 컴퓨터 코드실행 하는 방법입니다 .

IT 컴파일은 머신 코드로의 변환 대한 두 가지 전통적인 접근 방식 (AOT)해석조합이며 , 두 가지 장점과 단점을 결합합니다. JIT 컴파일은 컴파일 된 코드의 속도와 해석의 유연성을 결합합니다 .

JVM에서 사용되는 JIT를 고려해 봅시다.

예를 들어, HotSpot JVM JIT 컴파일러는 동적 최적화를 생성합니다. 즉, Java 응용 프로그램이 실행되는 동안 최적화 결정을 내리고 기본 시스템 아키텍처를 대상으로 하는 고성능 네이티브 컴퓨터 명령어를 생성 합니다.

컴파일을 위해 메소드가 선택되면 JVM은 해당 바이트 코드를 JIT (Just-In-Time) 컴파일러에 공급합니다. JIT는 메소드를 올바르게 컴파일하기 전에 바이트 코드의 의미와 구문을 이해해야합니다. JIT 컴파일러가 메소드를 분석하는 데 도움을주기 위해 바이트 코드는 먼저 추적 트리라는 내부 표현으로 재구성되며, 이는 바이트 코드보다 기계 코드와 더 유사합니다. 그런 다음 분석법의 트리에서 분석 및 최적화가 수행됩니다. 결국 나무는 원시 코드로 변환됩니다.

트레이스 트리는 프로그래밍 코드의 런타임 컴파일에 사용되는 데이터 구조입니다. 트레이스 트리는 핫스팟 동안 실행되는 코드를 추적하고 컴파일하는 '정시 컴파일러'유형에 사용됩니다. 이것을 참조하십시오 .

참조 :


1

비 JIT 컴파일러는 소스 코드를 가져와 컴파일 타임에이를 머신 특정 바이트 코드로 변환합니다. JIT 컴파일러는 컴파일 타임에 생성 된 머신 독립적 바이트 코드를 가져와 런타임에 머신 특정 바이트 코드로 변환합니다. Java가 사용하는 JIT 컴파일러는 단일 바이너리가 수정없이 여러 플랫폼에서 실행될 수 있도록하는 것입니다.


0

바이트 코드의 20 %가 시간의 80 %로 사용됩니다. JIT 컴파일러는 이러한 통계를 가져오고 인라인 메소드를 추가하고 사용하지 않는 잠금을 제거하고 해당 머신에 고유 한 바이트 코드를 작성하여 바이트 코드의 20 %를 더 빠르게 실행하도록 최적화합니다. 나는이 기사에서 인용하고 있는데, 그것이 편리하다는 것을 알았다. http://java.dzone.com/articles/just-time-compiler-jit-hotspot


이것이 -1로 표시된 이유를 잘 모르겠습니다. 여기서 요점은 런타임 통계가 최적화를 돕는 데 사용된다는 것입니다.
eze

예, 그러나 대답은 그런 식으로 말하지 않았습니다. 말 그대로 JIT는 코드의 가장 인기있는 20 %를 최적화하지 않습니다.
mabraham

0

JIT는 더 빠르지 만 더 많은 메모리가 필요한 JVM 구현 중 일부에서 실행 엔진을 의미합니다. 이 체계에서, 메소드의 바이트 코드는 메소드가 처음 호출 될 때 고유 머신 코드로 컴파일됩니다. 그런 다음 메소드의 기본 기계 코드가 캐시되므로 다음에 동일한 메소드가 호출 될 때 재사용 될 수 있습니다.


2
새롭거나 더 나은 것을 제공하지 않으면 이와 같은 질문에 대답하지 않습니다. 당신이 어떤 반응을 얻는다면 그것은 아마도 공언이나 비판 일 것입니다 : 당신의 대답은 정확하지 않습니다. "JIT"는 JVM (Java Virtual Machine)으로 제한되지 않으며 "빠르지 만 더 많은 메모리를 사용합니다"는 효과가 있지만 JIT 개념에 내재되어 있지 않으며, 첫 번째 호출에서 메소드가 컴파일되지 않는 경우가 종종 있습니다. JIT'ing에 보낸 시간은 전반적으로 유리합니다.
zapl

0

JVM은 실제로 성능상의 이유로 런타임 중에 컴파일 단계를 수행합니다. 이것은 Java가 컴파일 실행을 완전히 분리하지 않았 음을 의미합니다. 먼저 Java 소스 코드에서 바이트 코드로의 소위 정적 컴파일을 수행합니다. 그런 다음이 바이트 코드는 실행을 위해 JVM으로 전달됩니다. 그러나 바이트 코드 실행 속도가 느리기 때문에 JVM은 바이트 코드 실행 빈도를 측정하고 매우 자주 실행되는 코드의 "핫스팟"을 발견하면 바이트 코드에서 "핫스팟"코드 (핫스팟 프로파일 러)의 기계 코드로 동적 컴파일을 수행합니다. 오늘날 효과적으로 Java 프로그램은 머신 코드 실행으로 실행됩니다.


0

JIT 컴파일러라고도하는 Just In Time 컴파일러는 Java의 성능 향상에 사용됩니다. 기본적으로 활성화되어 있습니다. 컴파일 시간은 실행 시간보다 일찍 완료됩니다. Java는 JVM에 JIT 컴파일러를 포함시켜 널리 사용했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.