개요
C, C++과 같은 언어는 운영체제. 즉, 실행환경에 따라 컴파일러가 그에 맞는 기계어 코드로 변환합니다.
Java는 이와 같은 환경 종속성을 어느 정도 해결하기 위해 JVM, Java Virtual Machine이라는 구조를 채용했습니다.
JVM은 Java를 실행하기 위한 환경을 제공해줄 뿐 아니라, GC, JIT 등과 같은 기능을 제공하고, 주기억장치를 할당받아 사용하는 역할을 맡고 있습니다.
오늘은 JVM이 주기억장치를 할당받으면 이를 어떻게 나누고 사용하는지 알아보도록 하겠습니다.
JVM 메모리구조

JVM은 위와 같은 구조를 가지고 있습니다.
여기서, Java가 실행될 때 클래스, 메서드, 객체 등의 정보를 적재하는 부분은 Runtime Data Area입니다.
이러한 메모리구조는 각 Java버전, 배포하는 주체마다 다르기 때문에, 항상 이와 같은 구조를 가지지는 않습니다.
대표적으로, Method Area의 경우 Permanent Area, Class Area, Static Area등 다양한 이름을 가지고 있습니다.
또, 어떤 경우에는 Heap에 포함된 구조로 알려진 경우도 있습니다.
오늘은 Method Area를 Heap과 분리한 구조로 보고, 설명을 진행하도록 하겠습니다.
Method Area
Method Area는 아래와 같은 데이터를 바이트코드로 저장합니다.
1. Class
2. Method
3. Interface
4. static이 붙은 데이터
5. final이 붙은 데이터
모든 스레드들이 공유하는 메모리 영역이기 때문에 어디서나 접근 가능합니다.
그렇기 때문에, 동시성 문제가 발생할 가능성이 있고 데이터 변경이 가능한 경우 관리의 필요성이 있습니다.
Stack
메서드 실행 시 생성되는 영역입니다.
지역변수와 파라미터, 리턴값, 연산에 사용되는 데이터 등
해당 메서드나 스레드의 스코프 내에서 사용되는 데이터를 보관합니다.
스레드 간 공유되지 않는 자원이기 때문에, 동시성 문제로부터 비교적 자유롭습니다.
Heap
객체 생성시 객체가 할당되는 영역입니다.
GC가 관리하는 메모리 영역이며, Hotspot JVM의 경우 Eden, Survivor1, Survivor2를 Young Generation으로 한번에 묶어 새로 생성되거나 참조상태가 유지되는 객체들을 관리합니다.
참조상태가 유지되지만, 특정 Age가 넘어간 객체들의 경우 Old Generation으로 넘기게 됩니다.
자세한 내용은 아래 링크를 참조하시면 됩니다.
(Hotspot JVM, GC : https://nangmandeveloper.tistory.com/2)
PCR(PC Register)
스레드가 실행될 때마다 생성되는 영역입니다.
영역 이름답게 프로그램 카운터, 스레드가 진행하고 있는 현재 주소와 명령어를 가집니다.
Native Method Stack
자바 이외의 언어인 C, C++, 어셈블리로 작성된 네이티브 코드를 사용하기 위해 할당되는 영역입니다.
우리에게 익숙한 메서드인 start0()메서드 또한 네이티브 코드에 해당합니다.
정리
Stack, PCR영역의 경우 메서드를 실행할 때 스레드가 독립적으로 가지게 됩니다.
따라서, 여러 스레드가 동시에 접근하는 동시성 문제로부터 비교적 자유롭습니다.
Method, Heap의 경우 여러 스레드가 동시에 접근할 수 있습니다.
따라서 동시성 문제를 해결하기 위해 synchronized와 같은 방법을 이용해야 합니다.
이 부분에 대해서 따로 포스팅을 진행하도록 하겠습니다.
+ 가끔 헷갈릴 수 있는 부분이 있습니다.
새로 생성된 객체는 Heap영역에 할당되지만, 이를 참조하는 참조변수들은 Stack, Method영역 등에 할당됩니다.
이렇게 새로 생성된 객체는 참조변수가 Stack, Method영역에 살아있어야 참조가 유지되는 것입니다.
Stack이나 Method영역에서 해당 객체에 대한 참조를 해제하는 경우 GC가 해당 객체를 지울 수 있기 때문에 유의해야 합니다.
또, 객체의 경우 해당 객체를 가리키는 참조변수가 있다면 접근이 가능할 수 있습니다.
Spring Security를 사용할 때, Connection들의 인증정보를 ThreadLocal에 저장하는 모습을 볼 수 있습니다.
코드를 조금 보면, request를 마무리할 때 ThreadLocal.remove()메서드를 호출하는 과정을 포함합니다.
이는 참조변수가 사라진 객체에 접근하는 참조변수가 생김을 예방하는 것으로 볼 수 있습니다.
'JAVA > 일반' 카테고리의 다른 글
[JAVA] ThreadPool (0) | 2023.12.21 |
---|---|
JVM부터 JDK까지 (0) | 2023.12.18 |
개요
C, C++과 같은 언어는 운영체제. 즉, 실행환경에 따라 컴파일러가 그에 맞는 기계어 코드로 변환합니다.
Java는 이와 같은 환경 종속성을 어느 정도 해결하기 위해 JVM, Java Virtual Machine이라는 구조를 채용했습니다.
JVM은 Java를 실행하기 위한 환경을 제공해줄 뿐 아니라, GC, JIT 등과 같은 기능을 제공하고, 주기억장치를 할당받아 사용하는 역할을 맡고 있습니다.
오늘은 JVM이 주기억장치를 할당받으면 이를 어떻게 나누고 사용하는지 알아보도록 하겠습니다.
JVM 메모리구조

JVM은 위와 같은 구조를 가지고 있습니다.
여기서, Java가 실행될 때 클래스, 메서드, 객체 등의 정보를 적재하는 부분은 Runtime Data Area입니다.
이러한 메모리구조는 각 Java버전, 배포하는 주체마다 다르기 때문에, 항상 이와 같은 구조를 가지지는 않습니다.
대표적으로, Method Area의 경우 Permanent Area, Class Area, Static Area등 다양한 이름을 가지고 있습니다.
또, 어떤 경우에는 Heap에 포함된 구조로 알려진 경우도 있습니다.
오늘은 Method Area를 Heap과 분리한 구조로 보고, 설명을 진행하도록 하겠습니다.
Method Area
Method Area는 아래와 같은 데이터를 바이트코드로 저장합니다.
1. Class
2. Method
3. Interface
4. static이 붙은 데이터
5. final이 붙은 데이터
모든 스레드들이 공유하는 메모리 영역이기 때문에 어디서나 접근 가능합니다.
그렇기 때문에, 동시성 문제가 발생할 가능성이 있고 데이터 변경이 가능한 경우 관리의 필요성이 있습니다.
Stack
메서드 실행 시 생성되는 영역입니다.
지역변수와 파라미터, 리턴값, 연산에 사용되는 데이터 등
해당 메서드나 스레드의 스코프 내에서 사용되는 데이터를 보관합니다.
스레드 간 공유되지 않는 자원이기 때문에, 동시성 문제로부터 비교적 자유롭습니다.
Heap
객체 생성시 객체가 할당되는 영역입니다.
GC가 관리하는 메모리 영역이며, Hotspot JVM의 경우 Eden, Survivor1, Survivor2를 Young Generation으로 한번에 묶어 새로 생성되거나 참조상태가 유지되는 객체들을 관리합니다.
참조상태가 유지되지만, 특정 Age가 넘어간 객체들의 경우 Old Generation으로 넘기게 됩니다.
자세한 내용은 아래 링크를 참조하시면 됩니다.
(Hotspot JVM, GC : https://nangmandeveloper.tistory.com/2)
PCR(PC Register)
스레드가 실행될 때마다 생성되는 영역입니다.
영역 이름답게 프로그램 카운터, 스레드가 진행하고 있는 현재 주소와 명령어를 가집니다.
Native Method Stack
자바 이외의 언어인 C, C++, 어셈블리로 작성된 네이티브 코드를 사용하기 위해 할당되는 영역입니다.
우리에게 익숙한 메서드인 start0()메서드 또한 네이티브 코드에 해당합니다.
정리
Stack, PCR영역의 경우 메서드를 실행할 때 스레드가 독립적으로 가지게 됩니다.
따라서, 여러 스레드가 동시에 접근하는 동시성 문제로부터 비교적 자유롭습니다.
Method, Heap의 경우 여러 스레드가 동시에 접근할 수 있습니다.
따라서 동시성 문제를 해결하기 위해 synchronized와 같은 방법을 이용해야 합니다.
이 부분에 대해서 따로 포스팅을 진행하도록 하겠습니다.
+ 가끔 헷갈릴 수 있는 부분이 있습니다.
새로 생성된 객체는 Heap영역에 할당되지만, 이를 참조하는 참조변수들은 Stack, Method영역 등에 할당됩니다.
이렇게 새로 생성된 객체는 참조변수가 Stack, Method영역에 살아있어야 참조가 유지되는 것입니다.
Stack이나 Method영역에서 해당 객체에 대한 참조를 해제하는 경우 GC가 해당 객체를 지울 수 있기 때문에 유의해야 합니다.
또, 객체의 경우 해당 객체를 가리키는 참조변수가 있다면 접근이 가능할 수 있습니다.
Spring Security를 사용할 때, Connection들의 인증정보를 ThreadLocal에 저장하는 모습을 볼 수 있습니다.
코드를 조금 보면, request를 마무리할 때 ThreadLocal.remove()메서드를 호출하는 과정을 포함합니다.
이는 참조변수가 사라진 객체에 접근하는 참조변수가 생김을 예방하는 것으로 볼 수 있습니다.
'JAVA > 일반' 카테고리의 다른 글
[JAVA] ThreadPool (0) | 2023.12.21 |
---|---|
JVM부터 JDK까지 (0) | 2023.12.18 |