자바 static 메모리 영역

prana·2023년 11월 23일

JAVA

목록 보기
4/8

스터디원분과 1:1로 리뷰하다가 이해가 잘 안갔던 부분이 있다고 하셔서! 다시 정리하게 됐다.
157p에서 이해가 안되는 부분이 있었다. 클래스가 제일 처음 사용될 때는

  • (1)🥕클래스의 정적 속성을 사용할 때
  • (2)🥕클래스의 정적 메서드를 사용할 때
  • (3)🥕클래스의 인스턴스를 최초로 사용할 때
  • 당근🥕이 어디에 나오는지 찾아내듯 읽으면 도움이 될 것 같다.

  • 여기서 스태틱 영역에 대해 다시 정리해보려고 한다.
Start.java

public class Start{
	public static void main(String[] args){
      System.out.println("Hello OOP!");
    }
}

p43 중요!

  1. JRE는 안에 main() 메서드가 있는지 확인한다.
  2. main() 존재가 확인되면, JRE는 프로그램 실행을 위해 JVM을 부팅시킨다.
  3. JVM은 가장 먼저 👉java.lang패키지를 T메모리의 스태틱 영역에 가져다 놓는다.
  4. 다음으로, JVM은 👉개발자가 작성한 모든 클래스와 임포트 패키지 역시 스태틱 영역에 가져다 놓는다.
  5. 그래서 스태틱 영역을 클래스들의 놀이터라고 한다.

1. main()메서드가 실행되기 전 JVM에서 수행하는 전처리 작업들

  • java.lang 패키지를 T메모리의 스태틱 영역에 배치한다.
  • import된 패키지를 T메모리의 스태틱 영역에 배치한다.
  • 프로그램 상의 모든 클래스를 T메모리의 스태틱 영역에 배치한다.

p153부터의 내용이다.

2. 클래스 생성 시의 실행 블록, static 블록

* 동물.java
package OOP.staticBlock;

public class 동물 {
    👉(2)🥕static{
        System.out.println("1. 동물 클래스 레디 온!");
    }
}

package OOP.staticBlock;

public class Driver01 {
    public static void main(String[] args) {
        동물 뽀로로 = new 동물(); // 출력값: 1. 동물 클래스 레디 온!
    }
}

main 메서드가 로딩하기 전에 ✅모든 클래스들을 스태틱 영역에 배치한다고 했었다.
👉 해당 동물 클래스 실행 시 static 블록을을 스태틱 영역에 같이 올려 실행된다는 것을 확인할 수 있다.

그렇다면 아래 Driver02.java를 보자.

package OOP.staticBlock;

public class Driver02 {
    public static void main(String[] args) {
        System.out.println("main 메서드 시작!");
        // 출력값: main 메서드 시작!
    }
}

의문1. 🤔 어? 방금 위에서 프로그램이 시작될 때, "모든 패키지와 모든 클래스"가 T메모리의 스태틱 영역에 로딩된다고 했는데?

동물 클래스 레디 온!
main 메서드 시작!

으로 동물 클래스의 static 블록도 같이 불러왔어야 하는거 아니야??

3-1. 응 아니야(p154)

Q. Driver02.java에서 동물 클래스를 사용하였는가?
A. 아니요
Q. 자바는 생각하는 것보다 지능적이다. 동물 클래스를 사용하는 코드가 없으므로 동물 클래스의 static 블록을 실행하지 않는다. (코드에 없었으니까!😶‍🌫️)

4. static 블록 안에서 사용할 수 있는 것들(p155)

* 동물.java
package OOP.staticBlock;

public class 동물 {
    👉static{
        System.out.println("1. 동물 클래스 레디 온!");
    }
}

👉static 구간에서는

  • 당연히 static 멤버만 사용할 수 있다!!
  • 왜? 객체 메머는 클래스가 static영역에 배치되고-> 객체 생성자를 통해 힙에 생성됨
  • static 블록 중에 생성자가 실행되어 객체가 만들어졌는가? 아니요


😏 책에 안적힌 동물 생성자를 추가해봤다. 생성자가 실행되기 전 static 블록을 실행하는가?

의문2. 🤔해당 패키지 또는 클래스가 처음으로 사용될 때 로딩? 이건 뭔 말?(155p)

package OOP.staticBlock;

public class Driver03 {
    public static void main(String[] args) {
        System.out.println("main 메서드 시작!");
        동물 뽀로로 = new 동물();

        /* 콘솔 출력값
         main 메서드 시작!
         1. 동물 클래스 레디 온!*/
    }
}

동물 클래스의 static 블록보다 main()메서드 실행문이 먼저 실행되었다.

package OOP.staticBlock;

public class Driver04 {
    public static void main(String[] args) {
        System.out.println("main 메서드 시작!");
        동물 뽀로로 = new 동물();
        동물 피카츄 = new 동물();
        // 두번 불렀으니까 두 번 출력되는 것 아니야..?
    }
}


동물 클래스의 인스턴스를 여러 개 만들어도 동물 클래스의 (3)🥕static 블록은 👉단 한 번만 실행되는 것을 알 수 있다.

5. 클래스의 정적 속성에 접근하는 예제

  • 여기서는 내맘대로 코드를 막 갖다가 붙여봤다. (156p)
package OOP.staticBlock;

public class Driver05 {
    public static void main(String[] args) {
        System.out.println("main 메서드 시작!");
        System.out.println(Animal.age);
        System.out.println(Animal.age);
       👉 Animal 동물 = new Animal(19);
    }
}

class Animal{
    private int myage; // 객체변수 만들기 

    (1)🥕static int age = 0;
    
    static{
        System.out.println("Animal Class ready on!");
    }
   👉 public Animal(int age){ // 생성자 추가
        System.out.println("생성자 호출용이야");
        myage = age;
        System.out.println(age);
    }
}

  • 여기서 말하고픈 것은 static 블록에 접근해서 값 불러올 수 있다 정도로만 봐도 될 것 같다.

정리

  • 클래스 정보는 해당 클래스가 전부 로딩되어 사용되어지는 것이 아니라,
    클래스가 맨 처음 사용될 때 T 메모리의 스태틱 영역에 로딩이 되며, 이때 단 한번 해당 클래스의 static 블록이 실행이 된다.
  • 자바는 스태틱 영역에 한 번 올라가면 프로그램이 종료되기 전까지는 해당 메모리를 반환할 수 없지만 그럼에도 최대한 늦게 로딩함으로써 메모리 사용을 최대한 늦추고자 하였다.
  • 클래스의 정적 속성을 사용할 때
  • 클래스의 정적 메서드를 사용할 때
  • 클래스의 인스턴스를 최초로 만들 때

0개의 댓글