JVM - WORA

2025. 1. 28. 23:58JVM

JVM은 로고가 없다...

 


플랫폼 독립성

 

소프트웨어는 발전할수록 더 많은 환경에서 실행할 수 있는 유연성을 필요로 한다. 그러나 과거에는 운영체제(OS)나 하드웨어(CPU)에 따라 실행 방식이 달라지는 문제가 있었다. 이를 해결하기 위해 JVM(Java Virtual Machine)이 등장했다.

 

JVM이 무엇이며, 어떻게 자바 코드가 플랫폼 독립성을 가질 수 있는지 이해하기 위해, 먼저 기존의 실행 방식이 가졌던 한계를 살펴보자.

 


 

어셈블리어

특정 하드웨어에 종속된 실행 방식

 

          +------------------+  
          |  x86 CPU (Intel) |  
          +------------------+  
                   |  
    +------------------------+  
    |  x86 어셈블리 코드     (Intel 전용)  
    |  MOV AX, 5             |  
    |  ADD AX, BX            |  
    +------------------------+  
                   |
                (어셈블)
                   V  
  +----------------------------------+  
  |  실행 파일 (x86 기계어)        (Intel CPU 전용)
  |  OS: Windows                     |  
  +----------------------------------+  
                   |
            (CPU에서 직접 실행)
                     
-------------------------------------------------

          +------------------+  
          |  ARM CPU (Apple) |  
          +------------------+  
                   |  
    +------------------------+  
    |  ARM 어셈블리 코드    (Apple 전용)  
    |  MOV R0, #5            |  
    |  ADD R0, R1, R2        |  
    +------------------------+  
                   |  
                (어셈블)           
                   V  
  +----------------------------------+  
  |  실행 파일 (ARM 기계어)         (ARM CPU 전용)
  |  OS: macOS                       |  
  +----------------------------------+
                   |
           (CPU에서 직접 실행)

 

초창기 컴퓨터 프로그래밍에서는 어셈블리어를 사용했다.

어셈블리어는 기계어와 1:1로 대응하는 저수준 언어로, CPU 아키텍처마다 구분된 명령어 집합을 사용해야 했다.

 

따라서, 특정 CPU에서 실행할 프로그램을 작성하면, 다른 CPU에서는 사용할 수 없었다.

각 하드웨어마다 다른 어셈블리어를 작성해야 했고, 이는 개발의 비효율성을 초래했다.

 


 

C 언어

소스 코드의 독립성은 확보했지만, 실행 파일은 여전히 종속적

 

  +-----------------------------------+  
  |          C 소스 코드                |  
  |-----------------------------------|  
  |  int main() {                     |  
  |      printf("Hello, World!");     |  
  |      return 0;                    |  
  |  }                                |  
  +-----------------------------------+  
                                   |  
                             (컴파일 + 링킹)  
                                   |  
  +-------------------------+      |     +-------------------------+  
  | Windows 실행 파일       (EXE)    |     | macOS 실행 파일        (Mach-O)
  |-------------------------|<----OR---->|-------------------------|  
  |  (x86 Machine Code)     |            |  (ARM Machine Code)     |  
  +-------------------------+            +-------------------------+  
               |                                     |
     (실행하려면 OS가 일치해야 함)               (실행하려면 OS가 일치해야 함) 
               V                                     V
  +-------------------------+            +-------------------------+  
  | Windows OS (x86)        |            | macOS OS (ARM)          |  
  +-------------------------+            +-------------------------+

 

C 언어는 소스 코드를 어느 정도 플랫폼 독립적으로 작성할 수 있도록 했지만,

실행 파일은 여전히 특정 OS와 CPU 아키텍처에 맞춰 컴파일해야 했다.

 

즉, 소스 코드는 이식 가능하지만, 실행 파일은 플랫폼마다 다르게 생성해야 하는 문제가 남아 있었다.

예를 들어, 리눅스에서 만든 실행 파일은 윈도우에서 실행되지 않으며, 다시 컴파일해야 한다.

 


 

자바 

한 번의 컴파일로 여러 플랫폼에서 실행 가능

 

  +-----------------------------------------------+  
  |          Java 소스 코드                         |  
  |-----------------------------------------------|  
  |  public class Main {                          |  
  |      public static void main() {              |  
  |          System.out.println("Hello, World!"); |  
  |      }                                        |  
  |  }                                            |  
  +-----------------------------------------------+  
                |  
            (컴파일 Once) <- javac (자바 컴파일러)
                V  
  +---------------------------+  
  |  Java 바이트코드 (JVM용)     |  
  |---------------------------|  
  |  Main.class 파일           |  
  |  (플랫폼 독립적)             |  
  +---------------------------+  
                |  
          (실행 Anywhere)  
                V  
  +--------------------------+      +--------------------+      +--------------------+  
  |  JVM (Windows용)          |      |  JVM (macOS용)     |      |  JVM (Linux용)      |  
  |--------------------------|  OR  |--------------------|  OR  |--------------------|  
  |   바이트코드 실행 단계        |      |                    |      |                    |
  |--------------------------|      |                    |      |                    |
  |   1. 인터프리터 실행         |      |                    |      |                    |
  |   (한 줄씩 바이트코드 해석)   |      |        동일          |      |        동일         |
  |   - 초기 실행 빠름          |      |                    |      |                    |
  |   - 하지만 느림             |      |                    |      |                    |
  |--------------------------|      |                    |      |                    |
  |   2. JIT 컴파일 동작        |      |                    |      |                    |
  |   (반복 실행되는 코드 최적화)   |     |                    |      |                    |
  |   - 바이트코드 → 기계어 변환   |     |                     |      |                    |
  |   - 변환된 코드 캐싱         |      |                    |      |                    |
  |   - 이후 실행 속도 향상       |      |                    |      |                    |
  +--------------------------+      +--------------------+      +---------------------+  
                |                             |                              |
                V                             V                              V
  +--------------------------+      +--------------------+      +---------------------+  
  | Windows OS (x86)         |      | macOS OS (ARM)     |      | Linux OS (x86_64)   |  
  +--------------------------+      +--------------------+      +---------------------+

 

자바 컴파일러는 소스 코드를 특정 하드웨어나 OS에 맞춘 기계어로 변환하지 않고, 플랫폼 독립적인 바이트코드로 변환한다.

 

JVM은 각 운영체제에 맞게 구현되어 있으며, 바이트코드를 해석하여 해당 플랫폼에서 실행되도록 한다.

즉, 자바 프로그램은 운영체제나 하드웨어와 직접 맞물리지 않고, JVM이라는 추상화 계층 위에서 실행되기 때문에 플랫폼 독립성을 가질 수 있다.

 

이 개념은 자바의 대표적인 특징인 Write Once, Run Anywhere (WORA, 한 번 작성하면 어디서든 실행) 원칙을 가능하게 한다.

 


 

결론

 

어셈블리어

특정 CPU에 강하게 종속됨

 

C 언어

소스 코드는 독립적이나, 실행 파일은 플랫폼마다 다름

 

자바

바이트코드 + JVM으로 진정한 플랫폼 독립성 확보

 


마무리

 

어셈블리어와 C 언어의 약점을 통해서 자바의 강점을 확인할 수 있었다. 자바의 강점이 이뿐만이 아니지만, JVM을 통한 플랫폼 독립성은 자바가 널리 사용되는 중요한 이유 중 하나다.

 

이후에는 JVM의 구조를 알아볼 계획이다.

 

'JVM' 카테고리의 다른 글

JVM - 구조  (0) 2025.02.10