스노우 인턴 활동 [o]
4주 2일차 강의 [o]
스노우 사수 도움 요청 업무 [o]
팀장님 지시 업무 [o]
중간/일일 업무 보고 작성 [o]
정기 팀/동기 스터디 모임 참석 및 성실도 [o]
Method Area
(메소드 영역): 클래스 정보, 상수, 정적 변수 등이 저장됩니다.
Heap Area
(힙 영역): 객체와 배열이 저장되는 곳으로, 가비지 컬렉션의 주 대상입니다.
Stack Area
(스택 영역): 각 스레드마다 런타임 스택이 생성되며,
메소드 호출과 함께 스택 프레임이 쌓이고 메소드 종료와 함께 해제됩니다.
PC Registers
: 각 스레드의 JVM 명령 주소를 가집니다.
Native Method Stack
: 네이티브 메소드 호출을 위한 스택입니다.
VM에서 프로그램이 실행될 때, 각 클래스와 인스턴스는 위의 메모리 영역
에 할당됩니다.
메소드 호출 시 매개변수, 지역 변수 등은 스택 영역
에 저장되며, 객체는 힙 영역
에 생성됩니다.
public class MemoryExample {
static int staticVar = 5; // 메소드 영역에 저장됨: 클래스 변수
int instanceVar = 10; // 힙 영역에 저장됨: 인스턴스 변수
public void show() {
int localVar = 20; // 스택 영역에 저장됨: 지역 변수
System.out.println(staticVar + " " + instanceVar + " " + localVar);
}
public static void main(String[] args) {
MemoryExample example = new MemoryExample(); // 힙 영역에 저장됨: 객체 인스턴스
example.show();
}
}
//staticVar는 클래스 변수로, 모든 인스턴스에 공통으로 사용되며 메소드 영역에 저장됩니다.
//instanceVar는 각 객체 인스턴스에 속한 변수로, 객체가 생성될 때 힙 영역에 저장됩니다.
//localVar는 show 메소드의 지역 변수로, 메소드 호출 시 스택 영역에 생성되고 메소드 종료 시 제거됩니다.
//example 객체는 힙 영역에 저장되며, 이 객체를 통해 인스턴스 변수와 메소드에 접근할 수 있습니다.
Java의 가비지 콜렉터(GC)는 JVM에서 자동으로 메모리 관리를 수행하는 시스템입니다.
이 시스템은 더 이상 사용되지 않는 객체(즉, 어떤 루트도 참조하지 않는 객체)를
메모리에서 자동으로 제거하여
메모리 누수를 방지하고효율적인 메모리 사용을 도모합니다.
"Stop-The-World"
는 가비지 콜렉션을 수행하는 동안 JVM이
애플리케이션의 모든 스레드를 일시 중지시키는 현상을 말합니다.
이는 GC가 메모리를 안정적으로 청소하고 객체의 참조 관계를 정확히 파악하기 위해 필요합니다.
STW의 지속 시간은 GC의 유형과 힙의 크기, 힙에 있는 객체의 수 등에 따라 달라질 수 있습니다.
Java에서는 메서드 오버라이딩을 통해 다형성을 구현합니다.
이를 위해 JVM은 가상 메서드 테이블을 사용하여 각 객체의 실제 메서드 구현을 찾습니다.
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
public class VirtualMethodTest {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.sound(); // "Bark" 출력
}
}
//이 코드에서 myDog.sound()는 Dog 클래스의 sound() 메서드를 호출합니다.
//이는 JVM이 런타임에 myDog의 실제 타입을 확인하고 적절한 메서드를 가상 메서드 테이블에서 찾아 호출하기 때문입니다.
부족한 점 : 처음 들어보는 종류의 개념이라 아직 확립되지 않아 좀 더 공부해야할거 같다.
스스로 시도해본 것들 :
JVM Runtime Data Area에서 일어나는 일을 눈으로 볼 수 있게 도식화 작업 (개념 확립을 위한)
public class JvmTest {
static final long MY_LONG = 5L;
public static void main(String[] args){
// 1. JvmTest JVM 로드 진행 이후
int myInt = 10;
String name = "이순신";
long myLong = MY_LONG;
Customer customer = new Customer("장영실");
int[] intArr = new int[3];
// 2. 여러 로컬 변수 선언 후
makeCustomer(name);
customer = null;
// 4. makeCustomer 메소드 종료 및 null 선언 후
String str1 = "Hello World";
String str2 = new String("Hello World");
// 5. 각 String 변수 선언 후
}
static void makeCustomer(String name){
String nameWithUppercase = name.toUpperCase();
Customer customer = new Customer(nameWithUppercase);
// 3. makeCustomer 메소드 내부 진행
}
}
[Customer]
class Customer {
static int serialNum = 1;
private String name;
public Customer(String name) {
this.name = name;
}
}
해결 내용 :
도식화 작업을 통한 이해:
JVM Runtime Data Area의 동작을 시각화하여 클래스 로딩, 객체 생성, 메소드 호출,
가비지 컬렉션 등의 과정을 명확하게 이해
실제 코드와 연결: 실제 Java 코드를 작성하고, 각 코드 블록이 JVM 내에서 어떻게 처리되는지 관찰함으로써 이론과 실제의 연결고리를 확립.
알게된 점 :
메모리 영역의 구분
: 메소드 영역, 힙, 스택의 차이점과 각 영역에서 일어나는 주요 활동들을 이해
객체의 생명주기
: 객체가 생성되고, 사용되며, 참조가 제거된 후 가비지 컬렉터에 의해 언제 메모리에서 제거되는지의 전체 과정을 파악
가비지 컬렉션의 중요성
: 메모리 관리와 성능 최적화에 있어 가비지 컬렉션의 역할을 더 깊이 이해
헷갈리거나 실수한 점 :
정적 vs 인스턴스 변수
: 정적 변수가 메소드 영역에 저장되고 인스턴스 변수가 힙에 저장된다는 점을 혼동하기 쉽다.
정적 변수는 클래스 당 하나만 생성되며 모든 인스턴스가 공유하는 반면, 인스턴스 변수는 각 객체마다 별도로 존재
메소드 영역의 내용
: 메소드 영역에 저장되는 정보(클래스 정보, 정적 변수, 상수 등)를 정확히 이해하고 있어야 한다.
이 영역은 가비지 컬렉션의 대상이 아니라는 점도 중요
스택과 힙의 사용
: 메소드 호출 시 스택 프레임의 생성과 소멸, 힙 영역에서의 객체 할당과 해제 과정을 명확히 구분해야 한다.
특히, 로컬 변수와 객체 참조 변수의 스택 저장과 실제 객체의 힙 저장 위치를 혼동하기 쉽다.
가비지 컬렉션의 실행 시점
: 가비지 컬렉션이 언제 발생하는지, 그리고 그것이 어떻게 "Stop-The-World" 현상을 일으키는지는 JVM의 성능과 직결되므로 정확히 이해하고 있어야 한다.
가비지 컬렉션의 실행 시점과 방식은 선택된 가비지 컬렉터에 따라 다를 수 있을거 같다.
회고 : 처음보는 개념이라 정리하고 확립하는데에 시간이 좀 걸렸고
아직 머리속에 제대로 확립되었는지는 검증을 통해서 알아봐야할거 같다.
도식화를 하고 여러 예시들을 접하면서 천천히 정리해야겠다.