NIO
구분 |
IO |
NIO |
버퍼 |
넌버퍼 |
버퍼 |
비동기 |
지원X |
지원 |
블로킹/넌블로킹 |
블로킹만 지원 |
모두지원 |
스트림과 채널
스트림
- 스트림 기반
- 입력, 출력 스트림으로 구분되어 있다.(둘다생성해야함)
- 버퍼 제공해주는 보조 스트림을 사용해야함
- 이전 게시글 참조..
- read()메소드로 블로킹된다.
- write() 메소드로 데이터 출력 전까지 블로킹된다.
채널
- 양방향으로 입,출력이 가능하다.
- 하나의 파일에서 읽고 저장하는 작업을 모두 해야한다면 FileChannel만 생성하면 된다.
- 스레드 인터럽트로 빠져나올 수 있다.
- 넌블로킹 : 입출력 작업 준비가 완료된 채널만 선택해서 작업 스레드가 처리한다.
- 셀렉터(Selector)가 여러개의 채널 중에서 준비 완료된 채널을 선택하는 방법을 제공함!
선택 기준?
- NIO는 연결 클라이언트 수가 많고, 하나의 입출력 처리작업이 오래 걸리지 않은경우 좋다
- 스레드 입출력 처리가 오래걸리면, 대기 작업 수가 늘어나 제한된 스레드로 처리하는것이 안좋을 수 있음
- IO : 연결 클라이언트 수가 적고, 전송되는 데이터가 대용량이면서 순차적으로 처리될 필요성이 있을 경우에는 IO로 서버 구현하는것이 좋다.
버퍼
구분 |
넌다이렉트 |
다이렉트 |
사용 메모리 |
JVM의 힙 |
운영체제 메모리 |
버퍼 생성 시간 |
빠름 |
느림 |
버퍼 크기 |
작다 |
크다(큰 데이터 처리) |
입출력 성능 |
낮다 |
높다.(입출력 빈번할 때 유리) |
다이렉트버퍼
- 한 번 생성해 놓고 재사용하는 것이 적합하다.
사용
ByteBuffer directBuffer = ByterBuffer.aloocateDirect();
ByteBuffer nonDirectBuffer = ByteBuffer.allocate(용량);
- 다이렉트 버퍼는 채널을 사용해서 버퍼의 데이터를 읽고, 쓸 경우에만 운영체제의 native I/O를 수행한다.
- ByteBuffer의 get()/put()메소드를 사용해서 버퍼의 데이터를 읽고, 저장한다면 이 작업은 내부적으로 JNI를 호출해서 native I/O를 수행하기 때문에 JNI호 호출이라는 오버 헤더가 추가된다.
- JNI : 자바 코드에서 C함수를 호출할 수 있도록 해주는 API이다.