static은 정적이라는 의미를 가진다.
따라서 변수나 메서드앞에 static을 선언하면 "정적 메모리"를 가지고 있다고 생각할 수 있다. 이는 컴파일 시간 동안 할당 된 메모리이며 고정된 공간을 차지하고 런타임 중에 변경할 수 없는 특징을 가지고 있다.
JVM의 메모리구조
Static에 대해서 자세히 공부하려면 메모리의 구조를 알아야한다.
위의사진과 같이 JAVA의 메모리 구조는 Method Area(Static Area), Stack, Heap 으로 구분된다.
Java의 파일은 크게 Field, constructor, method로 구성된다. 그 중 필드 부분에서 선언된 변수(전역 변수)와 정적 멤버변수들이 static영역에 데이터를 저장하게 된다. static 영역의 변수들은 프로그램의 시작부터 컴파일이 종료될 때 까지 메모리에 남아있게 된다.
우리가 작성하던 기본 자료형에 해당되는 지역변수의 데이터 값이 저장되는공간이 Stack영역
이다. 해당 매서드가 호출될 때 메모리에 할당되고 컴파일이 종료되면 메모리가 해제된다. 즉 Stack 영역
은 LIFO(Last in First Out) 형식의 구조를 갖고 변수에 새로운 데이터가 할당되면 이전 데이터는 지워진다.
인스턴스가 생성되는 공간, new연산자에 의해 생성되는 배열과 객체는 모두 여기에 생성된다.
Heap에 저장된 데이터가 더 이상 사용이 불필요하다면 메모리 관리를 위해 JVM(자바 가상머신)에 의해 알아서 해제된다. 이러한 기능을 가비지컬렉션(GC, 쓰레기 수집)이라고 한다.
- static을 무분별하게 사용하면 메모리의 낭비가 심해진다.
- static은 전역에서 접근이 가능하므로 동시성 이슈가 발생해서 별도의 동기화 전략을 수립해야한다.
- 정적필드는 전역으로 관리되기 때문에 프로그램 전체에서 접근하여 수정할 수 있어서 테스트하기 까다롭다.
static은 보통 상수를 정의할 때 많이 사용한다.
또한 매서드 내에서 인스턴스변수를 사용하지 않는다면 static을 붙이는 것을 고려한다.