Java는 컴파일 된 또는 해석 된 프로그래밍 언어입니까?


169

과거에는 C ++을 프로그래밍 언어로 사용했습니다. C ++로 작성된 코드는 객체 코드 "machine code"가 될 때까지 컴파일 프로세스를 거칩니다.

Java가 그 점에서 어떻게 작동하는지 알고 싶습니다. 사용자가 작성한 Java 코드는 컴퓨터에서 어떻게 실행됩니까?


14
C ++는 해석 될 수 있습니다. C 통역사가 몇 군데 있습니다.
Tom Hawtin-tackline

답변:


220

Java 구현은 일반적으로 2 단계 컴파일 프로세스를 사용합니다. Java 소스 코드는 Java 컴파일러에 의해 바이트 코드로 컴파일됩니다 . 바이트 코드는 JVM (Java Virtual Machine)에 의해 실행됩니다. 최신 JVM은 JIT (Just-in-Time) 컴파일 기술 을 사용하여 런타임시 하드웨어 CPU가 이해하는 기본 명령어로 바이트 코드를 컴파일합니다.

JVM의 일부 구현은 바이트 코드를 기계 코드로 컴파일하여 직접 실행하는 대신 바이트 코드를 해석하도록 선택할 수 있습니다. 이것은 여전히 ​​"통역사"로 간주되지만, 고급 소스 코드를 읽고 실행하는 인터프리터와는 상당히 다릅니다 (이 경우 Java 소스 코드는 직접 해석되지 않으며, 바이트 코드, Java 컴파일러의 출력).

기술적으로 Java를 원시 코드로 미리 컴파일하고 결과 바이너리를 실행할 수 있습니다. Java 코드를 직접 해석 할 수도 있습니다.

실행 환경에 따라 바이트 코드는 다음과 같습니다.

  • 미리 컴파일되어 네이티브 코드로 실행 (대부분의 C ++ 컴파일러와 유사)
  • 적시에 컴파일 및 실행
  • 해석
  • 지원되는 프로세서에서 직접 실행 (바이트 코드는 일부 CPU의 기본 명령어 세트 임)

20
실제로 일부 HotSpot JVM은 바이트 코드를 해석하여 시작하며 컴파일 할 가치가있는 것을 파악한 후 코드를 실행하는 방법에 대한 통계를 수집 한 후에 만 ​​원시 코드로 컴파일합니다. 예를 들어 각 조건 분기에서 가장 일반적인 경로를 파악합니다.
Stephen C

1
따라서 'Hotspot'이라는 용어는 :) 최적화를 얻기 위해 자주 실행되는 작업을 수행합니다.
정오 실크

4
-Xcomp를 사용하여 HotSpot에서 인터프리터를 끌 수 있습니다. 응용 프로그램에서 나쁜 생각이 무엇인지 알아볼 가치가 있습니다.
Tom Hawtin-tackline

1
"현재 Sun HotSpot JVM 버전은 JIT (Just-In-Time) 컴파일 링 기술을 사용하여 런타임시 CPU가 이해할 수있는 기본 명령어로 바이트 코드를 컴파일합니다." JVM이 인터프리터라는 인상을 받았지만 바이트 코드를 더 컴파일하는 것이 좋습니다. 혼란 스러워요. 또한 런타임에 즉시 실행되도록 작성되었습니다. 누군가도 이것을 설명 할 수 있습니까?
Anand

java는 해석 된 언어이므로 성능 또는 Java 응용 프로그램 실행에 어떤 영향을 미치는지
NAND

93

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

Java로 작성된 코드는 다음과 같습니다.

  • 먼저 위 이미지의 왼쪽 섹션에 표시된대로 javac 라는 프로그램에 의해 바이트 코드로 컴파일 됩니다 .
  • 그런 다음 위 이미지의 오른쪽 섹션에 표시된 것처럼 java 라는 다른 프로그램 이 Java 런타임 환경을 시작 하고 Java Interpreter / JIT Compiler를 사용하여 바이트 코드를 컴파일 및 / 또는 해석 할 수 있습니다 .

Java는 언제 바이트 코드를 해석하고 언제 컴파일합니까? 애플리케이션 코드는 처음에 해석되지만 JVM은 자주 실행되는 바이트 코드 시퀀스를 모니터하고이를 하드웨어에서 직접 실행하기 위해 머신 코드로 변환합니다. 몇 번만 실행되는 바이트 코드의 경우 컴파일 시간이 절약되고 초기 대기 시간이 줄어 듭니다. 자주 실행되는 바이트 코드의 경우 JIT 컴파일은 느린 해석의 초기 단계 후에 고속으로 실행하는 데 사용됩니다. 또한 프로그램이 소수의 코드를 실행하는 데 대부분의 시간을 소비하므로 컴파일 시간이 단축됩니다. 마지막으로, 초기 코드 해석 중에 컴파일 전에 실행 통계를 수집하여보다 나은 최적화를 수행 할 수 있습니다.


Java가 많은 메모리를 사용하는 것은 캐시 된 바이트 코드 때문입니까?
Pedro Gordo

3
@ sedulam : '많은 메모리'는 희미한 진술입니다. Java의 메모리 관리는 매우 간단합니다. 3 세대는 JVM이 오브젝트 작성 및 유지 보수에 사용하는 것입니다. 이 다른 SO 답변 이 도움이 될 수 있습니다.
displayName

위의 설명을 통해 이론적으로 C ++ 컴파일 코드는 논리적으로 유사한 Java 코드보다 항상 빠릅니다. JIT가 기계 코드로 변환하지 않기로 결정한 .class 파일의 일부가 항상 있기 때문입니다. 다시 말해, java는 C ++이 보여준 베어 메탈 실행 속도를 절대로 잡을 수 없습니다. 이것이 올바른 가정입니까?
DevdattaK

@ DevdattaK : C ++을 많이 모르지만 내 생각 에 작고 전문적인 프로그램의 경우 Java는 속도가 높지 않은 코드 부분을 컴파일하는 데 시간을 낭비하지 않기 때문에 결과를 더 빨리 제공 할 수 있습니다.
displayName

1
@DevdattaK 가정은이 위키 페이지 en.m.wikipedia.org/wiki/Java_performance?wprov=sfla1 에서 논의됩니다 . 즉, 항상 사실은 아닙니다.
Sundar Rajan

57

프로그래밍 언어가 해석 및 / 또는 컴파일 될 수 있으므로 "통역 언어"또는 "컴파일 언어"라는 용어는 의미가 없습니다.

기존 Java 구현의 경우 대부분 바이트 코드 컴파일 단계가 포함되므로 컴파일이 포함됩니다. 런타임은 또한 바이트 코드를 동적으로로드 할 수 있으므로 항상 어떤 형태의 바이트 코드 인터프리터가 필요합니다. 해당 인터프리터는 내부 코드로 컴파일을 사용하거나 사용하지 않을 수 있습니다.

요즘에는 부분적 적시 컴파일이 JavaScript와 같이 한 번 "해석"된 것으로 여겨지는 많은 언어에 사용됩니다.


5
또한 Google의 V8 JavaScript 실행 엔진은 부분적인 적시 컴파일 만 수행하지 않습니다. 그것은 항상 사실, V8도하지 않고, 네이티브 코드로 컴파일 통역을. 그것은이 단지 컴파일러 (맥신과 비슷한, 그러나 맥신 달리 V8은 하나의 컴파일러를 가지고). 이 세 가지 예 (GCJ, Maxine 및 V8)는 모두 귀하의 요점을 더욱 강력하게 증명합니다. 해석 된 언어 나 컴파일 된 언어는 없습니다. 언어는 해석되거나 컴파일되지 않습니다. 언어는 단지 입니다 (즉, 실제로 슈리 람 크리슈나 머티하여 견적입니다).
Jörg W Mittag

3
왜 자바 질문에서 자바 스크립트에 대해 이야기하고 있습니까?
Koray Tugay

1
@KorayTugay 예를 들어. 나는 분명히 자바와 자바 스크립트가 그들의 이름의 처음 네 글자 이외의 공통점이 있다는 것을 암시하고 싶지 않습니다.
starblue

해석 언어와 컴파일 언어의 차이가 컴파일 언어 바이너리가 언제라도 실행 흐름을 변경할 수 없다는 것을 의미하지는 않지만, 해석 언어는 현재 작동하는 일부 기능에 매우 순종합니다. C의 라이브러리는 옵션이지만 다른 언어에서는 다른 플랫폼에서 업데이트되거나 완전히 다른 코드 일 수있는 C 이진 확장자가없는 배열 객체를 가질 수 없습니다. 스크립팅 언어는 두 언어 모두에서 실행될 수 있지만 컴파일 된 언어는 실행하기 위해 다른 바이너리가 필요합니다
Eaton Emmerich

53

Java는 바이트 코드로 컴파일 된 다음이를 해석하는 Java VM으로 이동합니다.


33
...하지만 정확하지는 않습니다.
Stephen C

2
JVM은 바이트 코드를 "해석"하지 않도록 선택할 수 있습니다. JIT 컴파일하고 직접 실행할 수 있습니다.
Mehrdad Afshari

1
JIT는 기술적으로 직접 실행하지 않습니다. 그것이 어떻게 실행되었는지 기억하고 있습니다.
cletus

Mehrdad : 동의합니다. 여기까지 JIT 작업에 대해 설명하지 않았습니다. JVM까지 고려한대로 어쨌든 간단하게 답을 유지하고있었습니다. :)
Noon Silk

7
cletus : JIT 바로 실행됩니다. JIT는 바이트 코드를 읽고 (예 : 완전한 방법) 머신 코드로 컴파일 하여 점프합니다.
Mehrdad Afshari

12

Java는 컴파일 된 프로그래밍 언어이지만 실행 가능한 기계어 코드로 직접 컴파일하는 것이 아니라 JVM 바이트 코드라는 중간 이진 형식으로 컴파일됩니다. 바이트 코드는 프로그램을 실행하기 위해 컴파일 및 / 또는 해석됩니다.


11

둘 다. 먼저 자바 컴파일 된 (일부는 "번역됨")을 바이트 코드로 변환 한 다음 JIT의 분위기에 따라 컴파일하거나 해석합니다.


32
그것은 분위기를 발전시키기위한 고급 소프트웨어입니다 :)
Thorarin

5
JIT는 실제로 컴파일러가 수행 할 수없는 런타임 정보 (프로파일 러와 같은)를 기반으로 최적화를 수행 할 수있는 매우 정교한 소프트웨어입니다. 사전 프로그램). 그러나 아마 실제로 기분이 없을 것입니다 ... :-)
Jesper

5

Java는 컴파일과 해석을 모두 수행합니다.

Java에서 프로그램은 실행 파일로 컴파일되지 않습니다 . 그것들은 바이트 코드컴파일되며 (이전에 논의 된 바와 같이) JVM (Java Virtual Machine)은 런타임에 해석 / 실행됩니다. javac 컴파일러를 사용하면 Java 소스 코드가 바이트 코드로 컴파일됩니다. 바이트 코드는 파일 확장자가 .class 인 디스크에 저장됩니다 .

프로그램이 실행될 때 바이트 코드가 변환 됩니다. JIT (Just-In-Time) 컴파일러를 사용하여 바이트 코드가 변환 될 수 있습니다. 결과적으로 머신 코드가 생성되어 메모리에 공급되어 실행됩니다.

Javac 는 Java 코드를 바이트 코드로 컴파일 하는 Java 컴파일러 입니다. JVM은 바이트 코드를 원시 시스템 코드로 실행 / 해석 / 변환하는 Java Virtual Machine입니다. Java에서는 인터프리터 언어로 간주되지만 바이트 코드가 JVM에있을 때 JIT (Just-in-Time) 컴파일을 사용할 수 있습니다. JIT 컴파일러는 많은 섹션에서 (또는 전체는 드물게) 바이트 코드를 읽고 머신 코드로 동적으로 컴파일하므로 프로그램을 더 빠르게 실행 한 다음 다시 컴파일 할 필요없이 나중에 캐시하고 재사용 할 수 있습니다. 따라서 JIT 컴파일은 컴파일 된 코드의 속도와 해석의 유연성을 결합합니다.

해석 언어는 이전에 기계어 명령으로 프로그램을 컴파일하지 않고, 그 구현의 대부분은 직접 자유롭게 명령을 실행하는 언어 프로그래밍의 유형입니다. 인터프리터는 프로그램을 직접 실행하여 각 명령문을 기계 코드로 이미 컴파일 된 하나 이상의 서브 루틴 시퀀스로 변환합니다.

컴파일 된 언어 (미리 입력 런타임 변환이 일어나지 않는다 소스 코드 단계별 실행기) 그 구현 일반적 컴파일러 (소스 코드에서 머신 코드를 생성 번역)되지 통역되는 프로그래밍 언어

Java와 같은 최신 프로그래밍 언어 구현에서 플랫폼이 두 옵션을 모두 제공하는 것이 점차 인기를 얻고 있습니다.


해야한다 "바이트 코드는 보다는"보다 변환 할 수 " 입니다 변환". Java 사양은 바이트 코드를 정의합니다. 바이트 코드가 (a) 하드웨어 에서 직접 실행되는지 , (b) 인터프리터를 통해 실행되는지 , (c) 사전에 컴파일되거나, (d) 런타임에 부분적으로 즉시 컴파일 되는지 여부 는 모두 구현 세부 사항으로 남습니다. 이러한 네 가지 옵션 모두 실제로 다양한 실제 Java 구현에서 사용되었습니다.
Basil Bourque

이것을 지적 해 주셔서 감사합니다. 바이트 코드가 기계 코드로 변환되지 않으면 어떻게됩니까? 바이트 코드가 일부 프로세서의 기본 명령어 세트이고 변환이 필요하지 않은 시나리오를 생각할 수 있습니다. 아니면 뭔가 빠졌습니까?
주요

I가 준 링크를 클릭 이젤 DBX (직접 바이트 코드 실행) JVM 바이트 코드의 일부는 기술 이다 는 CPU (좀-그렇다고)의 기본 기계 명령어를. 그렇지 않으면 바이트 코드 (a) 인터프리터 (즉석에서), (b) 컴파일러에서 미리 또는 (c) 적시에 컴파일 된 컴파일러 ( 처음에는 해석 한 다음 실행 중에 컴파일 및 캐시되기도합니다.
Basil Bourque

-2

Java는 Java Virtual Machine 이라는 플랫폼을 대상으로하는 바이트 컴파일 언어 이며 스택 기반이며 많은 플랫폼에서 매우 빠른 구현을 제공합니다.


1
"바이트 컴파일 된"은 무엇을 의미합니까?
Jesper

2
@Jesper : "바이트 컴파일"은 일반적으로 "바이트 코드로 컴파일"을 의미합니다. "바이트 코드"는 모든 종류의 비 텍스트 중간 코드 (일반적으로 머신 실행 불가능)를 포괄하는 일반적인 용어입니다.
Greg Hewgill

-3

인용 : https://blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

응용 프로그램 개발자는 현재 시장에 나와있는 다양한 OS에서 응용 프로그램 코드를 개발할 수 있습니다. Java 언어는이 단계에서 OS에 독립적입니다. Java 응용 프로그램 개발자가 작성한 화려한 소스 코드는 이제 Java 용어로 클라이언트 측 컴파일이라고하는 Java 바이트 코드로 컴파일됩니다. Java 바이트 코드로의이 컴파일은 Java 개발자가 '한 번 작성'할 수있게합니다. Java 바이트 코드는 호환 가능한 모든 OS 및 서버에서 실행될 수 있으므로 소스 코드를 OS / Server와 무관하게 만들 수 있습니다. Java 바이트 코드 생성 후 Java 응용 프로그램과 기본 OS / 서버 간의 상호 작용이 더 친밀합니다. 여정은 계속됩니다. 엔터프라이즈 애플리케이션 프레임 워크는 JVM (Java Virtual Machine) 또는 Java Runtime Environment (JRE)로 알려진 런타임 환경에서 이러한 Java 바이트 코드를 실행합니다. JVM은 OS 및 서버에서 제공하는 리소스를 활용하기 때문에 기본 OS 및 하드웨어와 밀접한 관련이 있습니다. Java 바이트 코드는 이제 플랫폼 별 기계 언어 실행 가능 코드로 컴파일됩니다. 이것을 서버 측 컴파일이라고합니다.

그래서 Java는 분명히 컴파일 된 언어라고 말할 것입니다.

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