주요글: 도커 시작하기
반응형
IO 스트림에서 출력 버퍼의 크기에 따른 자원 소모와 성능에 미치는 영향을 살펴본다.

출력 버퍼

출력 버퍼의 적당한 크기를 정하는데 생각해 볼 요소에는 다음과 같은 것들을 들 수 있다.

  1. 출력되는 데이터의 평균적인 크기
  2. 출력 버퍼의 보관된 데이터를 내보내는 flush의 타이밍
  3. 출력 버퍼를 위한 메모리 소모
즉, 출력 버퍼의 크기를 구하는데 가장 중요한 요소들은 경우에 따라 다르며, 주어진 조건에 따라 그 차이가 클 수도 있다.

그러나, 여기서는 20글자 (자바는 유니코드를 사용하므로 40 byte) String 객체를 10만번 파일 스트림으로 출력할 때 소모되는 시간과 메모리를 측정하여 보았다. 결과적으로 4메가 바이트의 데이터가 출력 스트림으로 보내진다. flush() 코드를 따로 추가하지 않고, 버퍼가 가득 찼을 때 자동으로 비워지도록 했을 경우 다음과 같은 결과를 얻을 수 있다.


위의 그래프는 버퍼의 크기가 상대적으로 작은 경우에는 버퍼 크기가 메모리나 시간에 큰 영향을 미치는 것을 보여준다. 따라서 지나치게 작은 출력 버퍼는 성능에 나쁜 영향을 줄 수 있다는 것을 보여준다.

그러나, 일정량 이상의 출력 버퍼를 가진 경우의 테스트 결과를 보면 다음과 같은 결과를 보여준다. 그래프에서 메모리 사용량은 거의 0에 가까운 바닥에 붙어서 보이지 않는데, 위의 그래프와 비교를 위해서 Y축의 비율을 그대로 유지하였다.


출력 버퍼의 크기가 어느 정도 충분한 크기에 이르면 자원 소모나 성능에 큰 영향을 미치지 못하는 것을 볼 수 있다. 대체로 512 char (즉, 1024 byte) 이상의 출력 버퍼는 별다른 성능의 차이를 보이지 않는다.

자바의 출력 버퍼의 기본값

자바의 BufferedWriter 클래스는 생성할 때, 버퍼의 크기를 지정해 줄 수 있지만, 버퍼 크기를 지정하지 않을 경우 기본값으로 버퍼가 생성된다. 기본 버퍼의 크기는 규정된 것은 아니지만 8192 char (즉, 16384 byte)이며 BufferedReader 클래스도 같은 크기의 입력 버퍼를 가지고 있다.

바이트 스트림의 입출력 버퍼 역할을 해주는 클래스인 BufferedInputStream 클래스와 BufferedOutputStream 클래스는 조금 다른 크기의 버퍼를 기본 크기로 가지고 있다.

버퍼 크기를 지정해주지 않을 경우 BufferedOutputStream 클래스의 출력 버퍼는 512 byte로 기본 버퍼크기가 규정되어 있으며, BufferedInputStream 클래스의 입력 버퍼는 지정되어 있지는 않지만 보통 2048 byte의 크기를 가지고 있다.

보통 이런 기본 크기의 버퍼들은 일반적인 경우 가장 합리적인 크기이며, 특별히 버퍼의 크기를 조절할 필요가 없다. 또한, 기본 크기의 버퍼들이 테스트 결과와도 잘 일치한다.

입출력 스트림의 성능은 자바가 아닌 운영체계와 밀접한 관련이 있으며, 자바 뿐만이 아니라, C/C++나 그 이외의 언어에서도 512 byte에서 8192 byte 정도의 입출력 버퍼가 유효한 것으로 알려져 있다.

결론

출력 스트림에서 출력 버퍼의 중요성과 버퍼 크기에 따른 자원 소모량과 성능 향상에 미치는 영향에 대하여 1,2부로 나누어 살펴보았다. 1부에서는 출력 버퍼의 유무에 따른 영향과 빈번한 flush 호출에 따른 효과를 살펴보았으며, 2부에서는 출력 버퍼의 크기에 따른 최적화에 대하여 살펴보았다.



본 글의 저작권은 이동훈에 있으며 저작권자의 허락없이 온라인/오프라인으로 본 글을 유보/복사하는 것을 금합니다.

+ Recent posts