getBytes method of MultipartFile in Java 21 cause out of memory

• Java 17 환경에서 최대 다이렉트 메모리 사이즈를 20MB로 제한한 상태에서 아파치 제이미터로 요청을 보냈을 때, 최대 힙 메모리 사이즈까지 메모리 사용량은 증가했지만 OOM 에러는 발생하지 않았으며, jcmd 도구로 확인한 결과 다이렉트 메모리 사용량이 약 2MB 증가했다.
• Java 21 환경에서 동일한 설정으로 테스트했을 때 대부분의 요청이 OOM 에러로 실패했으며, jcmd 도구로 확인한 결과 다이렉트 메모리 사용량이 약 18MB 증가했고, 최대 다이렉트 메모리 사이즈를 제한하지 않았을 때는 힙 메모리까지 다이렉트 메모리로 사용할 수 있는 것으로 보인다.
• Java 21 버전에서는 `ChannelInputStream` 클래스의 `readAllBytes` 메소드가 새롭게 추가되어, 이전 버전과 다르게 `FileCopyUtils` 클래스가 `ChannelInputStream` 객체를 사용하여 데이터를 읽게 되었으며, 이로 인해 다이렉트 메모리 사용량이 증가하였다.
• `BufferCache` 객체가 `TerminatingThreadLocal` 클래스를 통해 스레드에 저장되고, 서블릿 컨테이너의 스레드 풀에서 스레드가 종료되지 않는 한 메모리 해제가 이루어지지 않아, 요청 처리 시 할당된 버퍼 객체들의 메모리가 애플리케이션 종료 전까지 유지되어 메모리 누수가 발생한다.

북마크
공유하기
신고하기