Item 6 : 불필요한 객체 생성을 피하라
기본적으로 자바에서 객체의 낭비를 피하는 것이 일반적이다. 가장 큰 예시가 String이다. 생성자를 통해 객체를 생성하지 않는 이상 같은 문자 리터럴에 대해서 같은 머신에 대해 같은 객체를 사용한다.
사용하는 경우는 다음과 같다.
1. 불변 객체 (예 : String)
2. 불변 객체가 아니더라도 프로그램 도중 변경되지 않을 객체
3. 어댑터 (예 : Map의 keySet)
Spring에 적용
그렇다면 Spring 프로젝트에는 어떻게 적용이 가능할까? 첫번째 예시인 불변객체는 기본적으로 해당 객체가 불변객체인지 아닌지 확인 후 그대로 사용하면 된다. 또한 세번째 예시도 마찬가지로 적용이 가능하다.
두번째 예시인 프로그램 도중 변경되지 않을 객체가 프로그램 중간에 있다면 만들어놓고 사용한다.
예시
해당 코드는 sample 객체를 만들어놓고 그대로 사용한다.
장점 : 속도가 향상되며 코드가 명확해지고 이름이 주어지기에 존재가 명확히 표현된다.
단점 : 사용이 안된다면 낭비이고 Lazy Initialization 또한 효과가 미미하다.
public class MemberDTO {
private static final MemberDTO sample = MemberDTO.builder().userId("id").userPwd("pwd")
.userName("name").userNumber("number").userAddress("address").userEmail("email").build();
@NotNull
private String userId;
@NotNull
private String userPwd;
@NotNull
private String userName;
@NotNull
private String userNumber;
@NotNull
private String userAddress;
@NotNull
private String userEmail;
public static MemberDTO sample() {
return sample;
}
}
오토박싱을 피하라.
또한, 책에서는 오토박싱을 피하라고 설명한다. 예를 들어, Long 타입에 long을 계속 더하는 일을 의미한다. 이러한 경우, 객체를 계속 생성하기에 시간이 굉장히 오래걸리게 된다.
Item 7 : 다 쓴 객체 참조를 해제하자.
기본적으로 자바는 가비지 컬렉터가 있어 다른 언어들에 비해 다 쓴 객체에 대한 처리에 대한 걱정이 적다. 하지만 가비지 컬렉터가 해당 경우를 놓치는 경우가 존재하고 이는 메모리 누수 문제로 연결된다.
메모리 누수의 원인
1. 객체를 담고 삭제할 때 실제 null처리를 통한 참조해제가 아닌 가리키는 인덱스만 변화를 주는 경우
2. 캐시
3. 리스너와 콜백
위의 경우를 주의하고 메모리 누수를 대비해 참조를 해제해야 한다. 하지만 기본적으로 Stack 등은 메모리 누수를 대비해 원소 삭제시 참조해제를 처리한다. 주의할 점은 캐시인데, 책에서는 참조를 해제해야할 경우가 많은 경우 WeakHashMap과 같은 것을 사용하는 것을 권장한다.
Spring에 적용
기본적으로 Spring은 멀티스레드 환경이기 때문에 이러한 문제가 적다. 한 사용자가 사용한 객체들에 대해 굳이 모두 삭제해줄 필요가 없다. 하지만 이런 메모리 누수는 큰 문제를 일으키기에 항상 주의해야하고 의심해야한다.
Item 8 : finalizer와 cleaner의 사용을 피하자
Item 9 : try-finally 보다는 try-with-resources를 사용하라.
책에서는 객체 수거에 대해서 finalizer와 cleaner는 여러 문제들이 존재하고 객체 회수에 대해서는 가비지 컬렉터가 비메모리 자원을 회수하는 것에 대해서는 try-with-resources 가 담당하므로 굳이 위의 두 경우를 사용할 필요가 없다고 설명한다.
또한, try-finally를 사용하는 경우 자원이 두개 이상인 경우 코드가 지저분해지고 close 메서드를 제대로 사용하는 경우가 적어지므로 이를 피하라고 설명한다.
Spring에서 적용
책에서는 파일 처리, 네트워크 연결, 데이터 베이스 연결 등에서 try-with-resources를 사용하라고 권고 한다. 하지만, 현재 프로젝트에서는 데이터 베이스 연결이나 네트워크 연결에 대해서 Spring에 전적으로 맡기는 구조이기에 적용할 경우를 찾지 못했다.
또한, 파일 처리 부분에 대해서 현재 사용자의 사진 데이터를 컴퓨터에 저장해 사용하는 구조를 취하고 있는데, File 또는 Path 클래스를 사용한다. 이 클래스들은 close를 해줄 필요가 없고 try-with-resources도 사용할 필요가 없다.
하지만 FileInputStream과 같은 클래스에서는 필요하므로 해당 경우를 알고 사용에 주의하는 것이 필요할 것 같다.
'Trouble Shooting > Spring' 카테고리의 다른 글
Effective JAVA를 Spring 프로젝트에 적용해보자 (Item 10~14) (1) | 2023.10.04 |
---|---|
Effective JAVA를 Spring 프로젝트에 적용해보자 (Item 1~5) (0) | 2023.09.27 |