Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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
Tags
more
Archives
Today
Total
관리 메뉴

개발 한번 해블로그

[Java] 16. static과 JVM 메모리 모델 이해하기 본문

Java

[Java] 16. static과 JVM 메모리 모델 이해하기

hide on bush 2023. 12. 8. 12:52

static과 JVM 다 들어본 단어인데~~ 초짜들에게는 들어도 다시 까먹게 되는 magic 
그래도 나는 잊지않음(아마도)

1. static과 메모리의 관계

메인(시작) 클래스는 왜 객체 생성 없이(new ~~) 실행될까? → 메인클래스가 동작되는 방식을 이해해야지 알 수 있다

1) JVM이 실행할 클래스를 찾는다 → 찾았다면?!
2) static 키워드가 붙어있는 멤버들을 정해진 메모리(static zone) 위치에 한번 자동으로 로딩
- 여기서 static 멤버들은 클래스를 사용하는 시점에서 딱 한번 메모리에 로딩된다
3) JVM이 static zone에서 main() 메서드를 호출
4) 호출된 메서드를 Call Stack Frame Area(Stack Area)에 push(기계어코드를 넣고) 한 뒤 동작을 시작

public class StaticTest {
    public static void main(String[] args) {
        int a=10;
        int b=20;
        int sum=StaticTest.hap(a,b);
        System.out.println(sum);
    }
    //Q. 매개변수로 2개의 정수를 입력받아 총합을 구하여 리턴하는 메서드 정의
    public static int hap(int a, int b){
        int v=a+b;
        return v;
    }
}

- main이 먼저 있고 그 위에 hap이 오는 LIFO(Last In First Out)구조


2. static과 non static 멤버들의 접근 방법(하나의 클래스에서)


- 객체를 생성해서 메모리에 로딩(new~~)
- stack area가 아닌 Heap area에 생성

public class NoneStaticTest {
    public static void main(String[] args) {
        int a=10;
        int b=20;
        NoneStaticTest st=new NoneStaticTest();
        int sum=st.hap(a,b);
        System.out.println("sum = " + sum);
    }
    public int hap(int a, int b){
        int v=a+b;
        return v;
    }
}


3. static과 non static 멤버들의 접근 방법(두 개의 클래스에서)

<static 접근 방법>

- static 멤버는 클래스를 사용하는 시점에서 자동으로 static zone에 로딩
- 따라서 new를 이용하여 객체를 생성할 필요가 없고 <클래스 이름.호출메서드>로 static 멤버를 접근하면 된다

public class MyUtil {
    public static int hap(int a, int b){
        int v=a+b;
        return v;
    }
}
import fc.java.model.MyUtil;

public class StaticAccess {
    public static void main(String[] args) {
        int a=10;
        int b=20;
        int sum= MyUtil.hap(a,b);
        System.out.println(sum);
    }
}

 

<non static 접근 방법>

public class MyUtil1 {
    public int hap(int a, int b){
        int v=a+b;
        return v;
    }
}
import fc.java.model.MyUtil1;

public class NoneStaticAccess {
    public static void main(String[] args) {
        int a=10;
        int b=20;
        MyUtil1 my1=new MyUtil1();
        int sum=my1.hap(a,b);
        System.out.println("sum = " + sum);
    }
}

 


4. JVM의 메모리 모델

1) method area

- static-zone과 non static zone으로 나뉨
- 메서드의 바이트코드(기계어코드)가 할당되는 공간
- static 멤버들은 static zone에 할당

2) stack area(Call stack frame area)/PC register(Native Method area)
- 메서드가 호출되면 메서드의 기계어코드를 할당받고 메서드가 실행되는 메모리 공간, 즉 지역변수, 매개변수들이 만들어지는 공간
- PC에 의해서 현재 실행 중인 프로그램의 위치가 관리
- LIFO 구조로 운영되는 메모리 공간(메서드의 호출 순서를 알 수 있음)

3) Heap Area Generation
- 객체가 생성되는 메모리 공간(new 연산자)
- GC(garbage collector)에 의해서 메모리가 수집- 프로그램이 끝나고 메모리에 쌓인 객체들이 주기적으로 소멸시켜 줌

4) Runtime Constant Pool
- 상수 값 할당이 되는 메모리 공간
- 문자열 중 문자열 상수(Literal)가 할당되는 메모리 공간


5. 객체 생성과 static의 관계

- new 객체를 생성 못하게 하려면 private으로 바꿔야 한다
- 자바 API에서 pricate 생성자를 가지고 있는 클래스가 있다(ex. System, Math 등)
- 생성자는 반드시 public이다 라는 것은 잘못된 말임


6. class, object, instance 구분하기

서로 비슷한 개념으로 모두 객체를 나타내는 용어라고 생각하면 된다. 나는 진짜 다 똑같이 느껴졌는데 지금이라도 구분해야쥬 ^^,,

1) Class(클래스)
- 객체를 모델링하는 도구(설계도)
- 새로운 자료형을 만드는 도구

2) Object(객체)
- 클래스를 통해서 선선되는 변수
Student st;
- 여기서 Student 객체를 저장하는 st는 객체 변수
- 변수가 구체적인 실체(대상)를 가리키지 않는 상태(객체 변수)
- 객체가 서로 구분이 되지 않는 시점

3) Instance(인스턴스, 실체)
- 객체 생성에 의해 메모리(Heap Memory)에 만들어진 객체를 인스턴스
st=new Student();
- 여기서 st가 인스턴스 변수
- 객체가 구체적인 실체를 가리키는 상태이며 객체가 서로 구분이 되는 시점


이제,,, 객체와 인스턴스의 구분이 좀 되는 듯,, 그래도 뭔가 헷갈리는 기분,, 글로 설명하면 쉽지만 막상 코드짤 때 하나도 모르겠다 ㅠㅠ 주륵