-
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 같은 정수 특화 명령어들이 사용됨
'개발' 카테고리의 다른 글
CSV Driver SELECT 요청 개선기 (4) 2024.08.05 내가 만든 was, Maven에 올렸지 (0) 2024.07.20 ServerSocket의 내부 동작 살펴보기: TCP 연결 설정의 로우레벨 이해 (0) 2024.07.08 Buffered I/O Steram vs I/O Stream: 커널 영역 접근과 성능 비교 (0) 2024.07.08 [LiveStreamingOnWebRTC] 스트리밍 서비스를 WebRTC로 구현해보기 (0) 2024.05.02