부트캠프

Java - Thread, JVM

hunm719 2023. 1. 10. 16:54

어떤 애플리케이션이 실행되면 운영체제가 해당 애플리케이션에게 메모리를 할당해주며 애플리케이션이 실행되는데, 이처럼 실행 중인 애플리케이션을 프로세스라고 함. 프로세스 내에서 실행되는 소스 코드의 실행 흐름을 스레드라고 하며, 단 하나의 스레드를 가지는 프로세스를 싱글 스레드 프로세스, 여러 개의 스레드를 가지는 프로세스를 멀티 스레드 프로세스라고 함.

즉, 프로세스는 실행 중인 애플리케이션을, 스레드는 하나의 코드 실행 흐름을 의미함

1.메인 스레드(Main Thread)
-자바 애플리케이션을 실행하면 가장 먼저 실행되는 메서드는 main 메서드이며, 메인 스레드가 main 메서드를 실행시킴
-메인 스레드는 main 메서드의 코드를 처음부터 끝까지 순차적으로 실행시키며, 코드의 끝을 만나거나 return문을 만나면 실행을 종료함


2.멀티 스레드(Multi-Thread)
-하나의 프로세스는 여러 개의 스레드를 가질 수 있는데, 이는 여러 스레드가 동시에 작업을 수행할 수 있음을 의미하며, 이를 멀티 스레딩이라함.
-하나의 애플리케이션 내에서 여러 작업을 동시에 수행하는 멀티 태스킹을 구현하는 데에 핵심적인 역할을 수행

+위의 정보를 종합해보면 싱글 스레드 프로세스는 메인 스레드 하나만을 가질 것이고, 멀티 스레드 프로세스는 하나의 메인 스레드와 여러 개의 작업스레드로 구성되어 있음.


3.작업 스레드
-메인 스레드 외에 별도의 작업 스레드를 활용한다는 것은 작업 스레드가 수행할 코드를 작성하고, 작업 스레드를 생성하여 실행시키는 것을 의미함
-하지만 자바는 객체지향 언어이므로 모든 자바 코드는 클래스 안에 작성되기 때문에 스레드가 수행할 코드도 클래스 내부에 작성함

3-1.작업 스레드 생성
-자바에서는 run()이라는 메서드 내에 스레드가 처리할 작업을 작성하도록 규정되었고 run() 메서드는 Runnable 인터페이스와 Thread 클래스에 정의되어져 있음

 (1)Runnable 인터페이스를 구현한 객체에서 run()을 구현하여 스레드를 생성하고 실행하는 방법
 (2)Thread 클래스를 상속 받은 하위 클래스에서 run()을 구현하여 스레드를 생성하고 실행하는 방법
 (3)익명 객체를 사용해 스레드를 생성

3-2.스레드의 이름
-메인스레드는 “main”이라는 이름을 가지며, 그 외 추가적으로 생성한 스레드는 기본적으로 “Thread-n”이라는 이름을 가짐

 (1)스레드 이름 조회 : 스레드의_참조값.getName()
 (2)스레드 이름 설정 : 스레드의_참조값.setName()
 (3)스레드 인스턴스 주소값 : Thread.currentThread()

3-3.스레드의 동기화
-멀티 스레드 프로세스의 경우, 두 스레드가 동일한 데이터를 공유하게 되어 문제가 발생할 수 있음
-이러한 상황이 발생하지 않도록 조치하는 것이 스레드 동기화이고, 먼저 임계영역과 락에 대한 이해가 필요함

 (1)임계 영역(Critical section) : 오로지 하나의 스레드만 코드를 실행할 수 있는 코드 영역
 (2)락(Lock) : 임계 영역을 포함하고 있는 객체에 접근할 수 있는 권한

-임계 영역을 설정하여 해당 영역 내에서는 두 스레드가 동시에 실행되지 못 하도록 하고, 해당 객체에 대한 락을 가진 스레드만이 코드를 실행할 수 있도록 하는 것
-락을 가진 스레드가 임계 영역 내의 코드를 모두 실행하면 락을 반납하고 이 때부터는 다른 스레드들 중 하나가 락을 획득하여 임계 영역 내의 코드를 실행하도록 할 수 있음

 (3)임계 영역 설정 방법 : synchronized 키워드
  -메서드 전체를 임계 영역으로 지정할 경우, 메서드 반환 타입 좌측에 synchronized 키워드 작성
  -특정한 영역을 임계 영역으로 지정할 경우, synchronized 키워드와 함께 소괄호(()) 안에 해당 영역이 포함된 객체의 참조를 넣고, 중괄호({})로 블럭을 열어, 블럭 내에 코드를 작성


4.자바 가상 머신(Java Virtual Machine)
-JVM(Java Virtual Machine)은 자바 프로그램을 실행시키는 도구로, 자바로 작성한 소스 코드를 해석해 실행하는 별도의 프로그램임
-프로그램이 실행되기 위해선 프로그램이 컴퓨터 자원을 할당받아야 하는데, 운영체제마다 필요한 컴퓨터 자원을 요청하는 방식이 달랐기에 기존엔 프로그래밍 언어가 운영체제에 대해 종속성을 가졌음.
-하지만 자바는 JVM을 매개해서 운영체제와 소통하고, JVM은 각 운영체제에 적합한 버전이 존재하기 때문에 자바는 운영체제로부터 독립적임


4-1.JVM 구조

JVM의 구조

 (1)자바로 소스 코드를 작성하고 실행하면, 먼저 컴파일러가 실행되면서 컴파일이 진행
 (2)컴파일의 결과로 .java 확장자를 가졌던 자바 소스 코드가 .class 확장자를 가진 바이트 코드 파일로 변환
 (3)JVM은 런타임 데이터 영역(Rumtime Data Area)에서 운영 체제로부터 소스 코드 실행에 필요한 메모리를 할당
 (4)클래스 로더(Class Loader)가 바이트 코드 파일을 JVM 내부로 불러들여 런타임 데이터 영역에 적재(=소스 코드를 메모리에 로드)
 (5)로드가 완료되면 실행 엔진(Execution Engine)이 런타임 데이터 영역에 적재된 바이트 코드를 실행
  *실행 엔진이 바이트 코드를 실행시킬때 아래의 두 가지 방식이 있음.
  **인터프리터(Interpreter)를 통해 코드를 한 줄씩 기계어로 번역하고 실행
  ***JIT Compiler(Just-In-Time Compiler)를 통해 바이트 코드 전체를 기계어로 번역하고 실행
  +기본적으로 인터프리터를 통해 바이트 코드를 실행시키다가, 특정 바이트 코드가 자주 실행되면 해당 코드를 JIT Compiler를 통해 실행시킴


4-2.Stack과 Heap

런타임 데이터 영역의 내부

-JVM구조 (3)에서 언급한 런타임 데이터 영역은 특정 값, 바이트코드, 객체, 변수등과 같은 데이터를 담는 메모리 영역
-위의 사진과 같이 크게 5가지 영역으로 구분되어 있는데, 그 중 Stack과 Heap을 먼저 살펴보겠음

 (1)Stack : 프로그램이 데이터를 저장하는 방식(자료구조)의 일종으로, LIFO(Last In First Out)이 핵심
  -메서드가 호출되면 그 메서드를 위한 공간인 Method Frame이 생성되는데, 메서드 내부에서 사용하는 다양한 값들이 임시로 저장됨
  -이런 Method Frame이 Stack에 호출되는 순서대로 쌓이게 되는데, Method의 동작이 완료되면 역순으로 제거됨

 (2)Heap : JVM이 작동되면 자동으로 생성되며 JVM내에 단 하나만 존재하는 영역으로, 객체나 인스턴스 변수, 배열이 저장됨
  -new연산자를 통해 인스턴스를 생성하는 코드를 짰을 때, 해당 코드가 실행되면 Heap 영역에 인스턴스가 생성됨
  -Heap 영역의 인스턴스에 실제 객체의 값이 저장되고, 우리가 객체를 다룬다는 것은 Stack 영역에 저장되어 있는 참조 변수를 통해 Heap 영역에 존재하는 객체를 다룬다는 의미


4-3.가비지 컬렉션(Garbage Collection) : 프로그램에서 더 이상 사용하지 않는 객체를 찾아 삭제하거나 제거하여 메모리를 확보하는 프로세스
-아무한테도 참조되고 있지 않은 객체 및 변수들을 검색하여 메모리에서 점유를 해제하며, 메모리 공간을 확보함
-JVM의 Heap영역은 객체가 얼마나 살아있냐에 따라 Heap 영역 안에서 Young영역 Old영역으로 나뉨

 (1)Young 영역 : 새롭게 생성된 객체가 할당되는 곳으로 이 영역에서 활동하는 가비지 컬렉터를 Minor GC라고 함
 (2)Old 영역 : Young영역에서 상태를 유지하고 살아남은 객체들이 복사되는 곳으로 이 영역에서 활동하는 가비지 컬렉터를 Major GC라고 함
  *Young 영역과 Old 영역은 서로 다른 메모리 구조로 되어 있기 때문에, 세부적인 동작 방식은 다르지만, Stop The World를 통해 모든 작업이 중단되면, 가비지 컬렉션이 모든 변수와 객체를 탐색해서 각각 어떤 객체를 참고하고 있는지 확인하고 사용되고 있는 메모리를 식별해서(Mark) 사용되지 않는 메모리는 제거(Sweep)하는 과정을 진행

 

 

 

이미지 및 내용 출처 - code states

'부트캠프' 카테고리의 다른 글

자료구조/알고리즘 - JSON  (0) 2023.01.13
자료구조/알고리즘 - 재귀 함수  (0) 2023.01.12
Java - 파일 입출력(I/O)  (0) 2023.01.09
Java - Annotation, Lambda, Stream  (0) 2023.01.06
Java 컬렉션 프레임워크  (1) 2023.01.04