자바코드의 실행과 메모리구조 그리고 JVM - 1

Muzi·2023년 3월 18일
0

JAVA

목록 보기
2/4

컴파일

JAVA의 컴파일

  • c언어는 컴파일이전에 전처리 과정이 있음
소스코드(hello.c) -> 전처리(preprocess) -> 전처리 후 소스(hello.i) -> Compiler -> 
Assembly소스(hello.s) -> Assembler -> 오브젝트파일(hello.o) -> Linker -> 실행파일(hello.out) -> 
Loader -> Memory
  • JAVA는 JVM이 전처리 과정을 거친다
  • Javac 명령어를 통해 컴파일
  • 컴파일이라고해서 C나 C++이 컴파일하면 생성하는 기계어와 동일하게 생각하면 안된다

    좀더 자세히 보자
    런타임 환경의 과정이 위 그림의 JVM부분과 같다 즉, JVM은 런타임 프로세스

  • Java의 컴파일 과정

어휘 분석

  • 키워드, 리터럴, 연산자 같은 오퍼레이터들을 수집한다
    • 어휘소라고한다
    • 키워드 ex) public, class
    • 리터럴 ex) "hello world"
    • 연산자 ex) +-
  • 수집한 어휘소를 하나의 스트림으로 만든다 => 토큰 스트림

구문 분석(Syntax Analysis)

: 토큰 스트림을 통해서 문법에 맞는지 확인하는 과정

  • 컴파일시 에러로 나타남

의미 분석

  • 타입 검사, 자동 타입 변환 등 진행
  • 구문 분석에서 잡지 못한 타입에러를 잡음
  • String에 Integer값 입력시, 구문 분석이 아니라, 의미 분석에서 에러 발생

바이트 코드

: 컴파일시 생성되는 중간 코드 = 바이트 코드

  • .class 파일
  • JVM이 읽을 수 있는 언어
  • JVM은 이 바이트 코드를 읽어 컴퓨터가 이해할 수 있는 언어로 변환한다
  • Class Format, type의 표현, constant pool, instruction set으로 구성
  • JAVAP = 바이트코드를 우리가 볼 수 있게 바꾸어주는 프로그램

1. Class Format

  • magic - 클래스 파일의 첫 4바이트, 자바 클래스파일이 맞는지 구분하는 용도
    • 파일 형식 고유 식별자
    • java 클래스파일의 magic은 16진수인 "CAFEBABE"
    • 항상 동일한 값
    • JVM의 버전, 클래스 이름 및 클래스 파일에 대한 정보가 포함된 헤더섹션이 포함되어있다는 점에서 MS windows에서 사용하는 PE헤더와 용도가 유사하다
  • minor_version, major_version
    • 클래스의 버전을 나타냄
    • 즉, JDK 1.6이냐 1.8이냐를 구분하는데 JDK 버전에 따라 다른 값이 나온다
  • constant_pool_count
    • 클래스 파일의 상수 풀(constant pool)의 개수를 나타내는 용도
  • access_flags
    • 클래스의 modifier 정보를 나타낸다

      namevalue의미
      ACC_PUBLIC0x0001클래스가 public, 다른 클래스에서 접근이 가능
      ACC_FINAL0x0010클래스를 상속할 수 없다
      ACC_SUPER0x0020invokespecial 인스트럭션은 수퍼클래스의 메서드를 호출함
      ACC_INTERFACE0x0200interface임을 명시
      ACC_ABSTRACT0x0400abstract임을 명시
      ACC_SYNTHETIC0x1000소스 코드에서 명시적으로 선언되지 않고 컴파일러에서 생성되었음을 의미
      ACC_ANNOTATION0x2000annotation @interface임을 명시
      ACC_ENUM0x4000enum class 임을 명시
      ACC_MODULE0x8000module임을 명시
  • interfaces_count
    • 클래스가 구현한 인터페이스의 개수와 각 인터페이스에 대한 constatnt_pool내의 인텍스를 나타냄

2. type의 표현

  • Java 바이트 코드의 표현은 우리가 사용할 수 있는 모든 type을 bytecode expression으로 변환할 수 있다
// 예를 들어서 다음과 같은 코드가 있다면
Object print(String str, int i)

// Type의 표현으로 다음과 같이 표현가능하다
(java/lang/String;I)Ljava/lang/Object;

3.Constant pool

JVM이 동적으로 코드를 실행시킬 때 모든 데이터를 즉시 생성하는 것이 아니라,
constant pool에 저장 후 Constant pool에 존재하는 데이터를 우선적으로 가져와 메모리를 더욱 효율적으로 사용할 수 있게한다

  • 런타임에 생성되는 Static 상수 저장소

  • 즉, 정적영역에 있는 메모리이기에 GC의 대상 x

  • # 해시코드로 시작하는 특징

  • Constant pool에서 제공하는 타입

  • 원문

    typebit
    Integer(Boolean,Short,Byte 상수는 Integer 취급32bit
    Float32bit
    Double, Long64bit
    String16bit(실제값이 아닌 주소값이 저장된다)

4. Instruction Set

  • OpCode와 Operands로 구성되는데
  • 자바바이트코드에서는 1 Byte의 OpCode와 2 Byte의 Operands 로 구성
public class Test { 
	private String name; 
    public String getName() {
    	return name; 
    } 
    public void setName(String name) {
    this.name = name; 
    } 
}

해당 코드를 javap 명령(javac Test.java, javap -c Test)을 통해 bytecode를 보면

// 이렇게 나온다
public class bridge.view.Test {
  public bridge.view.Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public java.lang.String getName();
    Code:
       0: aload_0
       1: getfield      #2                  // Field name:Ljava/lang/String;
       4: areturn

  public void setName(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #2                  // Field name:Ljava/lang/String;
       5: return
}
  • aload_0 : local variable 을 stack 에 push 한다, 0은 frame안 instruction 위치
  • invokespecial : instance Method 를 호출하고 결과를 stack 에 push한다.

해당 링크를 통해 자세한 명령어 정의를 볼 수 있다

추가

  • JAVAP - 바이트코드를 우리가 볼 수 있게 바꾸어주는 프로그램
  • 바이너리 코드는 무엇인가?
    - 0과1로 구성된 코드
    • c로 작성된 .c를 컴파일한 .obj파일이 바이너리 코드
    • .obj 파일만으로는 실제 컴퓨터가 이해하여 실행할 수 없다. 이때 필요한 것이 링커로 링커는 여러 개의 코드와 데이터를 모아서 연결하여 메모리에서 실행 가능 한 파일로 만드는 역할

Reference

아래 블로그들을 토대로 작성하였습니다

https://velog.io/@jieuni/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DAssembler
https://www.geeksforgeeks.org/cc-preprocessors/
https://catch-me-java.tistory.com/9
https://github.com/gyoogle/tech-interview-for-developer/blob/master/Language/%5Bjava%5D%20%EC%9E%90%EB%B0%94%20%EC%BB%B4%ED%8C%8C%EC%9D%BC%20%EA%B3%BC%EC%A0%95.md
https://wonit.tistory.com/589
https://wonit.tistory.com/588
https://d2.naver.com/helloworld/1230
https://docs.oracle.com/javase/specs/jvms/se16/html/jvms-4.html
https://www.baeldung.com/jvm-constant-pool
https://jiwondev.tistory.com/114#head5

profile
좋아하는걸 열심히

0개의 댓글