새소식

Spring & Java/Java

5. JVM

  • -

JVM < JRE < JDK

JDK : 자바 개발 키트의 줄임말로 JRE에 컴파일러, 디버거 등 개발 도구를 포함하는 프로그램

 

JRE : 자바 실행 환경의 줄임말로 JVM에 자바 라이브러리와 기타 파일들이 결합된 자바를 실행하기 위한 프로그램.

 

JVM : 자바 가상 머신으로 애플리케이션을 클래스 로더를 통해 읽어 들여 API와 함께 실행

 

 

JVM 구성

(class Loader)

1.  java 파일을 Java 컴파일러가 컴파일하면 .class 파일인 바이트 코드가 생성

2. 클래스 파일들을 엮어서 JVM이 운영체제로부터 할당받은 메모리 영역인 Runtime Data Area에 적재하는 역할을 한다.

 

(execution engine)

 1. 클래스 로더에 의해 메모리에 적재된 클래스(바이트 코드)들을 기계어로 변경해 명령어 단위로 실행하는 역할을 함.

 

(gabage Collector)

1. Heap 메모리 영역에 생성된 객체들 중에 참조되지 않는 객체들을 탐색 후 제거하는 역할을 함. – 메모리를 자동으로 수거하는 것

2. GC가 수행되는 동안 GC를 수행하는 쓰레드가 아닌 다른 모든 쓰레드가 일시 정지된다.

3. 특히 Full GC가 일어나서 수 초간 모든 쓰레드가 정지한다면 장애로 이어지는 치명적인 문제가 생길 수 있다.

 

(runtime data area)

·  개별 스레드에서 관리

  • PC Register : 쓰레드가 실행되는 부분의 주소와 명령을 저장하는 영역
  • JVM Stack : 지역 변수, 파라미터, 리턴 , 연산에 사용되는 임시 값이 생성되는 영역
  • Native Method Stack : 자바 언어로 작성된 네이티브 코드를 위한 메모리 영역(C/C++ 코드)

·  공유 스레드에서 관리

  • Method Area : 클래스 멤버 변수의 이름, 데이터 타입, final 클래스 변수
  • Heap Area : new 키워드로 생성된 객체와 배열이 생성되는 영역, ( jdk 8 이상 : static 변수, string 상수 )

 

자바에서는 크게 영역으로 2가지로 나누는데, Young Old 영역으로 나눈다.

Young 영역: 생성된지 얼마 되지 않은 객체들을 저장하는 장소(시간이 지남에 따라 우선순위가 낮아지면 Old 영역으로 옮겨짐)

Old 영역 : 생성된지 오래된 객체를 저장하는 장소

Perm 영역 : Class, Method 등 코드가 저장되는 영역으로, JVM에 의해 사용된다.

 

 

 Eden 영역은 자바 객체가 생성되자마자 저장되는 장소입니다. JVM이 메모리를 관리하는 방식 - Minor GC, FULL GC

New/Young 영역의 GC Minor GC라고 하고Old 영역의 GC Full FC라고 합니다. Minor GC는 자주 일어나기 떄문에 GC에 걸리는 시간이 짧은 알고리즘을 선택하는 것이 적합하다.

 

Full GC는 속도가 매우 느리며, Full Gc가 일어나는 도중 순간적을 자바 애플리케이션이 멈춰버리기 때문에, Full Gc가 일어나는 정도와 시간은 애플리케이션의 성능과 안전성에 큰 영향을 미침. Minor gc < Major Gc 메모리가 더 많이 차지하고, 대부분 Gc 튜닝은 major Gc에서 일어남.

 

GC 튜닝 목표의 핵심 : Minor GC 보다 Stop the world 시간이 긴 Major GC 관리

1.    Old 영역으로 넘어가는 객체의 수 최소화하기. Young영역 조절

2.    Full GC 시간 줄이기. Old 영역 조절

 

 

1. Default GC

 기본적인 GC 방법으로 Minor GC에서 Copy & Scavenge 알고리즘 사용하고Full GC에서 Mark & Compact 알고리즘 사용하는 방법입니다.

 

Copy & Scavenge

 Minor GC 발생하면 Eden Survivor1 활성 객체를 Survivor2 복사하고, Eden Survivor1 영역을 비웁니다.

 다음 Minor GC 발생하면 Eden Survivor2 활성 객체를 Survivor1 복사하고, Eden Survivor2 영역을 비웁니다.

 다음과 같은 작업을 반복적으로 수행해 오래된 객체는 Old 영역으로 옮겨지게 됩니다.

 속도가 비교적 빠르고, 작은 크기의 메모리를 Collecting 하는데 효과적인 알고리즘입니다.

 

Mark & Compact

 전체 객체의 참조를 확인해 참조되지 않은 객체를 표시하고, 표시된 객체의 메모리를 반환하거나 사용하는 객체로 대체하는 알고리즘입니다.

 

 

JVM 실행 과정

프로그램이 실행되면 JVM OS로부터 프로그램이 필요로 하는 메모리를 할당 받는다. JVM 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.

자바 컴파일러(javac) 자바소스(.java)코드를 읽어 들여 자바 바이트코드(.class) 변환시킨다.

변경된 Class 파일들을 Class Loader 통해 JVM 메모리영역(Runtime Data Areas) 영역으로 로딩한다.

로딩된 class파일들은 Execution engine 통해 해석된다.

해석된 바이트코드는 Runtime Data Areas 배치되어 실질적인 수행이 이루어지게된다. 이러한 실행과정속에서 JVM 필요에 따라 Thread Synchronization GC같은 관리 작업을 수행한다.

 

 

자바 메모리 영역

  • 메소드 영역 : 클래스 메타 데이터(Field 이름, Field 타입, Class 이름 등등)
  • 스택 영역 : 기본형 데이터, 로컬 변수(참조형일 경우 주소값만 저장됨) 저장되는 영역
  • 영역 : 참조형 데이터가 저장되는 영역

 

 

static 데이터는 어느 메모리 영역에 존재하는가?

: Java 8 이전에는 Method Area Permgen(permanant Generation Space) 할당하였다. Static data 애플리케이션이 생성되면 영구적으로 메모리에 올라가기 때문에 String Constant Pool이나 Static 배열 오용으로 인한 OutOfMemory 이슈가 발생하였다. (Perm 영역은 JVM 의해 크기가 강제되던 영역이다)

 

Java 8 이후부터는 PermGen 영역이 Metaspace 영역으로 변경되면서 기존에 관리되던 Static 데이터나 String Constant Pool Heap 메모리로 이동하게 되었고 클래스의 메타 데이터만 Metaspace 이동하게 되었다. Metaspace 영역은 네이티브 메모리에서 관리하므로 -XX:MaxPermSize 통해서 관리되는 데이터 양에 따라 유동적으로 관리할 있게 되었다.

 

* JVM의 피연산자 스택은 피연산자를 4 Bytes 단위로 저장한다는 것이다. , char short와 같이 int보다 작은 자료형의 값을 계산하면 int형으로 자동 형 변환되어 연산이 수행된다.

 

* 원시 타입은 스택 영역에 존재한다. 반면 참조 타입은 스택 영역에는 참조 값만 있고, 실제 값은 힙 영역에 존재한다. 참조 타입은 최소 2번 메모리 접근을 해야 하고, 일부 타입의 경우 값을 필요로 할 때 언박싱 과정(ex. Double double, Integer int)을 거쳐야 하므로 원시 타입과 비교해서 접근 속도가 느린 편이다.

 

* Method Area(Static Area)은 초기 로드 필요한 정보들 즉 필요한 패키지 클래스, 인터페이스, 상수static변수, final 변수, 클래스 멤버 변수 등 로드된 후 메모리에 항상 상주하고 있는 영역입니다. Stack Area는 클래스 안 메서드 실행 시 해당 영역이 할당되며 메서드에서 직접 사용할 지역 변수, 파라미터, 리턴 값, 참조 변수일 경우 주소 값들이 저장됩니다. Heap Area은 메서드 안에서 사용되는 객체들을 위한 영역으로 new를 통해 생성된 객체, 배열, immutal 객체 등의 메모리와 값이 저장됩니다.

 

 

 

참고

1. https://incheol-jung.gitbook.io/docs/study/object/2020-03-10-object-chap1

 

1장 객체, 설계 - Incheol's TECH BLOG

Theater의 enter 메서드는 프로세스(Process)이며 Audience, TicketSeller, Bag, TicketOffice는 데이터(Data)이다. 이처럼 프로세스와 데이터를 별도의 모듈에 위치시키는 방식을 절차적 프로그래밍이라고 부른다.

incheol-jung.gitbook.io

2. https://steady-coding.tistory.com/606

 

[Java] 원시 타입 vs 참조 타입

java-study에서 스터디를 진행하고 있습니다. 원시 타입 원시 타입은 정수, 실수, 문자, 논리 리터럴 등 실제 데이터 값을 저장하는 타입이다. int a = 10; 와 같이 코드를 작성했다면 정수 값이 할당될

steady-coding.tistory.com

 

'Spring & Java > Java' 카테고리의 다른 글

2. Spring 3대 요소  (0) 2023.11.23
1. 핵심원리 기본편  (0) 2022.08.02
3. 개념  (0) 2022.07.18
3. 스프링 웹 개발 기초  (0) 2022.07.14
2. Java (TDD, GCC)  (0) 2022.07.14
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.