Java란? 자바의 특징

권광재·2024년 2월 22일

java

목록 보기
4/6

들어가기 전

처음 java를 이해하기 전에 운영체제라는 것에 대해서 이해를 할 필요성이 있다.
운영체제 란 Operating System으로 하드웨어를 관리하는 프로그램이다. 우리가 아는 운영체제로는 윈도우, 맥os, 우분투등이 있다.
즉, 컴퓨터를 보다 쉽게 사용할 수 있게 해주는 소프트웨어이다. 사실상 우리가 컴퓨터를 사용하려면 빼놓을 수 없는 부분이다.

1. 자바의 동작

자바에는 크게 3개로 나누어져 있다. JVM, JDK, JRE이다.

JDK: 자바 개발 도구(JVM용 소프트웨어 개발 도구)
JRE: 자바 실행 환경(JVM용 os)
JVM: 자바 가상 기계(가상의 컴퓨터)

여기서 가장 중요한 역할을 하는 것은 JVM이라고 볼 수 있다.

현실에서는 소프트웨어, 즉 프로그램은 개발자가 개발 도구를 이용해 개발하고 운영체제를 통해 물리적 컴퓨터인 하드웨어 상에서 구동된다,

자바 세계에서는 자바 개발 도구인 JDK를 이용해 개발된 프로그램을 JRE에 의해 가상 컴퓨터인 JVM상에서 구동된다.

배포를 진행할 때 편의를 위해 JDK가 JRE를 포함하고 다시 JRE는 JVM을 포함하는 형태로 배포된다.

이러한 관계를 알았다면 내가 작성한 코드는 어떻게 동작을 하는 것일까?? 그것을 알기 위해서는 javac.exe, java.exe에 대해서 알아야 한다.

1-1 javac.exe, java.exe


JDK는 자바 소스 컴파일러인 javac.exe를 포함하고 있고,
JRE는 실행기인 java.exe를 포함하고 있다.

javac.exe: 자바 컴파일러이다. 자바 소스 코드(.java 파일)를 바이트 코드(.class 파일)로 컴파일하는 데 사용된다. 이는 자바 개발자가 자신의 코드를 컴파일하여 실행 가능한 프로그램으로 변환할 수 있도록 도와준다.(컴파일러는 자바 개발 키트(Java Development Kit, JDK)에 포함)

java.exe: 자바 가상 머신(Java Virtual Machine, JVM)을 실행하는 데 사용한다. 컴파일된 자바 바이트 코드(.class 파일)를 해당 플랫폼에서 실행할 수 있는 기계 코드로 변환하고 실행한다. 이를 통해 자바 프로그램이 다양한 운영 체제와 하드웨어에서 실행될 수 있게 된다. 또한, java.exe를 통해 자바 애플리케이션을 실행할 수 있다.

이러한 과정을 통해서 자바 프로그램이 다양한 운영 체제와 하드웨어에서 실행될 수 있게 되는 것이다. 바로 자바의 장점인 이식성이 뛰어나다는 것이다.

1-2 JVM 아키텍쳐

ClassLoader(클래스로더): 자바 가상 머신(JVM)에서 클래스 파일을 메모리로 로드하는 역할을 수행
1. 로딩 (Loading): 로딩 단계에서는 클래스로더가 클래스 파일(.class)을 찾아서 메모리에 로드
2. 링킹 (Linking): 링킹은 로딩 단계 후에 이루어지며 메모리에 로드된 클래스의 정적 변수들에 대한 메모리 공간을 할당, 클래스가 다른 클래스나 인터페이스를 참조하는 경우, 이러한 참조들을 실제 참조로 변경(클래스 A가 클래스 B를 상속하거나 인터페이스 C를 구현하는 경우, 클래스로더는 실제로 클래스 B와 인터페이스 C를 로드하고 이를 참조로 변경)
3. 초기화 (Initialization): 초기화 단계에서는 클래스의 정적 변수들을 초기화하고 정적 초기화 블록을 실행한다.

Runtime Data Area(런타임 데이터 영역, 메모리 영역): JVM이 프로그램을 실행하는 동안 데이터를 저장하는 메모리 영역

메서드 영역(Method Area): 클래스에 대한 메타데이터(클래스의 구조, 필드, 메서드 등)를 저장하는 공유 메모리 영역
힙 영역(Heap Area): 객체 인스턴스와 배열 등이 저장되는 공간으로, 가비지 컬렉션의 대상이 되는 영역
스택 영역(Stack Area): 각 스레드마다 생성되는 공간으로, 메서드 호출 시 지역 변수, 매개변수, 메서드 호출 정보 등을 저장
PC 레지스터(Program Counter Register): 스레드가 실행 중인 명령의 주소를 저장하는 공간
네이티브 메서드 스택(Native Method Stack): 네이티브 코드(C, C++ 등)를 실행하는데 사용되는 공간

Execution Engine(실행 엔진): 실행 엔진은 JVM의 핵심 부분으로서, 컴파일된 바이트 코드를 실행하는 역할을 담당
인터프리터(Interpreter): 바이트 코드를 한 줄씩 읽어 해당하는 기계어를 실행합니다. 이 방식은 실행 속도가 느릴 수 있지만, 빠른 시작과 적은 메모리 사용량을 보장
JIT 컴파일러(Just-In-Time Compiler): 인터프리터가 반복되는 코드 블록을 발견하면 해당 코드 블록을 기계어로 컴파일하여 캐시에 저장합니다. 이를 통해 반복되는 코드의 실행 속도를 향상
가비지 컬렉터(Garbage Collector): 실행 중인 프로그램에서 더 이상 필요하지 않은 객체를 찾아내고 해당 메모리를 회수하여 재사용 가능한 메모리로 반환하는 작업을 담당

2 알아야할 것(단점)

자바의 장점이라고 한다면 자바의 JVM이 많은 것을 담당해주어 우리의 개발을 편하게 해준다는 것이다. 하지만 이것은 장점이자 단점이다.

단점이라 하면 대표적으로 뽑히는 것이 성능 이슈,메모리 사용량, JVM에 대한 과도한 의존이다.

JVM은 인터프리터 및 JIT 컴파일러를 통해 바이트 코드를 실행하며, 이 과정에서 추가적인 오버헤드가 발생할 수 있다. (이것에 대한 기준도 참 재미있는데 다음에 설명해보도록 하겠다! 찾아보는 것도 추천한다. -> 메모리에 많은 관련이 있다)

JVM은 메모리를 효율적으로 관리하려고 노력하지만, 가비지 컬렉션과 같은 메모리 관리 작업으로 인해 추가적인 메모리 사용량이 발생할 수 있다.

그렇다면 이 단점으로 알아야할 여러가지가 있지만 하나만 설명해보겠다.

가비지 컬렉터(GC)에서 객체가 사용되지 않는다고 간주되는 경우는 무엇이 있을까??

Reachability(도달 가능성)을 잃은 객체, Strong Reference Cycle(강한 참조 순환)이 있다.

도달 가능성을 잃은 객체는 프로그램이 실행되는 동안 특정 객체에 접근할 수 없게 되면, 그 객체는 더 이상 사용되지 않는 것으로 간주되는 것이다.
강한 참조 순환은 두 개 이상의 객체가 서로를 강한 참조하는 경우 강한 참조 순환이 발생해 이 경우에는 두 객체 모두 도달 가능성을 잃지 않으므로 가비지 컬렉터가 이를 회수하지 못한다.

예시

Employee employee = new Employee();
employee = null; // 도달 가능성을 잃음

Employee employee1 = new Employee(); //object 1
Employee employee2 = new Employee(); //object 2
employee1 = employee2; //강한 참조로 인해 회수가 불가능하다. 

이러한 특징을 잘 파악하고 자바를 다가가면 더 세밀한 작업이 가능할 것이라고 생각한다.

profile
안녕하세요

0개의 댓글