최근 ​잘 돌아가던 톰캣이 갑자기

OutOfMemery를 내뿜으며 종료되는 사건이 비일비재 하게 되어

메모리 누수관리에 대한 심각성을 새삼 깨닫게 되었습니다.

​평소에

"자바는 가비지컬렉터가 있어. 알아서 메모리 반환을 잘해줄거야"

라고 생각하던 ​사람중에 한 사람이었는데

구글 검색 중 여러가지 글들을 보게 되면서

"가비지컬렉터는 ​생각보다 멍청하다"라는 결론을 내리게 되고

소스를 한번 짜봤죠.

자원반납이 얼마나 중요한지...

​우선 소스를 확인해보겠습니다.

예제1)​

public class Test {
    public static void main(String[] args) {
        int total = (int)Runtime.getRuntime().maxMemory();

        
byte[] bytes = new byte[total/2];
        System.out.println(bytes);  

        byte[] bytes2 = new byte[total/2];
        System.out.println(bytes2);  
    }
}

​OOM 을 뱉어내고 종료되는군요.

​이번엔 null 할당을 해보겠습니다.

예제2)

public class Test {

    public static void main(String[] args) {
        int total = (int)Runtime.getRuntime().maxMemory();

        
byte[] bytes = new byte[total/2];
        
System.out.println(bytes);
        bytes = null;

        
byte[] bytes2 = new byte[total/2];
        System.out.println(bytes2);
    }
}

 

 

​OOM이 발생하지 않네요.

​물론 예제1 예제2는 단편적인 예제 소스입니다.

​아래와 같이 메소드 단위로 소스를 구성하면 OOM은 발생하지 않지요.

 

 

예제3)

public class Test {

    public void test() {

        int total = (int)Runtime.getRuntime().maxMemory();
        byte[] bytes = new byte[total/2];
        System.out.println(bytes);
    }

    public static void main(String[] args) {
        Test test = new Test();
  
        test.test();
        test.test();
    }

}

 

이는 아마 메소드 실행이 끝나면 지역변수들의 역할을 끝으로 보고

자원반납이 자동으로 이루어지지 않나 하는 생각을 해봅니다. (당연한가요?)

 

모든 프로그래밍이 예제3 처럼만 구성되어 있다면 좋겠지만

프로그래밍이란건 예측 못하는 상황이 너무 많기 때문에,

많은 자원이 예약된 로직이 시작되기 전에

변수 사용이 끝나면 null할당을 염두에 두어야 할 것입니다.

+ Recent posts