자바 성능 튜닝 - static By starseat 2024-05-07 16:30:30 java/spring Post Tags [자바 성능 튜닝 이야기](https://product.kyobobook.co.kr/detail/S000001032977) 책을 읽고 정리한 내용 입니다. --- # static **static** 은 '정적인. 음직이지 않는' 이라는 뜻이다. ## 클래스 변수 **static** 으로 선언한 변수를 클래스 변수라고 한다. ```java public class VariableTypes { int val1; static int val2; // ... } ``` 위 코드에서 `val1` 은 '객체 변수' 이고 `val2` 가 '클래스 변수' 이다. ## 초기화 블록 **static** 을 사용하면 **static 초기화 블록** 이란 것이 있다. ```java public class StaticBasicSample { static String staticVal; static { staticVal = "Static Value"; staticVal = TempClass.staticInt + ""; // TempClass 에서 'public static int staticInt = 0;' 으로 선언 됨. } public static void main(String[] args) { System.out.println(StaticBasicSample.staticVal); // Performance is important! 출력 } static { staticVal = "Performance is important!"; } } ``` 위는 사용 예제 이다. **static 초기화 블록** 은 위 코드와 같이 클래스 어느 곳에서나 지정할 수 있다. 다만 클래스가 최초 로딩될 때 수행하므로 생성자 실행과 상관없이 수행되며, 여러번 사용되더라도 순차적으로 읽혀져 마지막에 지정한 값이 된다. **static** 으로 선언하게 되면 *같은 주소에 존재하는 값을 참조하고, GC 의 대상도 되지 않는다.* 여러 쓰레드에서 하나의 static 변수에 접근하게 되면 데이터가 꼬일 수 있는 여지도 있다. # static 잘 활용하기 ## final static 자주 사용하고 절대 변하지 않는 변수는 `final static` 으로 선언해야 된다. (ex. 코드성 데이터) 템플릿 성격의 객체를 static 으로 선언하는 것도 성능 향상이 될 수 있다. ## 설정 파일 정보 설정 파일정보를 클래스의 객체를 생성할 때마다 설정 파일을 로딩하면 엄청난 성능 저하가 발생하게 된다. 이럴 때는 static 으로 데이터를 읽어서 관리해야 된다. ## 코드성 데이터는 한번만 로드 자주 바뀔 확률이 낮은 데이터들을 DB 에서 읽을때 한번만 읽어서 관리하는 것이 성능 측면에서 좋다. (memcached, EhCache 등 캐시(cache)를 사용하는 것도 좋은 방법이다.) # static 잘못 사용 ```java import java.util.HashMap; public class BadQueryMansger { private static String queryURL = null; public BadQueryManager(String url) { queryURL = url; } public static String getSql(String sql) { try { FileReader reader = new FileReader(); HashMap document = reader.read(queryURL); return document.get(sql); } catch(Exception ex) { System.out.println(ex); } return null; } } ``` 얼핏보면 문제가 될게 없어 보이지만 심각한 문제를 가지고 있다. 처음 실행시에는 정상적으로 동작할 것이다. `getSql()`을 호출하면 파일을 읽어야 하므로 성능의 영향을 받을 것이다. 만약 다른 부분에서 `BadQueryMansger` 생성자를 실행 후 `getSql()` 을 호출하게 되면 처음 사용하는 곳에서 오류가 발생될 것이다. 다른 부분에서 설정된 값과 동일한 값으로 세팅 되었기 때문이다. 참고로, 어떤 프로그램이든 파일 IO가 발생하면 느려지게 된다. 파일에 접근하기 위한 IO가 발생하면서 대기하는 IO wait가 발생하기 때문이다. # static 과 메모리 릭 앞에 언급하였듯이 **static 으로 선언한 부분은 GC가 되지 않는다.** 어떤 클래스에 데이터를 `Vector` 나 `ArrayList` 에 담을 때 항상 Collection 객체를 static 으로 선언하게되면 GC가 되지 않아 OutOfMemoryException이 발생한다. 이럴 경우는 시스템을 재시작해야 하며, 해당 인스턴스는 더이상 서비스 할 수 없다. Previous Post 자바 성능 튜닝 - loop (for, while) 성능 향상 Next Post 자바 성능 튜닝 - 클래스 정보