자바 바이트 코드
Java bytecodeJava 바이트 코드는 Java Virtual Machine(JVM; Java 가상 머신)의 바이트 코드 구조 명령 세트입니다.
자바와의 관계
Java 프로그래머는 Java 바이트 코드를 전혀 의식하거나 이해할 필요가 없습니다.그러나 IBM developerWorks 저널에서 제시된 바와 같이 "바이트 코드와 Java 컴파일러가 생성할 가능성이 높은 바이트 코드를 이해하는 것은 조립에 대한 지식이 C 또는 C++[1] 프로그래머에게 도움이 되는 것과 같은 방식으로 Java 프로그래머에게 도움이 됩니다."
명령 집합 아키텍처
JVM은 스택머신이자 레지스터 머신입니다.메서드 호출의 각 프레임은 "operand stack"과 "local variables"[2]: 2.6 의 배열을 가집니다.오퍼랜드 스택은 오퍼랜드에서 계산 및 호출된 메서드의 반환값 수신에 사용되며 로컬 변수는 레지스터와 동일한 목적으로 사용되며 메서드 인수를 전달하기 위해서도 사용됩니다.오퍼랜드 스택과 로컬 변수 배열의 최대 크기는 컴파일러에 의해 계산되며 각 [2]: 4.7.3 메서드의 속성의 일부입니다.각 값은 0 ~65535의 값에서 독립적으로 사이징할 수 있습니다.각 값은 32비트입니다. long
그리고.double
타입(64비트)은 연속된2개의[2]: 2.6.1 로컬 변수(로컬 변수 배열에 64비트를 정렬할 필요는 없습니다) 또는 오퍼랜드스택의 1개의 값(단,[2]: 2.6.2 스택 깊이의 2개의 유닛으로 카운트됩니다)을 사용합니다.
명령 집합
각 바이트 코드는 opcode를 나타내는1바이트와 오퍼랜드의 [2]: 2.11 0바이트 이상으로 구성됩니다.
사용 가능한 256바이트 길이의 opcode 중 2015년 현재[update] 202개(~79%), 51개(~20%), 3개(~1%)는 JVM 구현용으로 [2]: 6.2 영구 예약되어 있습니다.이 중 2개(impdep1
그리고.impdep2
)는, 실장 고유의 소프트웨어와 하드웨어의 트랩을 각각 제공합니다.세 번째는 디버거가 브레이크 포인트를 구현하는 데 사용됩니다.
명령은 다음과 같은 다양한 그룹으로 나뉩니다.
- 로드 및 저장(예:
aload_0
,istore
) - 산술 및 논리(예:
ladd
,fcmpl
) - type conversion(변환)을 입력합니다(예:
i2b
,d2i
) - 오브젝트 작성 및 조작(
new
,putfield
) - 오퍼랜드 스택 관리(예:
swap
,dup2
) - 제어 전송(예:
ifeq
,goto
) - 메서드 호출 및 반환(예:
invokespecial
,areturn
)
또한 예외 발생, 동기화 등 보다 전문적인 작업에 대한 지침도 몇 가지 있습니다.
많은 명령어에는 동작하는 [2]: 2.11.1 오퍼랜드의 유형을 나타내는 접두사 및/또는 접미사가 있습니다.이것들은 다음과 같습니다.
프리픽스/서픽스 | 오퍼랜드 타입 |
---|---|
i | 정수 |
l | 긴 |
s | 짧다 |
b | 바이트 |
c | 성격 |
f | 흘러가다 |
d | 이중으로 하다 |
a | 언급 |
예를들면,iadd
는 2개의 정수를 추가합니다.dadd
두 개의 더블을 추가합니다.그const
,load
,그리고.store
명령어는 형식의 접미사를 사용할 수도 있습니다._n
여기서 n은 0 ~3 의 수치입니다.load
그리고.store
. 의 최대 n 입니다.const
타입에 따라 다릅니다.
그const
instructions는 지정된 유형의 값을 스택에 푸시합니다.예를들면,iconst_5
는 값이 5인 정수(32비트 값)를 스택에 푸시합니다.dconst_1
는 값이 1인 더블(64비트 부동소수점 값)을 스택에 푸시합니다.또,aconst_null
(이것에 의해null
언급.의 n은load
그리고.store
instructions는 로드원 또는 저장처 로컬 변수 배열의 인덱스를 지정합니다.그aload_0
instruction은 로컬 변수 0의 개체를 스택에 푸시합니다(보통this
오브젝트) istore_1
는 스택 상단의 정수를 로컬 변수1에 저장합니다.3을 초과하는 로컬 변수의 경우 접미사가 삭제되고 오퍼랜드를 사용해야 합니다.
예
다음 Java 코드를 고려합니다.
바깥의: 위해서 (인트 i = 2; i < > 1000; i++) { 위해서 (인트 j = 2; j < > i; j++) { 한다면 (i % j == 0) 계속하다. 바깥의; } 시스템..나가..인쇄 (i); }
Java 컴파일러는 위의 Java 코드를 다음과 같이 바이트 코드로 변환할 수 있습니다.
0: 아이콘_2 1: istore_1 2: iload_1 3: 사이푸시 1000 6: if_icmpge 44 9: 아이콘_2 10: istore_2 11: iload_2 12: iload_1 13: if_icmpge 31 16: iload_1 17: iload_2 18: 렘 19: 동작하고 있다 25 22: 에 가다 38 25: 인크 2, 1 28: 에 가다 11 31: 정전기 #84; // 들판 java/lang/시스템나가.:Ljava/io/PrintStream; 34: iload_1 35: 가상 호출 #85; // 메서드 java/io/PrintStream.println:(I)V 38: 인크 1, 1 41: 에 가다 2 44: 돌아가다
시대
Java 바이트 코드를 생성하여 Java 가상 머신을 대상으로 하는 가장 일반적인 언어는 Java입니다.원래 한 개의 컴파일러만 존재했는데, 이는 Java 소스 코드를 Java 바이트 코드로 컴파일하는 Sun Microsystems의 javac 컴파일러였다. 그러나 Java 바이트 코드에 대한 모든 사양을 사용할 수 있게 되었기 때문에 다른 당사자들은 Java 바이트 코드를 생성하는 컴파일러를 제공했다.기타 컴파일러의 예는 다음과 같습니다.
- Eclipse 컴파일러 for Java(ECJ)
- Jikes, Java에서 Java 바이트 코드로 컴파일(IBM에서 개발, C++로 구현)
- 에스프레소, Java에서 Java 바이트 코드로 컴파일(Java 1.0만 해당)
- GNU 컴파일러 for Java(GCJ)는 Java에서 Java 바이트 코드로 컴파일합니다.또, 네이티브 머신 코드로 컴파일 할 수도 있어 버전 6까지 GNU 컴파일러 컬렉션(GCC)의 일부였습니다.
일부 프로젝트에서는 Java 어셈블러가 Java 바이트 코드를 손으로 쓸 수 있도록 지원합니다.어셈블리 코드는 머신에 의해 생성될 수도 있습니다.예를 들어 Java 가상 머신을 대상으로 하는 컴파일러에 의해 생성됩니다.주요 Java 어셈블러는 다음과 같습니다.
- Jasmin, Java 클래스의 텍스트 설명을 Java 가상 머신 명령 집합을 사용하여 간단한 어셈블리형 구문으로 작성하여 Java 클래스[3] 파일을 생성합니다.
- Java 가상 머신의 매크로 어셈블리 언어인 자메이카.Java 구문은 클래스 또는 인터페이스 정의에 사용됩니다.메서드 본문은 바이트 코드 [4]명령을 사용하여 지정합니다.
- Krakatau Bytecode Tools는 현재 Java 클래스 파일용 디컴파일러 및 디스어셈블러와 클래스 [5]파일을 만드는 어셈블러의 3가지 도구를 포함하고 있습니다.
- Lilac, Java 가상 [6]머신의 어셈블러 및 디스어셈블러입니다.
다른 회사는 다음과 같은 Java 가상 머신을 대상으로 하는 다양한 프로그래밍 언어용 컴파일러를 개발했습니다.
- 콜드퓨전
- JRuby와 Jython, Ruby와 Python 기반의 두 스크립트 언어
- Apache Groovy, 정적 타이핑 및 정적 컴파일 기능을 갖춘 옵션 타입의 동적 범용 언어
- 객체 지향 및 함수 프로그래밍을 지원하는 타입 세이프 범용 프로그래밍 언어인 Scala
- JGNAT 및 AppletMagic, Ada 언어에서 Java 바이트 코드로 컴파일
- C에서 Java 바이트 코드 컴파일러[데드링크]
- Lisp 패밀리의 기능적이고 불변의 범용 프로그래밍 언어인 Clojure는 동시성을 강조합니다.
- 스킴 프로그래밍 언어의 구현인 Kawa는 리스프의 방언이기도 하다.
- MIDlet Pascal
- JavaFX 스크립트 코드가 Java 바이트 코드로 컴파일됩니다.
- Kotlin, 유형 추론을 가진 정적 유형의 범용 프로그래밍 언어
- 오브젝트 파스칼 소스 코드는 Free Pascal 3.0+ [7][8]컴파일러를 사용하여 Java 바이트 코드로 컴파일됩니다.
실행
현재 Java 바이트 코드를 실행하는 데 사용할 수 있는 Java 가상 머신은 무료 제품과 상용 제품 모두 여러 가지가 있습니다.가상 머신에서 바이트 코드를 실행하는 것이 바람직하지 않은 경우 개발자는 GCJ(GNU 컴파일러 for Java) 등의 도구를 사용하여 Java 소스 코드 또는 바이트 코드를 네이티브 머신 코드로 직접 컴파일할 수도 있습니다.일부 프로세서는 Java 바이트 코드를 네이티브로 실행할 수 있습니다.이러한 프로세서를 Java 프로세서라고 부릅니다.
동적 언어 지원
Java 가상 시스템은 동적으로 입력된 언어를 지원합니다.기존 JVM 명령어 세트의 대부분은 정적으로 입력됩니다.즉, 메서드콜은 컴파일 시에 시그니처를 타입 체크하고 실행시간을 늦추거나 대체 접근법에 [9]의한 메서드 디스패치를 선택하는 메커니즘이 없습니다.
JSR 292(Java 플랫폼에서 동적으로 [10]입력된 언어 지원)는 새로운 기능을 추가했습니다.invokedynamic
동적 유형 검사에 의존하는 메서드 호출을 허용하기 위한 JVM 수준의 명령입니다(기존 정적 유형 검사 대신).invokevirtual
명령)을 참조해 주세요.Da Vinci Machine은 동적 언어를 지원하기 위한 JVM 확장을 호스팅하는 가상 머신의 프로토타입 구현입니다.JSE 7을 지원하는 모든 JVM에는invokedynamic
opcode를 클릭합니다.
「 」를 참조해 주세요.
- Java 바이트 코드 명령 목록
- Java 클래스 파일
- JVM 언어 목록
- Java 백포트 도구
- C에서 Java 가상 머신 컴파일러
- JStik
- 공통 중간 언어(CIL), Microsoft의 Java 바이트 코드 경쟁사
- 오브젝트 웹 ASM
- 바이트 코드 엔지니어링 라이브러리
레퍼런스
- ^ "IBM Developer". developer.ibm.com. Retrieved 20 February 2006.
{{cite web}}
: CS1 maint :url-status (링크) - ^ a b c d e f g Lindholm, Tim; Yellin, Frank; Bracha, Gilad; Buckley, Alex (2015-02-13). The Java Virtual Machine Specification (Java SE 8 ed.).
- ^ Jasmin 홈페이지
- ^ 자메이카:Java Virtual Machine(JVM; Java 가상 머신) 매크로 어셈블러
- ^ 크라카타우 홈페이지
- ^ 라일락 홈페이지
- ^ 무료 Pascal 3.0 릴리즈 노트
- ^ 프리 Pascal JVM 타깃
- ^ Nutter, Charles (2007-01-03). "InvokeDynamic: Actually Useful?". Retrieved 2008-01-25.
- ^ 'JSR 292' 참조