요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

모든 프로그램에는 시작과 끝이 있습니다. 개발자가 코드를 작성하고 실행하면 JVM에서 프로그램이 실행된 후 종료됩니다. 이때, JVM 상에서 어떤 식으로 동작하며 개발자가 작성한 코드는 어떤 식으로 돌아가고 메모리는 어떻게 구성되어 있기에 객체지향언어라고 말하는지에 대해 설명하려고 합니다. 오늘은 간단한 이론을 먼저 알아보고 다음 편에서 더 자세한 자바(Java) 지식에 대해 설명하겠습니다.

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

초보 Spring(Java) 개발자를 위한 완전 기초 지식(이론편)

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

모든 프로그램에는 시작과 끝이 있습니다. 개발자가 코드를 작성하고 실행하면 JVM에서 프로그램이 실행된 후 종료됩니다. 이때, JVM 상에서 어떤 식으로 동작하며 개발자가 작성한 코드는 어떤 식으로 돌아가고 메모리는 어떻게 구성되어 있기에 객체지향언어라고 말하는지에 대해 설명하려고 합니다. 오늘은 간단한 이론을 먼저 알아보고 다음 편에서 더 자세한 자바(Java) 지식에 대해 설명하겠습니다.

 

1. 자바의 기초 상식

1) 자바 기초 상식

자바 JVM(Java Virtual Machine)은 자바로 작성된 프로그램을 실행하는 데 사용되는 가상 머신입니다. JVM은 자바 어플리케이션을 바이트코드로 변환하고, 이 바이트코드를 OS(운영체제)에 상관없이 실행할 수 있게 합니다. 이렇게 함으로써 자바는 플랫폼 독립적인 특성을 가집니다.

 

자바(Java)
출처: 작가

 

장점

  • 플랫폼 독립적: 자바 어플리케이션은 한 번 작성하면 어떤 플랫폼에서든 실행될 수 있습니다. 이는 JVM이 여러 OS에서 구현될 수 있기 때문입니다. 타 언어의 경우 언어에 맞는 환경에 따라 빌드를 다르게 해야 하지만 자바는 jar, war 파일을 OS에 상관없이 JVM 위에서 동작할 수 있습니다.
  • 메모리 관리: JVM은 가비지 컬렉션(GC)을 통해 메모리 관리를 수행하기에 개발자가 메모리를 직접 관리할 필요가 없습니다.
  • 보안: JVM은 클래스 로더와 바이트코드 검증을 통해 안전한 실행 환경을 제공합니다. 이를 통해 악성코드로부터 시스템을 보호할 수 있습니다.

 

단점

  • 느린 실행 속도: JVM을 사용하면 추가적인 오버헤드가 발생하여 네이티브 코드에 비해 상대적으로 느린 실행 속도를 보입니다.
  • 더 많은 메모리 소비: JVM이 가비지 컬렉션과 같은 메모리 관리 기능을 수행하면서 더 많은 메모리를 사용할 수 있습니다.
  • 추가적 시간 소요: JVM을 시작하고 클래스를 로드하는 과정에서 추가적인 시간이 소요됩니다.

 

2) JDK, JRE, JVM

자바(Java)
출처: 작가

 

  • JDK(Java Development Kit): JDK는 자바 언어를 사용하여 프로그램을 개발하기 위한 도구 모음입니다. JDK는 JRE와 JVM을 포함하며, 컴파일러 (javac), 디버거, 자바 라이브러리, 문서 생성 도구 (javadoc) 등을 포함합니다. 개발자는 JDK를 사용하여 자바 프로그램 작성, 컴파일, 테스트 및 디버깅할 수 있습니다.
  • JRE(Java Runtime Environment): JRE는 자바 프로그램을 실행하기 위한 환경을 제공합니다.JRE는 JVM과 자바 클래스 라이브러리로 구성되어 있으며, 사용자는 JRE를 통해 자바 애플리케이션을 실행할 수 있습니다. JRE는 개발 과정이 아닌 자바 프로그램 실행을 위한 환경을 제공하기 때문에 개발 도구는 포함하지 않습니다.
  • JVM(Java Virtual Machine): JVM은 자바 프로그램의 실행을 담당하는 가상 머신입니다. 가상 머신은 자바 코드 컴파일 후 생성된 바이트코드를 기계어로 변환하여 실행하고 이 자바코드가 여러 플랫폼에서 동일하게 작동할 수 있는 중립적인 환경을 제공합니다. 즉, 자바로 작성된 프로그램은 JVM이 설치된 모든 운영 체제에서 실행 가능합니다.

 

3) JAR, WAR, EAR

자바(Java)
출처: 스택오버플로우

 

  •  JAR(Java Application Resource or Java Application Archive)

JAR 파일은 자바 애플리케이션과 관련된 클래스 파일, 메타데이터, 리소스 파일 등을 하나의 압축 파일로 묶은 것입니다. 이 파일은 자바 애플리케이션을 쉽게 배포하고 설치할 수 있도록 하는 데 도움이 됩니다. 또한, JAR 파일은 자바 라이브러리를 포함할 수 있어, 재사용 가능한 코드 모듈을 효율적으로 관리할 수 있습니다. 즉 개발자가 개발하기 위해 필요한 기능을 압축한 것을 JAR이라고 합니다.

 

  •  WAR(Web Application Resource or Web Application Archive)

WAR 파일은 웹 애플리케이션과 관련된 파일들을 하나의 압축 파일로 묶은 것입니다. JSP, 서블릿(Servlet), 클래스 파일, XML 설정 파일, 웹 리소스 (HTML, CSS, 자바스크립트, 이미지 등) 등 웹 애플리케이션 구성 요소를 포함합니다. WAR 파일은 웹이나 애플리케이션서버에 배포할 수 있으며, 이를 통해 웹 애플리케이션을 쉽게 설치하고 관리할 수 있습니다. JAR은 웹으로 실행이 불가능하지만, WAR로 묶었을 때는 사용이 가능합니다.

 

  •  EAR(Enterprise Application Resource or Enterprise Application Archive)

EAR 파일은 자바 기반의 엔터프라이즈 애플리케이션을 패키징 하는 데 사용되는 파일 형식입니다. EAR 파일은 웹 애플리케이션 (WAR 파일), EJB(Enterprise Java Bean) 모듈, 자바 어플리케이션 (JAR 파일) 및 관련 리소스를 포함하며, 이들은 각각 서로 다른 계층의 구성 요소를 나타냅니다. EAR 파일을 사용하면 여러 모듈과 리소스가 포함된 대규모 엔터프라이즈 애플리케이션을 하나의 파일로 통합하여 배포하고 관리할 수 있습니다. 주로 자바 EE 애플리케이션 서버에서 사용되며, 서버 관리자는 EAR 파일을 통해 애플리케이션의 배포와 관리를 손쉽게 수행할 수 있습니다.

 

요약하면, JAR, WAR, EAR 파일은 각각 자바, 웹, 엔터프라이즈 형식의 애플리케이션을 패키징하고 배포하는 데 사용되는 파일 형식입니다. 이러한 파일 형식을 사용하면 애플리케이션의 구성 요소와 리소스를 효율적으로 관리하고  배포 및 설치를 간소화할 수 있습니다.

 

 

2. 자바 라이프사이클

프로그램이 실행되어 종료되기까지의 과정을 라이프 사이클이라고 합니다. 자바 실행 과정은 소스코드 작성, 컴파일, 클래스 로딩, 바이트코드 검증, Just-In-Time, 실행, 메모리 관리, 종료로 총 8단계로 나눌 수 있습니다. 각각의 단계에서 어떠한 동작이 발생하는지에 대해 설명하려고 합니다.

 

1) 소스코드 작성

개발자는 텍스트 에디터를 사용하여 자바 소스 코드를 작성합니다. 자바 소스 코드는 .java 확장자를 가지고 있습니다. 이렇게 작성된 소스코드는 컴파일 과정을 거쳐 .class 로 변환됩니다. 소스코드를 작성할 때는 자바 언어의 표준 라이브러리(Java Standard Library)를 활용하거나 사용자 정의 라이브러리를 사용하여 재사용성을 높일 수 있습니다.

 

2) 컴파일

소스코드의 구문 및 의미를 분석하여 바이트 코드로 변환합니다 쉽게 풀어서 설명하면 .java 형태로 개발된 코드를 .class 파일로 바꿔주는 작업을 합니다. 이 과정에서 자바 컴파일러의 문법 분석기는 자바 코드의 구문을 검사하고, 올바르게 작성되어 있는지를 검증합니다. 또한 자바 소스 코드가 다른 클래스나 라이브러리를 사용할 경우, 이를 참조할 수 있도록 해당 클래스나 라이브러리를 검색합니다. 이때, 사용되는 것이 클래스패스(Classpath)입니다. 클래스 패스는 컴파일러가 참조할 클래스나 라이브러리 위치를 지정해 주는 역할을 합니다.

 

3) 클래스 로딩

자바(Java)

 

클래스 로더는 JVM의 일부로, .class 파일을 메모리에 로드하는 역할을 합니다. 개발자가 클래스 로더의 역할에 대해 알게 된다면, 자바와 스프링의 구조에 대해 디테일하게 알 수 있습니다. 클래스 로더는 클래스를 로드한 후, 링크하고 초기화합니다. 링크는 클래스나 인터페이스의 레퍼런스를 해결하고, 필드와 메소드를 준비하는 과정을 의미하며, 초기화는 스태틱(static) 블록을 실행하고, 스태틱 변수를 초기화하는 과정을 의미합니다. 클래스 로더는 로드되는 클래스의 종류에 따라서 우선순위를 다르게 부여하고 부트스트랩 클래스 로더, 확장 클래스 로더, 시스템 클래스 로더로 JVM에 내장되어 있으며, 사용자 정의 클래스 로더로 구분할 수 있습니다.

 

부트스트랩 클래스 로더: JVM을 시작할 때, 자바 가상 머신은 부트스트랩 클래스 로더를 이용하여 기본적으로 제공되는 자바 클래스들을 로드합니다. 대표적으로 JVM의 핵심 라이브러리인 rt.jar가 있습니다. 부트스트랩 클래스 로더는 JDK(자바 개발 도구)에 내장되어 있으며, 가장 먼저 클래스를 로드하는 역할을 담당합니다.

 

확장 클래스 로더: 확장 클래스 로더는 표준 클래스 로더와 시스템 클래스 로더의 중간 단계에 해당합니다. 이 로더는 플랫폼별로 클래스를 로드합니다. 예를 들어, JDK가 설치된 경로에 있는 클래스들을 로드합니다.

 

시스템 클래스 로더: 시스템 클래스 로더는 애플리케이션 클래스들을 로드합니다. 애플리케이션 클래스는 앱개발자가 작성한 클래스들을 포함합니다. 시스템 클래스 로더는 확장 클래스 로더의 하위 단계에 해당하며, 클래스 패스에 지정된 경로에 있는 클래스들을 로드합니다. 이때, 시스템 클래스 로더는 애플리케이션 클래스 패스에 있는 클래스 파일을 검색하고 없을 시 에러를 발생시킵니다.

 

추가로 라이브러리의 jar 파일은 시스템 클래스 로더와 확장 클래스 로더 그리고 사용자 정의 클래스 로더 중 하나에 의해 로드되지만 일반적으로, 시스템 또는 확장 클래스 로더에 의해 로드됩니다. 이때, 시스템 클래스 로더는 JRE(자바 라이브러리, 자바 가상머신의 모둠)의 라이브러리 디렉터리(lib/)와 애플리케이션 클래스패스를 검색하며, 확장 클래스 로더는 JRE의 확장 디렉토리(ext/)를 검색합니다.

 

부트스트랩 클래스 로더: 부트스트랩 클래스 로더는 JVM의 핵심 라이브러리인 rt.jar 등의 클래스를 로드하는 역할을 합니다. 자바 에이전트가 부트스트랩 클래스 로더에 접근하려면, 자바 가상 머신에 '-Xbootclasspath/a:' 옵션을 사용하여 클래스 경로를 추가해야 합니다.

 

4) 바이트코드 검증

클래스 로더는 바이트 코드를 로딩한 후, JVM(자바 가상 머신) 내부에서 바이트 코드의 유효성을 검사합니다. 이 과정에서 JVM은 스택을 검사하고, 사용되지 않는 로컬 변수를 제거하는 등의 작업을 수행합니다. 유효하지 않은 바이트 코드는 JVM에서 실행되지 않으며, 실행 중 예기치 못한 오류가 발생할 수 있습니다.

 

바이트 코드 검증은 JVM의 안전성과 보안성을 보장하기 위한 과정입니다. 이 과정에서 바이트 코드의 구문 및 의미를 분석하고, 유효성을 검증합니다. 예를 들어, 메소드 호출이 올바르게 수행되었는지, 바이트 코드 내부에 선언된 변수가 유효한지 등을 검사합니다. 이 검사에서 유효하지 않은 바이트 코드가 발견되면, JVM은 이를 실행하지 않습니다. 이를 통해 JVM은 자바 프로그램의 실행 중에 예기치 않은 오류를 방지하고, 안정성을 높이는 역할을 합니다.

 

5) Just-In-Time

JVM은 자바 바이트 코드(Java Bytecode)를 실행하는데, 일반적으로는 인터프리터 방식으로 동작한다. 인터프리터 방식은 바이트 코드를 한 줄씩 읽어들이면서 실행하는 방식으로, 실행 속도가 느리다는 단점이 있다.

 

이를 해결하기 위해  Just-In-Time 컴파일러(JIT compiler)를 도입하여 이러한 속도 저하를 보완했다. Just-In-Time 컴파일러는 인터프리터 방식으로 바이트 코드를 실행할 때, 실행 속도가 느린 부분을 파악하여 해당 부분을 네이티브 코드(native code)로 변환하고, 이후에는 인터프리터 대신에 네이티브 코드를 직접 실행하는 방식으로 동작한다.

 

이 방식을 통해, 자바 애플리케이션의 실행 속도를 대폭 향상시킬 수 있다. 또한 JIT 컴파일러는 애플리케이션의 실행 패턴을 분석하여 최적화된 코드를 생성하므로, 애플리케이션의 실행 속도를 최적화할 수 있다.

 

JIT(Just-In-Time)  컴파일러는 크게 두 가지 방식으로 동작합니다.

 

첫째, 인터프리터 모드로 동작하면서, 런타임에 실행되는 바이트 코드를 추적하여 해당 코드를 네이티브 코드로 컴파일합니다.

둘째, AOT(Ahead-of-Time) 모드로 동작하면서, 프로그램이 시작될 때 모든 코드를 네이티브 코드로 변환하여 미리 컴파일합니다. 이렇게 미리 컴파일된 코드는 프로그램이 실행되는 동안 인터프리터 모드에서 실행됩니다.

 

6) 실행

 기나긴 과정을 거쳐 이제 개발자가 작성한 코드가 실행됩니다. 위 과정을 통해 변환된 기계어 코드는 JVM에서 실행됩니다. 이때, JVM은 자바 스레드(Thread)를 생성하여 여러 작업을 동시에 처리할 수 있으며,  스레드는 동기화된 코드를 실행하거나, I/O(입력/출력) 작업을 수행할 때 유용합니다. JVM은 자바 언어에서 제공하는 가비지 컬렉터(Garbage Collector)를 사용하여 메모리 누수를 방지합니다.

 

7) 메모리관리

JVM은 자바 프로그램에서 사용하는 메모리를 관리합니다. 이 과정에서 JVM은 메모리 할당, 해제, 가비지 컬렉션 등을 수행하여 자원의 효율성을 높이고, 메모리 누수 등의 문제를 방지합니다. JVM은 메모리를 스택(Stack)과 힙(Heap)으로 구분하여 관리하며 스택은 지역 변수와 메소드 호출을 위한 힙은 객체와 배열 등을 위한 메모리를 할당합니다. 자바의 메모리는 T메모리로 설명할 수 있으며, 해당 설명은 다음 편에서 추가적으로 설명할 예정입니다.

 

8) 종료

자바 프로그램이 실행을 마치면, JVM은 프로그램에서 사용한 자원을 해제하고 종료됩니다. 이때, 사용한 자원에는 파일, 네트워크 연결, 데이터베이스 커넥션 등이 포함됩니다. 또한, JVM은 일정 시간 동안 사용되지 않는 객체를 메모리에서 해제하며, 이를 가비지 컬렉션이 수행합니다.

 

이번 편에선 스프링 입문자를 위한 기초적인 이론 지식에 대해 살펴봤습니다. 다음 편에서는 실무 지식에 대해 이야기해보겠습니다. 

 

sh
편집 정선아 객원 에디터

 

요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.

좋아요

댓글

공유

공유

댓글 0
작가
9
명 알림 받는 중

작가 홈

작가
9
명 알림 받는 중
서울에서 개발자를 하고 있습니다.
Java APM 솔루션 개발 경험이 있으며, 현재 SI 개발을 하고 있습니다.
네트워크와 서버, 자동화등 다양한 것들에 관심이 많은 개발자 입니다.

좋아요

댓글

스크랩

공유

공유

요즘IT가 PICK한 뉴스레터를 매주 목요일에 만나보세요

요즘IT가 PICK한 뉴스레터를
매주 목요일에 만나보세요

뉴스레터를 구독하려면 동의가 필요합니다.
https://auth.wishket.com/login