본문 바로가기
C++ 200제/코딩 IT 정보

자바 스레드 Thread 문제점 3가지, 사이클, 자원 낭비, 안전성 문제

by vicddory 2017. 9. 26.

자바 스레드 Thread 문제점 3가지, 사이클, 자원 낭비, 안전성 문제


자바 스레드, 많이 생성했을 때 문제점[자바 스레드 Thread 문제점 3가지, 사이클, 자원 낭비, 안전성 문제]


작업마다 자바 스레드를 생성하는 정책은 상용 서비스에서 사용하기에는 무리가 있다. 왜냐하면, 특정 상황에서 엄청나게 많은 대량의 자바 스레드가 생성될 수도 있는데, 이럴 때는 아래와 같은 단점이 발생한다.


Java Thread 라이브 사이클 문제


자바 스레드를 생성하고 제거하는 작업에도 자원이 소모된다. Java Thread를 생성하고 제거하는 데 실제로 얼마만큼의 자원을 소모하는지는 운영체제에 따라 다르지만, 어쨌거나 자바 스레드를 생성하는 과정에는 일정량의 시간이 필요하다.


따라서 클라이언트의 요청을 처리할 때 기본적인 딜레이가 생기고, 그동안 JVM과 운영체제는 몇 가지 기초적인 작업을 진행한다. 만약 클라이언트의 요청 내용이 간단하면서 자주 발생하는 유형이라면 요청이 들어올 때마다 매번 새로운 자바 스레드를 생성하는 일이 상대적으로 전체 작업에서 많은 부분을 차지할 수 있다.


자원 낭비


실행 중인 Java Thread는 시스템의 자원, 특히 메모리를 소모한다. 하드웨어에 실제로 장착된 프로세서보다 많은 수의 Java Thread가 만들어져 동작 중이라면, 실제로는 대부분의 자바 스레드가 대기(idle) 상태에 머무른다.


이렇게 대기 상태에 머무르는 Java Thread가 많아지면 많아질수록 많은 메모리가 필요하며, JVM의 가바지 콜렉터에 가해지는 부하가 늘어날 뿐만 아니라 CPU를 사용하기 위해 여러 자바 스레드가 경쟁하는 모양이 되기 때문에 메모리 이외에도 많은 자원을 소모한다.


만약 시스템에 꽂혀있는 CPU의 개수에 해당하는 세레드가 동작 중이라면, Java Thread를 더 만들어 낸다 해도 성능이 직접 개선되지 않을 수 있으며 오히려 악영향을 미칠 가능성도 있다.


자바 스레드 java thread[자바 스레드 Thread 문제점 3가지, 사이클, 자원 낭비, 안전성 문제]


안전성 문제


모든 시스템에는 생성할 수 있는 Java Thread의 개수가 제한되어 있다. 몇 개까지 만들 수 있는지는 플랫폼과 운영체제마다 다르고, JVM을 실행할 때 지정하는 인자나 Thread 클래스에 필요한 스택의 크기에 따라서 달라지기도 한다


자바 스레드 32비트 시스템

32비트 시스템이라면 가장 큰 제약 요소는 바로 자바 스레드 스택에 적용되는 주소 공간이다. 자바 코드와 네이티브 코드를 실행할 수 있도록 모든 Java Thread는 두 개의 스택을 갖는다.


일반적인 JVM의 기본값으로 보면 두 개의 스택을 더한 용량이 대략 0.5MB 정도 된다. 이 값은 JVM을 실행할 때 -Xss 옵션을 지정하거나 Thread 클래스를 생성할 때 생성 메소드에 지정하는 값으로 변경할 수 있다.


예를 들어 자바 스레드별 스택 크기를 2의 32승으로 나눈 값으로 설정하면, 수천 개나 수만 개의 Java Thread를 사용할 수 있다. 운영체제 등에서 제한하는 여러 가지 제약 조건은 훨씬 엄격하게 적용될 수 있다.


만약 제한된 양을 모두 사용하고 나면 아마도 OutOfMemoryError가 발생한다.


이처럼 OutOfMemoryError가 발생한 상황에서 해당하는 오류를 바로잡을 방법은 별로 없으며, 가능하다해도 안정적으로 처리하기가 어렵다. 결국 프로그램이 제한된 값 안에서 동작하도록 작성해 OutOfMemoryError가 발생하지 않도록 미리 방지하는 방법이 훨씬 쉽다.


일정한 수준까지는 Java Thread를 추가로 만들어 사용해서 성능상의 이점을 얻을 수 있지만, 특정 수준을 넘어간다면 성능이 떨어지게 마련이다. 더군다나자바 Java Thread 하나를 계속해서 생성한다면 애플리케이션이 제대로 다운되는 모습의 보게 될 것이다.


이런 위험한 상황에서 벗어나고자 한다면 애플리케이션이 만들어 낼 수 있는 Java Thread의 수에 제한을 두는 것이 현명한 방법이고, 애플리케이션이 제한된 수의 Java Thread만으로 동작할 때 용량에 넘치는 요청이 들어오는 상황에서도 자원이 고갈되어 멈추는 경우가 발생하지 않는지를 세심하게 테스트해야 한다.


이런 측면에서 볼 때 작업별로 자바 스레드를 생성하는 방법은 Java Thread의 개수를 제한할 방법이 전혀 없었다.


물론 클라이언트가 HTTP 요청을 천천히 하면 되긴 하지만, 그건 방법이라고 할 수 없다.


자바 thread[자바 스레드 Thread 문제점 3가지, 사이클, 자원 낭비, 안전성 문제]


대부분의 병렬 프로그램에서 발생하는 문제점이 그런 것처럼 자바 스레드를 제한 없이 생성할 수 있다 하더라도 애플리케이션의 프로토타입을 만들거나 실제 개발하는 과정에서도 문제가 없을 수 있다.


이런 Java Thread 문제는 실제 상황에서 엄청난 부하가 가해졌을 때만 발생하기 때문이다. 따라서 악의적인 사용자뿐만 아니라 일반적이라고 생각할 수 있는 사용자도 요청량을 늘려서 특정 수준이 넘어가도록 하면 웹서버를 다운시킬 수 있다.


항상 높은 가용성을 유지하고 부하가 걸리는 상황에서도 성능이 점진적으로 떨어지도록 만들어야 할 서버 애플리케이션에서 위와 같은 문제가 발생한다면 굉장히 치명적인 오류라고 볼 수 있다.


출처, 자바 병렬 프로그래밍, 강철구, 179p

자바 스레드 Thread 문제점 3가지, 사이클, 자원 낭비, 안전성 문제

댓글