Java IO 와 동기 blocking + CPU 자원

이번 포스팅에서는 Java IO 를 이용한 Server - Client 의 동작에서

동기 / 비동기, blocking / non-blocking 관점과 CPU 자원 소모를 알아보겠다.

 

 

server side

accept

서버를 구동하면 blocking 되는 첫번째 포인트이다.

클라이언트에서 연결 요청이 올때까지 blocking 된다.

 

read

클라이언트에서 요청 데이터를 보내서 서버 버퍼에 도착할 때까지 blocking 된다.

 

write

서버에서 클라이언트로 보낼 응답 데이터를 서버 OS 네트워크 버퍼에 적재를 완료할 때까지 blocking 된다.

-> accept, read 와 다르게 클라이언트의 시그널을 기다리는 것은 아니다.

 

 

client side

connect

클라이언트가 서버에 연결될 때까지 blocking 된다.

 

read, write

server side 와 동일하다.

 

 

정리

Java IO 를 사용하면

핵심적인(IO) 메서드를 호출 하는 순간,

동기 blocking 으로 동작한다.

 

대표적으로..

Socket clientSocket = serverSocket.accept();

위 코드는 서버에서의 accept 메서드를 호출하는 코드인데

accept 를 호출하는 순간,

커널이 리턴할 때까지 해당 스레드는 blocking 되며

리턴 타입인 clientSocket 으로

요청 데이터를 읽거나 응답 데이터를 쓸 수 있기 때문에 동기이다.

 

 

한계

1. Java IO 에서는...

커널 버퍼를 직접 사용하지 못한다.

 

서버에 요청 데이터가 도착했다고 생각해보자..

Disk(hardware) 에 도착한 값을 DMA (Direct Memory Access) 를 통해

커널 layer 의 버퍼에 값을 복사한다.

-> 이때는 DMA 로 인해 CPU 자원을 소모하지 않는다.

 

하지만, Java IO 에서는 데이터를 송수신하기 위해 유저 layer 의 버퍼를 사용해야한다.

그래서 커널 버퍼의 값을 유저 버퍼(JVM 내부) 로 복사한다.

-> 이때는 CPU 자원을 사용하며,

JVM 내부 메모리 이므로 GC 대상이므로 이 또한 CPU 자원을 소모하게된다.

 

2. Java IO 에서는...

동기 blocking 방식으로 동작한다.

application 에서 IO 메서드를 호출하면 커널이 리턴할 때까지

해당 스레드는 "아무것도 하지 못한다." (다른 작업도 못함)

-> 스레드를 생성하거나 풀에서 꺼내 쓰거나 간에

하나의 스레드가 할당(스레드 관리 자원 낭비) 되어있어야 함은 어쩔 수 없는 것이고,

IO 작업이 완료되어 인터럽트가 발생하면 CPU 가 소모되며 (컨텍스트 스위칭과 비슷하지만 보다 적은 CPU 자원 소모)

인터럽트 처리 이후 스레드 실행가능 상태에 따른 스레드 실행 시 컨텍스트 스위칭이 발생 (CPU 자원 소모)

 

 

'Java' 카테고리의 다른 글

Java NIO 의 Selector  (0) 2023.11.17
Java NIO 와 동기 non-blocking + CPU 자원  (0) 2023.11.15
Java 16 주요 변경점  (0) 2023.05.20
Java 11 ~ 15 주요 변경점  (0) 2023.05.19
Java 9, 10 주요 변경점  (0) 2023.05.19