티스토리 뷰

IT/개발

IO / NIO

K.Nero 2016. 1. 1. 16:29

자바에서는 IO와 NIO라는 두 종류의 입/출력을 제공하고 있다. IO는 Blocking 입출력이며 NIO는 Non Blocking 입출력이다. 참고로 여기서 입력과 출력을 구분 짓는 것은 자신의 메모리의 외부(파일, 네트워크)에서 메모리로 가져오는 것을 입력, 자신의 메모리에서 외부로 내보내는 것을 출력이라 한다.


* IO

IO에서 Blocking이 되는 부분은 ServerSocket의 accept()와 Socket의 read()가 있다. Blocking이 된다는 것은 이 작업을 수행하는 Thread가 다른 일을 하지 못 하고 호출한 Method가 종료될 때까지 기다려야 한다는 것을 뜻한다. ServerSocket의 accept에서의 Blocking을 극복하기 위해서 보통 IO는 accept의 반환값인 Client와의 Socket을 별도의 Thread를 생성하여 Socket의 read/write를 수행하게 된다. 여기서 Thread의 생성 비용이 발생하는데 이를 다시 극복하기 위해 ThreadPool을 사용하여 Thread를 재활용한다. 하지만 별도의 Thread도 생성하는데 한계가 있으며(계속 생성할 경우 OOM발생) 너무 많은 Thread는 Context Switching으로 인해 CPU의 자원을 낭비하게 된다. 하지만 손쉬운 사용이 장점이다.


* Context Switching

CPU는 한 번에 하나의 일만을 할 수 있다. 사람이 느끼기에는 여러가지 일을 동시에 하고 있는 것으로 보이나 실제로는 시간을 쪼개서 빠르게 여러가지 일을 순차적으로 처리한다. 물론 멀티코어는 코어 수 만큼의 Thread는 실제로 독립적으로 일을 수행한다. CPU가 현재 하던 일을 멈추고 다른 일을 시작할 때는 현재의 일에 대한 정보를 보관하고 다음 수행할 일에 대한 정보를 다시 가져와야하는데 이 작업을 문맥교환(Context Switching)이라고 한다. 이러한 문맥교환을 하는 동안 CPU는 다른 작업을 할 수 없으므로(Blocking) 문맥교환은 오버헤드이다.(Thread의 상태 :  Run, Waiting, Ready, Sleep, Blocked)


* NIO

NIO는 Non Blocking으로 기존 Blocking 되던 Method가 호출하는 즉시 결과를 반환하며 반환되는 값은 현재 원하는 결과의 유무를 반환한다. NIO에서는 Selector를 사용하여 원하는 이벤트(OP_ACCEPT, OP_CONNECT, OP_READ, OP_WRITE)를 등록하고 등록된 이벤트가 발생하면 결과를 반환해 준다.

Iterator<SelectionKey> keys = selector.selectKeys().iterator();

이렇게 Non Blocking과 이벤트를 등록하는 방법을 통해서 하나의 Thread Loop를 통해 4 가지의 이벤트를 처리할 수 있게 된다. 물론 시간이 걸리는 로직(DB접근 등)은 별도의 Thread를 만들어 처리하는게 좋지만 Client를 담당하는 Thread를 생성할 필요는 없어진다. 그리고 nio패키지의 ByteBuffer는 실제 메모리에서 JVM내의 메모리로 값을 가져오는 CPU의 작업없이 바로 메모리에 접근할 수 있게 해준다.

'IT > 개발' 카테고리의 다른 글

Github 에 개인 maven repository 생성하기  (0) 2018.02.14
Garbage Collection  (0) 2017.02.04
Object class  (0) 2017.02.01
Socket Option  (0) 2016.01.02
Java Architecture  (0) 2015.12.16
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함