ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 프로그램 바이트 코드를 분석해보자
    개발 2024. 7. 10. 21:13

    오늘 배운 JVM의 동작을 간단히 이해해 보고자 Java 프로그램을 간단히 작성해 바이트 코드를 분석해보았다.

    코드

    먼저 다음은 작성한 코드다.

    public class SimpleProgram {
        public static void main(String[] args) {
            int a = 5;
            int b = 3;
            int result = add(a, b);
            System.out.println("Result: " + result);
        }
    
        public static int add(int x, int y) {
            return x + y;
        }
    }

    바이트 코드

    다음은

    javac SimpleProgram.java | javap -c SimpleProgram

    을 실행한 결과다.

    Compiled from "SimpleProgram.java"
    public class SimpleProgram {
      public SimpleProgram();
        descriptor: ()V
        flags: (0x0001) ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 1: 0
    
      public static void main(java.lang.String[]);
        descriptor: ([Ljava/lang/String;)V
        flags: (0x0009) ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=4, args_size=1
             0: iconst_5
             1: istore_1
             2: iconst_3
             3: istore_2
             4: iload_1
             5: iload_2
             6: invokestatic  #7                  // Method add:(II)I
             9: istore_3
            10: getstatic     #13                 // Field java/lang/System.out:Ljava/io/PrintStream;
            13: iload_3
            14: invokedynamic #19,  0             // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String;
            19: invokevirtual #23                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            22: return
          LineNumberTable:
            line 3: 0
            line 4: 2
            line 5: 4
            line 6: 10
            line 7: 22
    
      public static int add(int, int);
        descriptor: (II)I
        flags: (0x0009) ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=2, args_size=2
             0: iload_0
             1: iload_1
             2: iadd
             3: ireturn
          LineNumberTable:
            line 10: 0
    }

    분석

    main 메소드 안 코드를 한 줄씩 분석해보았다.

     

    0: iconst_5
    : 상수 5를 스택에 푸시


    1: istore_1
    : 스택의 값을 1번째 지역변수에 저장


    2: iconst_3
    : 상수 3을 스택에 푸시


    3: istore_2
    : 스택의 값을 2번째 지역변수에 저장


    4: iload_1
    5: iload_2
    : 1, 2번째 지역변수를 스택에 저장


    6: invokestatic #7 // Method add:(II)I
    : add 메소드 실행 하면서 새로운 스택 프레임 생성 및 매개변수 pop 후 새로운 스택 프레임에 복사


    0: iload_0
    1: iload_1
    : 1, 2번째 지역번수를 스택에 저장


    2: iadd
    : 스택의 2개 값을 더함


    3: ireturn
    : 정수 결과값 반환


    9: istore_3
    : 반환된 값을 3번째 지역변수에 저장


    10: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream;
    : System.out 객체를 스택에 푸시


    13: iload_3
    : 3번째 지역변수를 스택에 푸시


    14: invokedynamic #19, 0 // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String;
    : #0 부트스트랩 메서드를 실행 문자열을 합치고 스택에 저장


    19: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    : 스택에서 값을 받아 println 실행


    22: return
    : 프로그램 종료

    주요 특징

    • 메소드와 문자열 참조는 상수 풀을 이용함
    • JVM은 스택 기반으로 연산을 진행함
    • 지역 변수는 인덱스로 접근
    • invokestatic, invokedynamic, invokevirtual 을 이용해 메서드를 실행함
    • iconst_, iadd 같은 정수 특화 명령어들이 사용됨

    댓글

Designed by Tistory.