[JAVA] 자바 메모리 구조와 static

Jaemin Lee·2023년 12월 4일

JAVA

목록 보기
6/7

이 글은 Inflearn 강의 중 김영한님의 김영한의 실전 자바 - 기본편을 감상하며 작성하였습니다.


JAVA 메모리 구조

자바의 메모리 구조는 크게 메서드 영역, 스택 영역, 힙 영역 으로 나누어진다.

  • 메서드영역

    • 메서드영역은 클래스 정보를 보관하는 영역이다.
    • 힙 영역에 인스턴스가 생성되면 인스턴스에 인스턴스 변수는 생성되지만 인스턴스 메서드는 메서드영역의 메서드 정보를 참조한다.
    • 메서드영역에는 클래스정보, static영역, 런타임 상수 풀 이 존재한다.
    • 클래스정보: 클래스정보에는 변수와 메서드 등 클래스에 대한 실행코드, 필드, 메서드와 생성자 코드 등 모든 실행 코드가 생성된다.
    • static 영역: static 변수를 보관한다.
    • 런타임 상수 풀: 공통 리터럴 상수를 보관한다.

  • 스택영역

    • 실제 프로그램이 실행되는 영역이다. 메서드를 실행할 때 마다 하나씩 생성되여 쌓이고 LIFO(Last In First Out) 으로 소멸된다.
    • 메서드 호출하면 Stack frame 이 하나 생성되고 메서드가 종료되면 소멸된다.
    • Statck frame 에는 지역변수, 중간연산결과, 메서드 호출정보가 포함된다.
  • 힙 영역

    • 인스턴스가 생성되는 영역이다. new 키워드를 사용하면 이 메모리영역에 인스턴스가 생성된다. 클래스의 인스턴스 뿐 아니라 new 로 생성하는 배열 등 모든 자료구조가 여기에 생성된다. String 도 new 키워드를 사용하여 인스턴스화 하면 힙 영역에 생성되고 리터럴로 생성하면 메서드영역의 상수풀에 생성된다.
    • 인스턴스에 생성된 인스턴스메서드가 메서드영역의 클래스정보에있는 메서드 정보를 참조한다.


static

static 키워드는 멤버변수와 메서드에 사용된다.

public class Test {
	public static int a;
    public static showA () {
    	System.out.println(a);
    }
}

static 키워드가 붙은 멤버변수와 메서드의 정보는 메서드영역의 static 영역 에 생성된다.

이제 static 키워드가 사용된 멤버변수 ashowA 메서드는 Test 클래스를 인스턴스화 하지않고 사용할 수 있다.

public static void main(String[] args) {
	Test.a = 10;
    Test.showA();
}

왜 이런 키워드와 영역을 만들게 되었을까?

어떤 객체가 생성될 때 생성자를 통해 생성된 인스턴스를 카운팅하는 변수를 생성해보자.

public class Test {
	public int count;
    Test () {
    	count++;
    }
}

이제 객체를 생성하면 count 변수의 값이 하나씩 증가한다.

Test test1 = new Test();
Test test2 = new Test();
Test test3 = new Test();

System.out.println(test1.count);
System.out.println(test2.count);
System.out.println(test3.count);

//결과
1
1
1

이는 당연한결과이다.
Test 객체의 인스턴스가 3개 생성되었고 count 라는 변수의 공간도 3개가 생성되어가 각각 관리된다.

이를 해결하기위해 Count 클래스를 설계하고 인스턴스화한 Count 인스턴스를 통해 count 변수를 관리할 수 있지만 힙 메모리영역을 낭비하게 된다.


static 변수와 메서드 사용

static 변수 및 메서드는 정적변수, 정적메서드 또는 클래스변수, 클래스메서드라고 부른다.
static 키워드가 붙지 않은 변수와 메서드는 인스턴스변수, 인스턴스메서드 라고 부른다.

  • static 변수와 메서드는 static 메서드에서만 사용할 수 있다.
  • 인스턴스메서드는 static 변수와 메서드도 사용할 수 있다.

static 변수와 메서드는 메서드영역의 static 영역에 보관된다. static 영역의 메서드에서 인스턴스 변수와 메서드를 포함하는 클래스가 힙 영역에 인스턴스화 되지않아 인스턴스변수와 메서드가 생성되지 않았기때문에 사용할 수 없다.

public class Test {
	private int a;
	static int b;
    
    public void showA () {
    	System.out.println(a);
        showB();
    }
    
    static void showB () {
    	System.out.println(b);
        showA(); //클래스메서드(정적메서드) 에서 인스턴스 메서드를 호출하여 컴파일에러 발생
    }
}
profile
Developer

0개의 댓글