티스토리 뷰

Programming/Java

Java Memory Structure

Albothyl 2016. 8. 20. 20:41

1. JVM


- Class loader : 런타임에 클래스를 처음으로 참조할 때 해당 클래스를 Runtime Data Areas로 로드하고 링크한다.


- Runtime Data Areas : JVM이 운영체제 위에서 실행 되면서 할당받는 메모리 영역이다.


- Execution Engine : Load된 Class를 실행하는 엔진이다.


- Garbage Collector : 사용 되지않는 객체를 해제하여 자동으로 메모리를 관리한다.




2. Runtime Data Areas


- Method

- 메서드 영역은 모든 스레드가 공유하는 영역으로 JVM이 시작될 때 생성된다. JVM이 읽어 들인 각각의 클래스 인터페이스에 대한 런타임 상수 풀, 필드메서드 정보, Static 변수, 메서드의 바이트코드 등을 보관한다.


- Heap

- 인스턴스 또는 객체를 저장하는 공간으로 가비지 컬렉션 대상이다. JVM 성능 등의 이슈에서 가장 많이 언급된다.


- Stack

- JVM 스택은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 생성된다. 스택 프레임(Stack Frame)이라는 구조체를 저장하는 스택으로, JVM은 오직 JVM 스택에 스택 프레임을 추가하고(push) 제거하는(pop) 동작만 수행한다. 예외 발생 시 printStackTrace() 등의 메서드로 보여주는 Stack Trace의 각 라인은 하나의 스택 프레임을 표현한다.


- Last In First Out (LIFO)

- 메서드 호출 시마다 각각의 스택프레임이 생성된다.

- 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장한다.


- PC Register

- 레지스터는 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 생성된다. PC 레지스터는 현재 수행 중인 JVM 명령의 주소를 갖는다.


- Native

- 자바 외의 언어로 작성된 네이티브 코드를 위한 스택이다. 즉, JNI(Java Native Interface)를 통해 호출하는 C/C++ 등의 코드를 수행하기 위한 스택으로, 언어에 맞게 C 스택이나 C++ 스택이 생성된다.




3. Heap


- Heap은 현재 실행되고 있는 Java의 데이터가 생성되고 소멸하는 영역이다. 

- Gargabe Collector가 사용하지 않는 객체를 삭제하여 메모리를 수거한다.


- 신규 객체는 YOUNG 영역이라고 불리는 메모리 영역에 생성된다.

- 시간이 오래 지나거나 더이상 사용 되지 않는 객체는 TENURED 영역으로 옮겨진다.

- PERM영역은 Garbage Collect에 필요한 자원들이 있는 영역이다. Runtime Data Areas의 Method 영역이다.


- Minor Garbage Collection (수행시간이 1초 미만으로 매우 짧고 서비스에 영향을 끼치지 않는다.)

1. 새로 생성한 대부분의 객체는 Eden 영역에 위치한다.

2. Eden 영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다.

3. Eden 영역에서 GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역으로 객체가 계속 쌓인다.

4. 하나의 Survivor 영역이 가득 차게 되면 그 중에서 살아남은 객체를 다른 Survivor 영역으로 이동한다. 그리고 가득 찬 Survivor 영역은 아무 데이터도 없는 상태로 된다.

5. 이 과정을 반복(s1 <-> s2 를 약 32번 반복)하다가 계속해서 살아남아 있는 객체는 Old 영역으로 이동하게 된다.


- Major Garbage Collection (수행시간이 오래거리고 실행중 프로세스가 잠시 정지하고 서비스에 영향을 미친다.)

1. Old영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체들을 모두 삭제하고 메모리를 반환하다.


- JDK 7 기준으로 GC의 종류 (GC 종류에 따라서 Old영역의 GC 방식이 틀려진다.)

 Serial GC

 ** 주의 : Serial GC는 데스크톱의 CPU 코어가 하나만 있을 때 사용하기 위해서 만든 방식으로 애플리케이션의 성능이 많이 떨어진다. 때문에 운영 서버에서 절대 사용하면 않된다.

- Young 영역에서의 GC는 앞 절에서 설명한 방식을 사용한다. Old 영역의 GC는 mark-sweep-compact이라는 알고리즘을 사용한다. 이 알고리즘의 첫 단계는 Old 영역에 살아 있는 객체를 식별(Mark)하는 것이다. 그 다음에는 힙(heap)의 앞 부분부터 확인하여 살아 있는 것만 남긴다(Sweep). 마지막 단계에서는 각 객체들이 연속되게 쌓이도록 힙의 가장 앞 부분부터 채워서 객체가 존재하는 부분과 객체가 없는 부분으로 나눈다(Compaction).

- Serial GC는 적은 메모리와 CPU 코어 개수가 적을 때 적합한 방식이다.

 Parallel GC

 - 동작은 Serial GC와 같으나 여러 쓰레드에서 병렬로 수행된다. 그렇기 때문에 Serial GC보다 빠른게 객체를 처리할 수 있다. 

- Parallel GC는 메모리가 충분하고 코어의 개수가 많을 때 유리하다. Parallel GC는 Throughput GC라고도 부른다.


 Parallel Old GC

(Parallel Compacting GC)

 - Parallel Old GC는 JDK 5 update 6부터 제공한 GC 방식이다. 앞서 설명한 Parallel GC와 비교하여 Old 영역의 GC 알고리즘만 다르다. 이 방식은 Mark-Summary-Compaction 단계를 거친다. Summary 단계는 앞서 GC를 수행한 영역에 대해서 별도로 살아 있는 객체를 식별한다는 점에서 Mark-Sweep-Compaction 알고리즘의 Sweep 단계와 다르며, 약간 더 복잡한 단계를 거친다.

 Concurrent Mark & Sweep GC

(이하 CMS)

 ** 주의 : 

- 다른 GC 방식보다 메모리와 CPU를 더 많이 사용한다.

- Compaction 단계가 기본적으로 제공되지 않는다.

- 따라서, CMS GC를 사용할 때에는 신중히 검토한 후에 사용해야 한다. 그리고 조각난 메모리가 많아 Compaction 작업을 실행하면 다른 GC 방식의 stop-the-world 시간보다 stop-the-world 시간이 더 길기 때문에 Compaction 작업이 얼마나 자주, 오랫동안 수행되는지 확인해야 한다.


- 1. 초기 Initial Mark 단계에서는 클래스 로더에서 가장 가까운 객체 중 살아 있는 객체만 찾는 것으로 끝낸다. 따라서, 멈추는 시간은 매우 짧다. 그리고 Concurrent Mark 단계에서는 방금 살아있다고 확인한 객체에서 참조하고 있는 객체들을 따라가면서 확인한다. 이 단계의 특징은 다른 스레드가 실행 중인 상태에서 동시에 진행된다는 것이다.

- 2. 그 다음 Remark 단계에서는 Concurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다. 마지막으로 Concurrent Sweep 단계에서는 쓰레기를 정리하는 작업을 실행한다. 이 작업도 다른 스레드가 실행되고 있는 상황에서 진행한다.

- 3. 이러한 단계로 진행되는 GC 방식이기 때문에 stop-the-world 시간이 매우 짧다. 모든 애플리케이션의 응답 속도가 매우 중요할 때 CMS GC를 사용하며, Low Latency GC라고도 부른다. 

 G1(Garbage First) GC

 - G1 GC를 이해하려면 지금까지의 Young 영역과 Old 영역에 대해서는 잊는 것이 좋다.

G1 GC는 바둑판 모양의 각 영역에 객체를 할당하고 GC를 실행한다. 그러다가, 해당 영역이 꽉 차면 다른 영역에서 객체를 할당하고 GC를 실행한다. 즉, 지금까지 설명한 Young의 세가지 영역에서 데이터가 Old 영역으로 이동하는 단계가 사라진 GC 방식이라고 이해하면 된다. G1 GC는 장기적으로 말도 많고 탈도 많은 CMS GC를 대체하기 위해서 만들어 졌다.




--------------- 전체 구조 한눈에 보기 ----------------



참조 : 

http://d2.naver.com/helloworld/1230

http://d2.naver.com/helloworld/1329

'Programming > Java' 카테고리의 다른 글

Generic  (0) 2016.08.22
Static  (0) 2016.08.21
Enum  (0) 2016.08.17
정렬 (Comparable, Comparator, Ordering)  (0) 2016.08.16
Serializable  (0) 2016.08.15
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함