본문 바로가기

Java

Apache common Pool을 사용한 Object Pool 만들기

Apache common 프로젝트 중 Pool이라는 것이 있습니다.
Object Pool을 개발 할 수 있는데요..
간단한 예제를 만들어보려고 합니다. 

Pool은 풀링 메카니즘을 쉽게 구현 할 수 있도록 해주는 프로젝트입니다.
DBCP도 이것을 활용해서 구현되어있구요..

기본적으로 Pooling 해서 사용 할 클래스를 하나 만들어 보겠습니다. 

  MyPoolableObject

그리고 필요한 것이 
위 클래스의 객체를 생성하여주는 Factory 클래스입니다.


  MyPoolableObjectFactory

위와 같이 두개의 클래스와 Pool에서 제공되는 GenericObjectPool을 사용하면 간단히 테스트 코드를
만들어 볼 수 있습니다.

  TestPool
결과는 아래와 같이 나옵니다.

 MyPoolableObject@ab95e6count : 1



이렇게만 봐서는 제대로 Pooling이 되는지 알기 어렵습니다.

테스트 코드를 조금만 변경하여 보겠습니다.
  TestPool
결과가 아래와 같이 나옵니다.

i : 0
MyPoolableObjectcount : 1
i : 1
MyPoolableObjectcount : 2
i : 2
MyPoolableObjectcount : 3
i : 3
MyPoolableObjectcount : 4
i : 4
MyPoolableObjectcount : 5
i : 5
MyPoolableObjectcount : 6
i : 6
MyPoolableObjectcount : 7
i : 7
MyPoolableObjectcount : 8
i : 8
MyPoolableObjectcount : 9
i : 9
MyPoolableObjectcount : 10  

결과를 보니 제대로 Pooling이 안되는 것 같네요..
Pooling이 되었다면 static으로 선언한 MyPoolableObject의 count가 전부 1이 되어야 할 것 입니다.
단 한번 객체로 만들어 진 이후에는 계속 Pooling이 되어 사용되었을테니까요.. 하지만 위 결과에서는
count가 지속적으로 증가하고 있고 이 이야기는 바로 매번 객체가 새로 생성되었다는 뜻 입니다.

뭐가 문제일까요?

for문을 보면 GenericObjectPool마저 매번 새로 생성하고 있는 것이 보입니다.
Pool자체가 매번 새롭게 생성되기 때문에 Pooling의 대상이 되는 MyPoolableObject도 매번 새롭게 생성되는 것 입니다.
Pool에 넣어두었지만 Pool자체가 새로 만들어지기 때문이죠..
그래서 아래처럼 코드를 수정해보겠습니다.

  TestPool
Pool은 단 한번만 생성하고 for문으로 돌면서 객체를 Pooling합니다.
결과가 잘 나올 것 같습니다만 실제로 돌려보면 결과는 아래와 같이 나옵니다.

i : 0
MyPoolableObjectcount : 1
i : 1
MyPoolableObjectcount : 2
i : 2
MyPoolableObjectcount : 3
i : 3
MyPoolableObjectcount : 4
i : 4
MyPoolableObjectcount : 5
i : 5
MyPoolableObjectcount : 6
i : 6
MyPoolableObjectcount : 7
i : 7
MyPoolableObjectcount : 8

count는 여전히 매번 증가하고 있으며
더군다나 i가 7에서 프로그램이 그대로 lock에 걸려버립니다.
이건 또 무슨일일까요???

코드를 보면 객체를 가져가는 부분은 있지만 (borrowObject)
사용하고 반납하는 부분이 없습니다.
GenericObjectPool에서의 Pooling max 값이 기본으로 8로 되어 있기 때문에
요청이 올 때마다 MyPoolableObject를 생성하였는데, 8개까지만 생성하고 더 이상
넘겨 줄 것이 없기 때문에 (반환을 하지 않았으므로...)
그대로 멈추고 있는 상황인 것 입니다.

실제 프로그램에서는 위 같은 상황이 되면 어딘가에서 객체를 반환 해 줄 때까지
프로그램이 멈춰있게 될 것 입니다.

그래서 코드를 아래와 같이 다시 한번 수정하여 보겠습니다.



TestPool
returnObject를 추가하였고
결과는 아래와 같습니다.

i : 0
MyPoolableObjectcount : 1
i : 1
MyPoolableObjectcount : 1
i : 2
MyPoolableObjectcount : 1
i : 3
MyPoolableObjectcount : 1
i : 4
MyPoolableObjectcount : 1
i : 5
MyPoolableObjectcount : 1
i : 6
MyPoolableObjectcount : 1
i : 7
MyPoolableObjectcount : 1
i : 8
MyPoolableObjectcount : 1
i : 9
MyPoolableObjectcount : 1

아~!!
이제 좀 제대로 되는 것 같네요.

실제로 사용하려면
여러가지 최적화된 설정도 필요하고
GenericObjectPool도 최소한 JVM안에서는 싱글턴으로 구현 되어야 할 것 입니다.