Notice
Recent Posts
Recent Comments
Link
개발자는 기록이 답이다
패스트캠퍼스 환급챌린지 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