버그 잡이

[안드로이드 비동기]Java Process, Thread 내부 구조에서 멀티스레딩의 단점까지 본문

안드로이드/멀티 스레딩

[안드로이드 비동기]Java Process, Thread 내부 구조에서 멀티스레딩의 단점까지

버그잡이 2020. 5. 5. 20:09

"안드로이드에서 LongTask한 작업은 새로운 스레드를 만들어서 작업한다."

 

내가 안드로이드 스레드를 공부하면서 느낀 스레드의 핵심 중 하나이다.

 

 

"그렇다면 스레드는 얼마나 만들어서 쓸 수 있는가?" 라는 질문이 생겼다.

 

 

- stackoverflow를 살펴보니 

- "메모리에서 허용하는 만큼, 정확히는 stack 메모리가 허용하는 만큼 만들 수 있다" 는 답변을 보았다.

 

이는 자연스레 "stack은 무엇인가?"라는 질문으로 이어졌고 이를 알기 위해선 Process와 Thread의 내부 구조를 살펴봐야했다.

 

 

 

Process

프로세스란 실행중인 프로그램으로 

메모리 입장에서는 운영체제로부터 시스템 자원을 할당받은 작업의 단위이다.

 

process 는 아래와 같은 구조로 이루어져있다.

 

https://jungwoon.github.io/android/2019/07/16/Process-Thread/

 

 

*Text 영역 : 실행할 프로그램의 코드가 저장되는 영역

*Data 영역 : 전역 변수, static 변수가 할당되는 곳

*Stack 영역 : 매개변수 지역변수 등 임시적인 데이터가 저장되는 곳 (함수 호출과 함께 할당, 함수 소멸시 소멸)

*Heap 영역 : 런타임시 생성. 자바의 'new' 키워드로 생성되는 곳

 

 

 

 

Thread

 

- 스레드는 프로세스에서 실행되는 논리적 흐름이다.

- 즉, 프로세스가 할당받은 자원을 이용한 실행 단위이다.

 

https://jungwoon.github.io/android/2019/07/16/Process-Thread/

 

- 스레드는 프로세스 내에서 각각 stack만 할당받고  Code, Data, Heap은 프로세스 내의 다른 스레드와 공유한다.

 

-> 그렇다. 여기서 멀티 스레딩으로 여러 개의 함수를 실행시키면 stackOverFlow 에러. 그 익숙한 단어가 여기서 발생할 수 있는 것이다.

 

    (멀티스레딩과 stack은 개발자에게 땔 수 없는 존재인 것 같다.)

 

 

[결론]

 

  "그렇다면 스레드는 얼마나 만들어서 쓸 수 있는가?"

 

-> 메모리가 가득 찰때까지.

-> 스레드는 생성될때마다 stack을 할당 받는다. -> 멀티스레딩은 stack 메모리를 점차 채우고 -> 이는 stackOverFlow 에러를 발생시킬 수 있다.

 

 

-----------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

*한걸음 더 나아가 멀티스레딩에 또 다른 단점을 살펴보자

 

 

 

멀티스레딩의 단점

 

멀티스레딩을 통해서 사용자가 접하는 UI 의 반응성을 올림으로써 성능을 개선하는 효과를 거둘 수 있지만

동시에 아래와 같은 단점들도 있다.

 

 

1. 자원 소비 증가

 

스레드는 메모리와 프로세서 사용량 측면에서 오버헤드를 동반한다.

스레드가 생성될때마다 지역변수와 매개변수를 저장하는 stack 메모리가 할당되고 스레드가 종료되면서 해제된다.

프로세서 측면에서는 스레드를 설정 및 해제할 때 오버헤드가 생긴다.

더 많은 스레드가 생길수록 메모리와 프로세서에 더 많은 부담을 주게 된다.

 

 

2. 데이터 불일치 

 

위 구조에서 살펴봤듯이 스레드에서는 공유되는 자원에 접근할 수 있다.

스레드의 순서는 기본적으로 불확정적이기 때문에 동기화 문제가 발생할 수 있다.

 

 

 

3. 메모리 누수

 

스레드는 실행 중에 가비지 컬렉터가 메모리를 회수하는 것을 방해할 수 있으므로 메모리 누수를 일으킬 잠재적 위험을 가지고 있다.

 

 

 

 

 

"그럼 멀티스레딩은 언제, 어떻게 사용해야하는가?"

 

1. 기본적으로, UI의 속도를 저하시킨다면 멀티스레딩을 고려해야한다.

 

 

2. 이와 더불어 책[안드로이드 멀티스레딩]에서는 다음과 같은 테스크 실행 전략을 제시한다.

고립되고 독립적인 테스크는 처리량을 증가시키기 위해 동시 실행할 수 있지만, 순서가 필요하거나 동기화 없이 공통 자원을 공유하는 테스크는 순차 실행해야한다.

 

 

3. 불필요한 스레드를 생성하지 않고 동작이 안료된 스레드는 바로 바로 해제해준다.

 

 

 

 

*진짜 결론

 

1. 멀티스레딩의 단점

   - 멀티스레딩과 stackOverFlow 잊지말자.

   - 메모리 자원을 공유하는 과정에서 동기화 문제가 발생할 수 있다.

   - 제때 해제되지 않은 스레드로 메모리 누수가 발생할 수 있다.

 

 

2. 멀테스레딩은 UI 반응성을 개선하는 좋은 방법이지만 그에 따른 비용을 고려하며 사용해야한다.

 

 

 

 

*참조

- https://jungwoon.github.io/android/2019/07/16/Process-Thread/

- 책[안드로이드 멀티스레딩]

반응형
Comments