1/11 섹션7 자바 메모리 구조와 static 필기
자바 메모리 구조
필기량이 많아서 빨리 끝낼 수 있을까 좀 걱정된다. 그래도 해야지 암! 아자아자!
지난 학기에 자바를 공부해야겠다 싶어서 도서관에서 책을 빌렸는데 거기에 자바의 메모리구조 설명이 있었다. 정말 자바에 대해 하나도 모르는 상태에서 집약적으로 설명해 놓은 책을 읽으니 당연히 이해가 잘 안 되지... 그때 찍어놓은 사진을 지금 다시 보니 무슨 내용인지 이제야 좀 눈에 들어오더라. 진짜 갓영한 선생님 아니었다면 어려워서 진작에 흘려보냈을 내용들...감사합니다🙏🙏
- 자바의 메모리 구조는 메서드 영역, 스택 영역, 힙 영역으로 나눌 수 있다.
- 메서드 영역: 클래스 정보 보관, 공통된 데이터나 코드 저장
- 스택 영역: 프로그램이 실제 실행되는 곳으로 메서드를 실행하면 위에 하나씩 쌓인다. (말 그대로 스택 구조)
스레드 수만큼 실행 스택이 생성된다. 스택 프레임이 종료되면 지역변수도 함께 제거된다, 스택 프레임이 모두 제거되면 프로그램도 종료된다. - 힙 영역: 인스턴스와 배열 생성, new를 통해 생성된다.
객체가 생성될 때 인스턴스(와 그 변수)는 힙 영역에 메모리가 할당되지만 메서드에 대한 새로운 메모리 할당은 없다. 메서드는 메서드 영역에서 공통으로 관리되고 실행된다. 인스턴스의 메서드를 호출하면 실제로는 메서드 영역에 있는 코드를 불러 수행한다. 즉, 공용으로 쓴다는 말!
스택, 큐 구조가 많이 사용된다 하니 빨리 자료구조를 공부해야겠다는 생각이 든다!
그리고 꿀팁!
- 단어 영역 바로 지정 단축키 ctrl w
static 변수
static 변수 = 정적 변수 = 클래스 변수
- 정적 변수에 접근하기 위해서는 '클래스명.'을 사용한다. -- 마치 클래스에 직접 접근하는 것처럼 느껴진다
- static이 붙은 멤버 변수는 힙 영역이 아닌 메서드 영역에서 관리한다.
- 같은 클래스 안에 있는 변수면 앞에 '클래스명.'을 생략해줘도 된다.
static이 붙은 곳에서만 '클래스명.'을 붙이고 this로는 사용할 수 없다.
static 변수는 메서드 영역에서 관리하고 여러 인스턴스들에서 공용으로 사용한다.
클래스 변수는 하나만 존재한다.
변수는 크게 지역변수와 멤버변수로 나눈다고 했었고 멤버변수는 위에 나온 static의 유무에 따라 클래스 변수와 인스턴스 변수로 나눌 수 있다. static이 붙은 쪽이 클래스 변수, 붙지 않은 쪽이 인스턴스 변수.
- 인스턴스 변수는 인스턴스를 생성해야 사용할 수 있고 인스턴스에 소속되어 있다. 인스턴스를 만들 때마다 새로 만들어진다.
- 클래스 변수는 인스턴스와 무관하게 클래스에 바로 접근해서 사용할 수 있고 클래스 자체에 소속되어 있다. 자바 프로그램이 시작될 때 딱 1개만 만들어진다. 보통 여러 곳에서 공유하는 목적으로 사용된다.
지역변수 - 스택영역 -- 스택 프레임 제거될 때까지
< 인스턴스 변수 - 힙 영역 -- GC가 발생하기 전까지
< 클래스 변수 - 메서드 영역 -- JVM이 종료될 때까지
그리고 주의 사항!
- 인스턴스를 통해 static 변수에 접근할 수 있지만 사실상 static 변수인 것을 확인하고 메서드 영역으로 접근한다.
-- 최적화의 문제로 바라볼 게 아니라, 코드 읽을 때 마치 인스턴스 변수처럼 오해할 수 있기 때문에 클래스명으로 접근 - 개발할 때 만드는 입장, 가져다 쓰는 입장 둘 다 생각해야 한다. 특히 후자를 고려하여 잘 작성한다.
static 메서드
정적 메서드도 정적 변수처럼 인스턴스 생성 없이 클래스명으로 바로 호출할 수 있다!
- 클래스 메서드는 인스턴스를 생성하지 않고 바로 호출할 수 있다.
- 인스턴스 메서드는 인스턴스를 생성한 후 접근한다.
static 메서드는 static이 붙은 정적 메서드나 정적 변수만 사용할 수 있다. 반대로는 접근 제어자만 허락한다면 클래스를 통해 모든 곳에서 static을 호출할 수 있다.
cf. 정적 메서드는 공용 기능이라는 점 기억하자.
static 메서드에서 인스턴스 변수와 인스턴스 메서드를 접근하지 못하는 이유는, 인스턴스 변수와 메서드는 인스턴스를 생성해야 알 수 있는데 static 메서드 입장에서는 그 객체의 참조값을 모르니 접근하지 못하는 것이다. (매개변수로 전달받지 않는 이상) 대조적으로 인스턴스 메서드는 본인의 인스턴스를 생성한 후 힙 영역의 본인의 인스턴스를 접근하여 사용할 수 있다. 물론 static도!
- 자주 사용하는 static 메서드를 사용할 때는 매번 클래스명을 입력하는 귀찮음이 있으니 import를 통해 그 부담을 해소할 수 있다. ex) import static static2.DecoData.*;
- 정적 메서드는 정적 메서드만 호출할 수 있다.
<- 정적 메서드인 main()이 호출하는 메서드는 다 정적 메서드, 같은 클래스 내부에서 정적 메서드만 호출할 수 있다.
정리:
- 보통 스택 영역에서 힙 영역의 인스턴스 참조값을 참조한다. 메서드 영역(ex. static영역)에서도 가능하다.
- 인스턴스의 메서드를 호출하면 메서드 영역의 클래스로 가서 실행한다기보다는(static은 아니니까) 코드를 불러와서 스택영역에 쌓는다.
- 클래스 속성 작성할 때 인스턴스 변수, 클래스 변수 둘 다 어쨌든 멤버변수라는 것을 유의하며 작성하기!
어서 빨리 파일 다시 봐야지-
--끝--
'inflearn' 카테고리의 다른 글
[인프런] 김영한의 자바 기본 강의 섹션9. 상속 (240112) (0) | 2024.01.12 |
---|---|
[인프런] 김영한의 자바 기본 강의 섹션8. final (240111) (1) | 2024.01.11 |
[인프런] 김영한의 자바 기본 강의 섹션6. 접근 제어자 (240109) (2) | 2024.01.10 |
[인프런] 김영한의 자바 기본 강의 섹션5. 패키지 (240109) (1) | 2024.01.09 |
[인프런] 김영한의 자바 기본 강의 섹션4. 생성자 (240108) (0) | 2024.01.08 |