language/java

JVM 메모리 구조

wooweee 2023. 3. 16. 12:05
728x90

1. 이전에 알고 있었던 JVM 메모리 구조

  • Method Area: class가 올라올 때 제일 먼저 static method와 static variable 생성
  • Call Stack: method 호출시 stack 올라오고 해당 stack에 local valiable 생성
  • Heap : 인스턴스 - 내부에 instance method, instance valiable 존재

 

  • 하지만 위의 개념은 반은 맞고 반은 틀렸다.
  • 맞은 점은 iv, im은 객체를 생성해야 사용가능하고 cv, cm은 객체를 생성하지 않아도 사용이 가능하다는 원리가 핵심이고 가장 중요한 부분이다.
  • 틀렸다는 점은 내부적으로 저장된 위치와 어떻게 호출되었는지 이기에 실제로는 몰라도 크게 상관이 없다.

 

2. JVM 내부 작동 원리

 

  • 3가지 존재
    1. static variable과 static method만 가진 class
    2. instance variable과 instance method만 가진 instance class
    3. static 과 instance를 모두 가진 짬뽕 class

  • class 영역
    • method area와 거의 동일, class 설계도가 저장되는 곳

    • class 설계도가 저장이 된다는 것을 코드로 표현
////// method Area 시작 //////

...

// class 영역에 class 설계도가 저장이 된다는 의미를 코드로 나타낸 것
class ExampleClass {
    static int x;
    static int y;
}

// constant pool
...

////// method Area 끝 //////



////// source code 시작 ////// 

class ExampleClass {
    static int x;
    static int y;
}

////// source code 끝 //////

 

2.1. static variable, static method만 가진 Class

 

  • cv, cm을 가지고 있는 class는 프로그램이 동작하는 순간 부터 method area의 클래스 영역에 클래스 설계도 저장
  • 그렇기 때문에 독립적으로 존재가능
  • 객체 생성 없이 class명을 이용해서 메서드나 변수 사용 가능
  • 저장 예
////// method Area 시작 //////

...

// class 영역에 class 설계도가 저장이 된다는 의미를 코드로 나타낸 것
class ExampleClass {
    static int x;
    static void method(){};
}

// constant pool
...

////// method Area 끝 //////



////// source code 시작 ////// 

class ExampleClass {
    static int x;
    static void method(){};
}

////// source code 끝 //////

 

2.2. instance variable과 instance method만 가진 instance class

 

  • class가 존재하더라도 객체가 생성되야지 메모리에 저장이 시작된다.
  • 객체 생성 후 저장 방식
    • Method Area와 Heap 2곳에 저장
      • Method Area : 클래스 영역에 클래스 설계도가 저장 되는데 im만 저장
        • 해당 설계도는 주소값이 존재
      • Heap: 생성된 객체가 저장되는데 iv만 저장
        • Method Area에 저장된 해당 설계도의 주소값을 보유
        • 그래서 실제로 객체는 iv의 집합이다.
  • 분리해서 저장하는 이유 - 효율성
    • method는 변수와 달리 변경되는 부분이 없는 동일한 명령을 수행하는 부분
    • method를 Method Area에 한번만 생성하고 클래스 설계도 주소를 공유해서 쓰는 것이 효율적
  • iv만 존재하는 객체가 im에 접근할 수 있는 이유
    1. 객체는 클래스 영역에 저장된 im이 존재하는 클래스 설계도의 주소 값을 보유
    2. JVM이 주소값을 참조하여 객체의 클래스 설계도에 접근 할 수 있다.
    3. 그래서 method 호출 시 JVM이 객체의 해당 클래스 정보(==주소값)를 이용해서 method를 참조 후 사용한다.

 

예시

constant pool 등 존재한다는 의미는 static 부분에서 보여줬으므로 코드 간략화를 위해 생략

 

ex1) class만 존재시

////// method Area 시작 //////

// class 영역에 class 설계도가 저장이 된다는 의미를 코드로 나타낸 것

객체를 생성하지 않았으므로 메모리에 아무것도 안 올라옴

////// method Area 끝 //////



////// source code 시작 ////// 

class ExampleClass {
    int x;
    void method1(){};
    void method2(){};
    void method3(){};
}

////// source code 끝 //////

ex2) 객체 생성

////// method Area 시작 //////

// class 영역에 class 설계도가 저장이 된다는 의미를 코드로 나타낸 것
// method만 보유
class ExampleClass {
    void method1(){};
    void method2(){};
    void method3(){};
    // 주소값 : 0x100
}

////// method Area 끝 //////

////// call stack 생략 /////

////// Heap 시작      //////


// 객체 주소 0x999
// class ExampleCalss 설계도 주소 보유 (0x100)
exampleClassObject [[ int x ][ int y ]] // []는 array가 아니고 객체 박스 표현 한 것


////// Heap 끝      //////


////// source code 시작 ////// 

class ExampleClass {
    int x;
    int y;
    void method1(){};
    void method2(){};
    void method3(){};
}

class Practice{
    public static void main(String args[]){
        ExampleClass exmapleClassObject = new ExampleClass();
    }
}

////// source code 끝 //////

 

2.3. static 과 instance를 모두 가진 class

  • 객체 생성 없이도 class 내부에 static들만 묶어서 method area에 클래스 설계도 생성
  • 객체를 생성시
    • Method Area와 Heap 2곳에 저장
      • Method Area : 클래스 영역에 클래스 설계도가 저장 되는데 im만 저장
        • 이 때 클래스 설계도와 static 묶은 설계도는 다른 것 
        • 해당 설계도는 주소값이 존재
      • Heap: 생성된 객체가 저장되는데 iv만 저장
        • Method Area에 저장된 해당 설계도의 주소값을 보유
        • 그래서 실제로 객체는 iv의 집합이다.

 

  • 이러니깐 static은 최대한 static끼리 묶어서 class 만들고 인스턴스는 인스턴스끼리 묶어서 만드는 것 같다.

 

ex1) class만 존재

////// method Area 시작 //////

// class 영역에 class 설계도가 저장이 된다는 의미를 코드로 나타낸 것

// static class 설계도
class ExampleClass {
    static int x;
    static void method(){};
}

// instance class 설계도
객체 생성 안해서 아직 없음

////// method Area 끝 //////


////// source code 시작 ////// 

class ExampleClass {
    static int x;
    static void method(){};
    int y;
    void method1(){};
}

////// source code 끝 //////

 

ex2) 객체 생성시

////// method Area 시작 //////

// class 영역에 class 설계도가 저장이 된다는 의미를 코드로 나타낸 것

// static class 설계도
class ExampleClass {
    static int x;
    static void method(){};
}

// instance class 설계도
class ExampleClass {
    void method1(){};
    // 주소값 : 0x100
}

////// method Area 끝 //////

////// call stack 생략 /////

////// Heap 시작      //////


// 객체 주소 0x999
// class ExampleCalss 설계도 주소 보유 (0x100)
exampleClassObject [[ int y ]] // []는 array가 아니고 객체 박스 표현 한 것


////// Heap 끝      //////



////// source code 시작 ////// 

class ExampleClass {
    static int x;
    static void method(){};
    int y;
    void method1(){};
}

class Practice{
    public static void main(String args[]){
        ExampleClass exmapleClassObject = new ExampleClass();
    }
}

////// source code 끝 //////