활동성을 최대로 높이기
데드락
식사하는 철학자 문제
JVM은 데이터베이스 서버와 같이 데드락 상태를 추적하는 기능 ❌ 데드락은 시스템에 부하가 걸리는 최악의 상황에서 모습을 드러낸다.
락 순서에 의한 데드락
두 개의 스레드가 서로 다른 순서로 동일한 락을 확보하려 할 때 발생 같은 순서로 락을 확보하도록 돼 있다면, 종속성 그래프에 사이클 ❌ > 데드락 ❌ 모든 스레드에서 락을 모두 같은 순서로만 사용한다면 락 순서에 의한 데드락 ❌
동적인 락 순서에 의한 데드락
함수의 인자로 들어온 객체를 대상으로 락을 건다면?
Systen.identityHashCode 등의 메서드를 활용해 락 순서를 고정할 필요가 있다. 인자로 들어오는 객체, 혹은 동기화 객체 순서를 정렬해서 균일한 락 순서를 가지도록 해야한다.
객체 간의 데드락
락을 확보하고 에일리언 매소드를 호출하는지 체크하기
에일리언 메소드 > 정의는 되어있지만 기능이 만들어져 있지 않은 메소드, 내부에서 어떤 동작이 일어날 지 모르는 메소드
오픈 호출
오픈 호출(open call) > 락을 전혀 확보하지 않은 상태에서 메소드를 호출하는 것
오픈 호출을 활용하면, 활동성 분석도 간편
synchronized 블록도 범위를 최대한 줄이기
프로그램 작성할 때 최대한 오픈 호출한다. 데드락 분석이 쉬워진다.
리소스 데드락
필요한 자원을 사용하기 위해 대기하는 과정도 데드락 ⭕️
스레드 부족 데드락, 다른 작업 실행 결과를 사용해야 하는 작업이 있다면, 스레드 소모성 데드락 원인 되기 쉽다.
데드락 방지 및 원인 추적
가능하다면 한 번에 하나의 락만 사용하게 개발 락 사용 순서를 설계 단계부터 고려
데드락 발생 가능성 여부 판단
락의 시간 제한
Lock 클래스 등 명시적 락은 일정 시간 동안 락 확보 못하면 tryLock에서 오류 발생시킬 수 있다.
에러를 받고 재시도하도록 할 수 도 있겠다.
스레드 덤프를 활용한 데드락 분석
그 밖의 활동성 문제점
소모, 놓친 신호, 라이브락
소모(starvation)
스레드가 작업 진행하는 데 꼭 필요한 자원을 영영 할당받지 못하는 경우
자바에서 소모 상황이 발생하는 대부분의 원인
스레드 우선 순위를 적절치 못하게 올리거나 내리는 부분 스레드 우선 순위는 왠만하면 건드리지 말자. 활동성 문제를 일으킬 수 있고, 플랫폼 종속적이 되곤 한다.
락을 확보한 채 종료되지 않는 코드 실행 시 👉 다른 스레드는 해당 락을 영영 가저갈 수 없어 소모 상황 발생
형편 없는 응답성
응답성이 떨어지는 상황
라이브락(livelock)
실패할 수밖에 없는 기능을 계속해서 재시도하는 경우 e.g ) 메시지 전송에 실패했을 때, 해당 트랜젝션을 롤백하고 큐의 맨 뒤에 쌓아두는 애플리케이션에서 발생
회복 불가능한 오류를 회복 가능하다고 판단해 계속 재시도하는 과정에서 나타나는 문제
각 스레드가 다른 스레드 응답에 따라 각자의 상태를 계속 변경하느라 실제 작업은 전혀 못하는 경우에도 발생
임의의 시간 동안 기다리다가 재시도 하는 방법 등으로 해결
Last updated