자바 프로그래밍에서 성능을 향상시키는 방법 중 하나는 static을 사용하는 것이다.
그러나 잘 모르고 사용하면 더 느려지거나 오류가 발생할 수 있다.
static의 특징
자바에서 static으로 지정한 것은 해당 메서드나 변수가 정적이라는 의미다.
static으로 선언한 변수 = 클래스 변수
-
하나의 JVM이나 WAS 인스턴스에서 동일한 주소 값을 참조한다.
-
GC의 대상이 되지 않는다.
static 잘 활용하기
(1) 자주 사용하고 절대 변하지 않는 변수는 final static
으로 선언하자.
자주 변경되지 않고, 경우의 수가 단순한 쿼리 문장이 있다면 final static이나 static으로 선언하여 사용하자.
(2) 설정 파일 정보도 static으로 관리하자.
클래스의 객체를 생성할 때마다 설정 파일을 로딩하면 엄청난 성능 저하가 발생하게 된다.
이럴 때는 반드시 static으로 데이터를 읽어서 관리해야 한다.
(3) 코드성 데이터는 DB에서 한 번만 읽자.
부서가 적은 회사의 코드나, 건수가 그리 많지 않되 조회 빈도가 높은 코드성 데이터는
DB에서 한 번만 읽어서 관리하는 것이 성능 측면에서 좋다.
만약 코드가 수정되었을 때는 updateCodes()
같은 메소드를 호출해서 코드 정보를 다시 읽으면 된다.
그런데 만약 서버 인스턴스가 하나만 있다면 코드가 변경되는 것을 걱정하지 않아도 된다.
하지만 서로 다른 JVM에 올라가 있는 코드 정보는 수정된 코드와 상이하므로 그 부분에 대한 대책을 마련해 놓아야 한다.
이러한 JVM 간에 상이한 결과가 나오는 것을 방지하기 위해서 요즘에는 mem-cached, EhCache 등의 캐시를 많이 사용한다.
static을 잘 못 사용한 경우
(1) 쿼리 관리용 클래스에서 사용한 static String queryURL = ...;
여러 화면에서 호출하는 경우 queryURL이 그때 그때 바뀌게 된다.
모든 스레드에서 동일한 주소를 가리키게 되어 문제가 발생한다.
(2) private static boolean successFlag;
성공 여부를 담기 위해 successFlag를 만들었다.
개발자 PC에서 테스트 하거나 성능, 통합 테스트를 할 때 문제점을 발견하지 못할 수도 있다.
수십명이 동시에 정보 확인을 위해 위 서블릿을 호출하면
다른 사용자에 의해 나의 정보가 바뀔 수 있다.
static과 메모리 릭
static으로 선언한 부분은 GC가 되지 않는다.
그럼 만약 어떤 클래스에 데이터를 Vector나 ArrayList에 담을 때
해당 Collection 객체를 static으로 선언하면 어떻게 될까?
만약 지속적으로 해당 객체에 데이터가 쌓이는데 GC가 되지 않으면 시스템은 OutOfMemoryError를 발생시킨다.
이렇게되면 시스템을 재시작해야 하고 해당 인스턴스는 더 이상 서비스할 수 없다.
더 이상 사용 가능한 메모리가 없어지는 현상을 메모리 릭(Memory Leak)이라고 하는데, static과 Collection 객체를 잘못 사용하면 메모리 릭이 발생한다.