Static이란?
- '고정된'이란 의미를 가지고 있으며, 프로그램 시작 시 클래스 로더가 메소드 또는 힙 영역에 클래스 메타 데이터 및 정적 변수 등을 적재 함
Static 멤버 저장 위치
Java 8 이전 vs 이후
-
Java 8 이전의 힙을 보면, Permanent 영역이 존재하고 이 안에 클래스 메타 데이터, 정적 변수 등이 저장된다. 이때, Permanent 영역은 메소드 영역에 해당하므로 Java 8 이전 static 변수는 메소드 영역에 저장되는 것이 맞다
-
JDK 8의 레퍼런스를 살펴 보자면, Permanent 영역에서 관리하던 클래스 메타 데이터는 Metaspace로 옮겨지고 interned String과 클래스 정적 변수는 힙 영역에 옮겨진다는 사실을 알 수 있다. 즉, java 8 이후부터 static을 힙 영역에서 관리하게 된다.
Static 사용 단점
- 메모리 문제
- static은 프로그램 실행 시점에 메모리에 할당을 하며, 웬만하면 프로그램 종료 시점까지 메모리에서 해제되지 않는다.
- 동시성 이슈 문제
- static은 전역에서 접근이 가능하므로 별도의 동기화 전략을 수립해야 한다.
- 런타임 다형성 불가
- static으로만 이루어진 메소드를 사용하는 객체의 경우, 해당 객체를 메모리로 할당하여 사용하는 것이 아니고 객체.메소드로 바로 접근하여 호출한다.
- 객체의 상태를 이용할 수 없다
- 정적 메소드를 사용하기 위해서는 필요로 하는 인자를 모두 외부에서 주입해야 한다. 정적 메소드 안에는 클래스의 인스턴스 필드를 사용할 수 없기 때문이다.
- static은 프로그램 시점에 메모리에 올라가는데, 정적 메소드 안에 객체의 인스턴스 필드가 초기화되지 않았다면 문제가 생길 수 있다. 그래서 정적 메소드 안에는 정적 변수만 사용할 수 있다.
- 일반 메소드라면 객체 내의 있는 상태를 통해 해당 메소드를 구현해 줄 수 있으므로 변화하는 상태에 따라 다채로운 기능 구현이 가능하다.
- 결국 객체 내의 정적 메소드가 많아지면, 외부 값에 의존하는 수동적인 객체가 되어 버린다.
- 테스트하기 어려움
- 정적 필드는 전역으로 관리되기 때문에 프로그램 전체에서 이 필드에 접근하고 수정할 수 있다. 따라서 해당 필드를 추론하기 어려워 테스트하기 까다롭다.
Static을 사용하는 경우
- 상수 정의
- 절대 변하지 않는 값으로, Static으로 정의하여 놓으면 메모리를 아낄 수 있음
- 유틸리티 클래스 정의
- 유틸리티 클래스는, 인스턴스 메소드와 인스턴스 변수를 제공하지 않고, 데이터 처리를 위한 정적 메소드만 존재하는 클래스
- 애초부터 객체의 상태를 이용할 생각이 없고, 여러 객체들의 필요에 의해 데이터를 처리하는 공통 로직이 필요할 때는 static을 사용하여 설계한다.
참고 출처 https://steady-coding.tistory.com/603