본문 바로가기
츄Log/네트워크 프로그래밍 끄적

Java NIO (New IO)

by 츄츄🦭 2023. 11. 29.
728x90

안녕하세요! 오늘은 java NIO의 개념을 간단하게 정리해보려고 합니다. 

 

자바 1.4이전의 IO(Old IO로 OIO라고 함)는 운영체제 수준의 시스템콜을 직접 사용할 수 없었습니다.

왜 OIO는 느렸을까요?

 

운영체제 시간에 배운 것처럼 모든 IO는 반드시 커널 영역을 직간접적으로 거쳐야 합니다. 

커널 영역에 저장된 데이터는 JVM의 버퍼로 다시 복사를 해야 합니다.

 

디스크에서 커널 영역의 버퍼로 데이터를 저장하는 것은 디스크 컨트롤러가 DMA라는 기술을 사용하여 CPU의 도움 없이 처리하지만,

커널 영역의 버퍼에서 프로세스 영역의 버퍼로 데이터를 전달하는 것은 CPU를 사용합니다.

또한 디스크에서 커널 영역의 버퍼로 데이터를 복사하는 동안 프로세스는 블록킹됩니다. 

 

이런 문제점으로 시스템콜을 직접 사용할 수 없는 Java의 IO는 다른 저수준 언어에 비해 매우 느렸습니다.

 

NIO(New IO)는 운영체제 수준에서 지원되는 기술들을 사용할 수 있게 만들어서 위에서 말한 문제점을 해결하였고, 많은 성능 향상을 이루어냈습니다.

 

NIO에 추가된 내용은 다음과 같습니다. 

  1. Buffer 클래스 도입
    DirectByteBuffer 한정이지만, 커널에 의해 관리되는 시스템 메모리를 직접 사용할 수 있는 클래스를 도입했습니다. 
  2. 네이티브 IO 서비스를 제공하는 채널 도입
    기존 스트림의 향상된 버전인 Channel을 도입했습니다.
    채널은 단방향 뿐만 아니라 양방향 통신도 지원합니다. 또한 운영체제에서 제공해주는 다양한 네이티브 IO 서비스를 이용할 수 있게 해줍니다. 
    이 채널은 버퍼클래스와 함께 작업하도록 만들어져 있습니다. 채널을 이용해서 시스템 메모리인 버퍼에 직접 데이터를 읽거나 쓸 수 있습니다. 
  3. Selector 도입 
    기존의 자바 네트워크 프로그래밍은 클라이언트마다 하나의 스레드를 할당해야 했기 때문에 사용자가 많아질수록 급격한 성능저하와 메모리에 대한 걱정을 없앨 수 없었습니다.
    하지만 리액터 패턴의 구현체인 셀렉터의 도입으로 multiplexing I/O를 가능하게 했습니다.
    버퍼, 채널과 함께 셀렉터를 사용하면 하나의 스레드로 수만 수천개의 동시 요청을 처리할 수 있습니다.

궁금한게 있으면 댓글 남겨주세요 :) 

728x90