개발자는 기록이 답이다

패스트캠퍼스 환급챌린지 3일차 미션 (2월 3일) : Spring Webflux 완전 정복 : 코루틴부터 리액티브 MSA 프로젝트까지 강의 후기 본문

패스트캠퍼스

패스트캠퍼스 환급챌린지 3일차 미션 (2월 3일) : Spring Webflux 완전 정복 : 코루틴부터 리액티브 MSA 프로젝트까지 강의 후기

slow-walker 2024. 2. 3. 21:43

 

1. Java NIO

  • java New Input/Output (non-blocking x)
  • Java 1.4에서 처음 도입
  • 파일과 네트워크에 데이터를 읽고 쓸 수 있는 API 제공
  • buffer 기반 (객체)
  • non-blocking 지원
    • 논블로킹이 아니게도 할 수 있고, 논블로킹을 쓰지 못하는는 API도 있다.
  • selector, channel 도입으로 높은 성능 보장

 

2. Java NIO vs Java IO

 

  Java NIO Java IO
데이터 흐름 양방향 단방향
종류 Channel InputStream, OutputStream
데이터의 단위 buffer byte 혹은 character
blocking 여부 non-blocking지원
(blocking 한 API도 존재)
blocking 만 가능
특이사항 Selector  

 

3. Channel과 Buffer

Channel은 우리가 관심있어하는 리소스(File)와 통신하고 버퍼를 매개체로 사용한다.

  • 데이터를 읽을때 : 적절한 크기의 Buffer를 생성하고 Channel의 read()메서드를 사용하여 데이터를 Buffer에 저장
    • 미리 확보해놓은 버퍼에 채널이 값을 읽어서 채워준다.
  • 데이터를 쓸 때 : 먼저 Buffer에 데이터를 저장하고, Channel의 write()메서드를 사용하여 목적지로 전달
  • clear() 메서드로 초기화하여 다시 사용 가능

 

4. Buffer

버퍼라는 인터페이스를 구현한 다양한 종류가 있다. (단위가 다름)

  • ByteBuffer : byte단위로 데이터를 읽고 쓴다.
  • CharBuffer :  char 단위
  • ShortBuffer : short단위
  • IntBuffer : int 단위
  • LongBuffer : long 단위
  • FloatBuffer : float단위
  • DoubleBuffer : double단위

여러가지 타입의 버퍼가 존재하는 이유는 InputStream/OutputputStream은 바이트를 읽고 쓰고, Reader/Writer는 캐릭터 단위로 값을 읽고 쓸 수 있는 것 처럼, 다양한 타입을 지원함으로써 읽어들여야 하는 별도의 채널이 아니라 버퍼 자체를 타입에 따라 만들어서 값을 저장할 수 있도록 한다.

 

5. Buffer 위치 속성

 

Buffer는 값을 읽고 쓸 수 있다. 그렇기 때문에 위치 속성을 가진다.

 

  • capacity : Buffer가 저장할 수 있는 데이터의 최대 크기. Buffer 생성 시 결정되며 변경 불가
    • 만일 capacity를 1024, 1kb에 해당하는 크기 만큼 잡았다면 그 이후에 버퍼는 아무리 많이 커져도 1kb밖에 값을 저장할 수 없다.
  • position : Buffer에서 현재 위치를 가리킨다. 현재 위치라는건 계속 바뀔 수 있다는 것을 의미
    • 버퍼에서 데이터를 읽거나 쓸때, 해당 위치부터 시작하고, 1 Byte만큼 position을 늘린다.
    • Buffer에 1Byte가 추가될때마다 1증가
  • limt : Buffer에서 데이터를 읽거나 쓸 수 있는 마지막 위치
    • limit이후로 데이터를 읽거나 쓰기 불가. 최초 생성시 capacity와 동일
    • capacity와 다르게 변경 가능하고,
    • limit까지 포지션이 값을 읽거나 쓸 수 있기 때문에 limit을 잘 활용하면 버퍼내에서도 크기를 제한할 수 있다.
  • mark : 현재 position 위치를 mark()로 지정할 수 있고, resest()호출 시 position을 mark로 이동
    • 특정 포지션의 위치를 표시한 것이므로 포지션보다 작거나 크다.
  • 0 <= mark <= poisiotn <= limit <= capacity
  • 각각의 위치속성이라는게 인덱스에 해당하는 값을 표현하기 때문에, capacity는 크기, position과 limit은 위치를 가르킨다.

 

6. Java NIO에서 커널 버퍼에 직접 접근?

 

DirectByteBuffer

 

  • native메모리(off-heap)에 저장
  • 커널 매모리에서 복사를 하지 않으므로 데이터를 읽고 쓰는속도가 빠르다
  • 비용이 많이 드는 system call을 사용하므로 allocate, deallocate가 느리다.
  • allocateDirect()함수로 생성 가능

 

HeapByteBuffer

 

  • JVM heap메모리에 저장. byte array를 랩핑
  • 커널 메모리에서 복사가 일어나므로 데이터를 읽고 쓴느 속도가 느리다
  • 이 과정에서 임시로 Direct Buffer를 만들기때문에 성능저하
  • gc에서 관리가 되므로  allocate, deallocate가 빠르다
  • allocate(), wrap()함수로 생성 가능

DirectByteBuffer인지, HeapByteBuffer인지는  isDirect()로 구분 가능

 


※ 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다. https://bit.ly/48sS29N