컴퓨터나 자바에서 프로그램이 돌아가는 영역을 메모리라고 하는데, 자바의 메모리는 대표적으로 3개로 나뉜다.

첫번째는 우리가 현재 직접 코드로 짜고 만드는 클래스와 static이 붙지 않은 멤버 변수나 메소드 함수, 자바에서 가장 많이 쓰는 Main 메소드 그리고 단순한 숫자 상수 리터럴이나 String 객체 등이 저장되는 상수 풀이 저장되는 Static 메모리, 정적 메모리이고

두번째는 클래스 내부에서 선언되었지만 static 붙지 않은 일반 메서드나 그 메서드의 지역 변수들이 저장되는 Stack 메모리가 있으며

마지막으로는 클래스의 객체나 배열 객체가 만들어지고 그 객체 '자체 값'이 저장되는 Heap 메모리가 있다.

좀 더 구체적으로 말하자면static 메모리는 프로그램이 로드되자마자 불러오는 메모리이고 그렇기에 항상 객체를 생성해서 접근해야하는 Heap 메모리 영역과는 반대되는 영역이라 할수 있다. (그래서 Static 메모리에 들어가는 유형들을 보면 항상 우리가 이클립스를 키면서 바로 입력하는 숫자와 문자 리터럴, String 관련 메소드들, 항상 우리가 보는 메인 메소드들과 클래스들 그리고 후일에 보게될 자바 기본 패키지들과 관련된 클래스들 메소드들 모두 Static 메모리 영역에 속한다.)

그렇기에 우리가 Static 선언이 된 멤버 변수나 메소드들은 굳이 객체를 생성 안해도 (생성해서 접근도 가능은 하지만) 패키지명.클래스명.메소드명 혹은 멤버변수만으로 접근이 가능하다. 그래서 같은 프로젝트 안의 어떤 패키지, 클래스, 메소드안이라도 Static 변수나 메서드는 접근이 가능하며 한 메모리 영역을 서로 공유하기에 값이 변경되면 다른 패키지/클래스.메소드에서 또 불러와도 마지막에 변경된 값이 불러와진다. 또한, Static 메소드는 변수를 사용해야할때 그 변수는 무조건 클래스 내에서 Static으로 미리 선언된 Static 멤버 변수이거나 혹은 그 메서드가 따로 지칭한 지역 변수 (메소드에서만 사용 가능, 메소드 밖에선 사용 불가능. 이 부분은 아래 stack 메모리에서 후술하겠다.)만 사용 가능하다. 그리고 Static 변수는 클래스의 멤버 변수만이 될수 있다. 또, static으로 선언된 변수나 메서드는 이탤릭체로 표시된다.

다음으로 넘어가서 Stack 메모리는 (Static이 붙지 않은) 클래스 안에서 따로 선언된 메소드와 그 메소드안에서 선언되어 메소드 안에서만 사용되는 지역 변수가 저장되는 공간을 뜻하며 LIFO, Last in First out 규칙에 따라 가장 마지막에 선언된 (바깥에 위치한) 메소드나 지역 변수가 먼저 실행되고 실행되고 나면 가장 먼저 없어지는 그런 특성을 가지고 있다.

예를 들자면, 내가 amd라는 메소드가 있고 그 아래줄에 cmd라는 메소드가 있는데 cmd 메소드에서 amd 메소드를 호출하고 amd 메소드에서는 지역 변수 c를 사용해서 어떤 계산을 한다고 할때, cmd 메소드를 호출하면

가장 아래 마지막에 위치했던 cmd가 먼저 메모리에 올라가고 cmd 메소드가 안의 코드 내용, 즉 amd를 호출하고나서 더 이상 실행할것이 없다면 cmd는 메모리에서 사라진다. 그리고 amd를 호출했으니 amd가 메모리에 들어오고 amd안, 지역 변수 c를 이용한 연산 처리를 하면 지역 변수와 함께 연산 처리를 위한 수식이 메모리에 또 올라오고 이 처리가 다 되어 결과값이 나왔을때,

쓰였던 지역 변수 c와 수식들과 먼저 불렸던 amd 메소드는 사라져 결과값만 남게 되어 이 결과값은 cmd 메소드를 호출했던 자리로 반환된다.

이처럼 Stack 메모리 영역에서는 메소드들과 관련된 지역 변수들 및 수식들이 올라가고 그것의 처리가 끝날때마다 단계별로 LIFO 규칙을 지키며 메모리에서 사라지는 과정이 발생한다.

마지막으로 Heap 메모리 영역, 실제로 우리가 자바를 다루면서 근간이라고 할수 있는 객체를 다룰때 그 객체가 실제로 저장되는 메모리 영역이 바로 Heap 메모리 영역이다.

참고로 말하자면 우리가 생성자를 이용해 객체를 생성하면 이 Heap 메모리 영역에 객체가 저장되면서 이 객체를 가리키는 변수는 Heap 메모리 영역 안에 이 객체가 실제로 저장된 위치를 가리키는 주소만 가진다. 그리고 이 객체 변수는 지역 변수이며 그렇기에 위치한 영역은 Stack 영역이다. (그래서 객체를 담는 변수를 주소를 가지고 있다는 의미에서 참조 변수라고 하며, 이 변수를 출력문에서 따로 toString 오버라이드 처리 없이 출력하면 그 주소값만 출력된다.)

그래서 객체를 이용한 연산 작업은 이 Heap 메모리에 객체가 없으면 불가능하며 참조변수에 다른 객체를 담게된다면 원본 객체와 참조변수간의 연결 관계는 끊어진다. 이 경우에 더이상 이 객체가 쓰이지 않는다면 GC, Garbage Collector에 의해 객체는 메모리에서 지워지게 된다.

자바의 메모리 영역은 간단히 보자면 이 정도이며 좀 더 자세한 내용은 다음 링크에 가면 알수 있다.

다음장에서는 드디어 자바의 꽃인 상속과 인터페이스에 대해서 배워보겠다.

0개의 댓글