๐Ÿ–Œ๏ธ [Flutter] Isolate๋Š” ๋ฌด์—‡์ธ๊ฐ€ ?

Tygerยท2024๋…„ 9์›” 5์ผ
3

Flutter

๋ชฉ๋ก ๋ณด๊ธฐ
63/64
post-thumbnail

๐Ÿ–Œ๏ธ Isolate๋Š” ๋ฌด์—‡์ธ๊ฐ€ ?

Concurrency and isolates | Flutter
Concurrency | Dart

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Isolate์— ๋Œ€ํ•ด์„œ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

Flutter๋กœ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ณด๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋“ฃ๊ฑฐ๋‚˜ ์ฐพ์•„๋ณด๊ฒŒ ๋˜๋Š” ๊ธฐ๋Šฅ์ด ๋ฐ”๋กœ Isolate ๊ธฐ๋Šฅ์ผ ๊ฒƒ์ด๋‹ค.

Isolate๊ฐ€ ๋ฌด์—‡์ด๋ฉฐ, ์™œ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์ธ์ง€, ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€, ์–ด๋–ค ๋‹จ์ ๋“ค์ด ์žˆ๋Š”์ง€์— ๋Œ€ํ•ด์„œ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณด๋ฉฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๊ธ€์„ ์ž‘์„ฑํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

Isolate ?

๋จผ์ € Isolate๋Š” ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

Isolate๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด Dart ๊ณต์‹๋ฌธ์„œ์—์„œ ๋‚ด์šฉ์„ ํ™•์ธํ•ด๋ณด์•˜๋‹ค.

Isolate๋Š” Dart ํ”„๋กœ๊ทธ๋žจ์—์„œ ์‹คํ–‰๋˜๋Š” ๊ณ ์œ ํ•œ ์ž‘์—… ๋‹จ์œ„์ž…๋‹ˆ๋‹ค. ๊ฐ Isolate๋Š” ์ž์‹ ๋งŒ์˜ ๋ฉ”๋ชจ๋ฆฌ์™€ ์‹คํ–‰ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ Isolate์™€ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ฐ˜์ ์ธ ์Šค๋ ˆ๋“œ ๋ชจ๋ธ๊ณผ ๊ตฌ๋ณ„๋˜๋Š” ์ ์ž…๋‹ˆ๋‹ค.
Isolate ๊ฐ„ ํ†ต์‹ ์€ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ๊ฐ์˜ Isolate๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฉ”์ธ Isolate๋Š” Flutter ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฃผ UI ์Šค๋ ˆ๋“œ์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ๊ณ„์‚ฐ์ด๋‚˜ ํŒŒ์ผ I/O ์ž‘์—…์ด ๋ฉ”์ธ Isolate์—์„œ ์‹คํ–‰๋˜๋ฉด UI๊ฐ€ ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ๋‹ค๋ฅธ Isolate๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์ด ๊ณต์‹๋ฌธ์„œ์—์„œ ์„ค๋ช…ํ•˜๊ณ  ์žˆ๋Š” ๋‚ด์šฉ์ธ๋ฐ, Isolate์— ๋Œ€ํ•œ ๊ฐœ๋…์„ ์ฒ˜์Œ ์ ‘ํ•œ๋‹ค๋ฉด ๋‹น์—ฐํžˆ ํ•œ ๋ฒˆ์— ์ดํ•ด๋Š” ์•ˆ๋˜์‹ค๊ฑฐ๋ผ ์ƒ๊ฐํ•œ๋‹ค.

Isolate๊ฐ€ ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด์„œ ์ข€ ๋” ํ’€์–ด์„œ ์ •์˜ํ•ด ๋ณด์ž๋ฉด, Isolate๋Š” Flutter, Dart์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ผ์ข…์˜ ๋…๋ฆฝ๋œ ์‹คํ–‰ ๋‹จ์œ„์˜ ๊ฐœ๋…์ด๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•ด์„œ ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ ๋ณ„๋„์˜ ๋ฉ”๋ชจ๋ฆฌ(Memory) ๊ณต๊ฐ„๊ณผ ์Šค๋ ˆ๋“œ(Thread)๋ฅผ ๊ฐ€์ง€๋Š” ๋…๋ฆฝ์ ์ธ ์‹คํ–‰ ํ™˜๊ฒฝ์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
๋ณ„๋„์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์—์„œ ์‹คํ–‰๋˜๋Š” ํ™˜๊ฒฝ์ด๋ฏ€๋กœ ๋‹น์—ฐํžˆ Isolate ๊ฐ„์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š๊ฒŒ ๋˜๋ฉฐ, ํ†ต์‹ ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€์˜ ์„ค๋ช…์„ ๋ณด๋ฉด ๊ตฌ์กฐ๊ฐ€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ๊ณผ ์œ ์‚ฌํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์–ด ๊ฐ„ํ˜น Isolate๋ฅผ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋กœ ์„ค๋ช…ํ•˜๋Š” ๊ธ€๋“ค์ด ์žˆ๋Š”๋ฐ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์˜ ๋ณต์žก์„ฑ๊ณผ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๋ฉด์„œ๋„ ๋ณด๋‹ค ์•ˆ์ „ํ•œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์˜ ์ด์ ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์ด ์ฐจ์ด์ ์ด๋ผ ๋ณด์‹œ๋ฉด ๋œ๋‹ค.

์™œ ํ•„์š”ํ•œ๊ฐ€ ?

Isolate์— ๋Œ€ํ•œ ๊ฐœ๋…์ด ๋ช…ํ™•ํžˆ ์žกํžˆ์ง€ ์•Š์•˜๋”๋ผ๋„ ์•„์ง์€ ์ „ํ˜€ ๋ฌธ์ œ๋  ๊ฒƒ์ด ์—†๊ธฐ์— ์ฒœ์ฒœํžˆ ์ดํ•ดํ•˜๋ฉด์„œ ๋‹ค์Œ ๋‚ด์šฉ๋“ค์„ ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ž.

Isolate๊ฐ€ ๋ฌด์Šจ ๊ธฐ๋Šฅ์ธ์ง€๋Š” ์•Œ๊ฒ ๋Š”๋ฐ, ๋„๋Œ€์ฒด ์™œ ํ•„์š”ํ• ๊ฑธ๊นŒ ?

์ด ๋ถ€๋ถ„์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Flutter, Dart์˜ ์ž‘์—… ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Flutter๋Š” Dart ์–ธ์–ด๋กœ ๊ฐœ๋ฐœ๋˜์–ด์ง„ ํ”„๋ ˆ์ž„์›Œํฌ๋ผ๋Š” ๋ถ€๋ถ„์€ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ์„ ๋‚ด์šฉ์ด๊ณ , ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ(Single-threaded) ํ™˜๊ฒฝ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค๋Š” ๊ฒƒ๋„ ๋Œ€๋ถ€๋ถ„์˜ Flutter ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ์•„๋Š” ๋‚ด์šฉ์ด๋‹ค.

์ฆ‰, ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜์–ด ์ง€๊ธฐ์— ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread) ๋˜๋Š” UI ์Šค๋ ˆ๋“œ(UI Thread)๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ด๋ฒคํŠธ ๋ฃจํ”„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ํ•ด๋‹น ์ž‘์—…์˜ ์ฝœ๋ฐฑ์„ ์‹คํ–‰์‹œํ‚ค๋ฉฐ, UI ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•œ ๋žœ๋”๋ง ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค.

ํ•œ ๊ฐœ์˜ ๋‹จ์ผ ์Šค๋ ˆ๋“œ๊ฐ€ ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž ํ–‰๋™์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ณต์žกํ•œ ์—ฐ์‚ฐ๋„ ์‹คํ–‰ํ•œ๋‹ค๊ณ  ์‰ฝ๊ฒŒ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ดํ•ด๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

๋งŒ์ผ ์‹คํ–‰์ด ์ง€์—ฐ๋˜๊ฑฐ๋‚˜ ํฐ ์ž‘์—…์ด ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด UI๊ฐ€ ๋ฒ„๋ฒ…์ด๋Š”(Jank) ์น˜๋ช…์ ์ธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ฒŒ๋œ๋‹ค.

๊ณผ์—ฐ ์–ผ๋งˆ๋งŒ์˜ ์‹œ๊ฐ„์— ์ž‘์—…์ด ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๊ฑธ๊นŒ ?

Flutter๋Š” 60ํ”„๋ ˆ์ž„(์ตœ๋Œ€ 120ํ”„๋ ˆ์ž„)์—์„œ ์ตœ์ ์˜ ํผํฌ๋จผ์Šค๋ฅผ ๋ชฉํ‘œ๋กœ ํ•˜๋Š”๋ฐ, ํ•ด๋‹น ํ”„๋ ˆ์ž„์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ 16ms๋งˆ๋‹ค UI๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ ธ์žˆ๋‹ค.
๋งค ์ดˆ 60ํ”„๋ ˆ์ž„์ด ๋žœ๋”๋ง ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ •ํ™•ํžˆ๋Š” 16.67ms ๋‚ด์— ๋žœ๋”๋ง์ด ๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด๊ณ , 120ํ”„๋ ˆ์ž„์ธ ๊ฒฝ์šฐ๋Š” 8.33ms ๋‚ด์— ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜์–ด์•ผ ์ตœ์ ์˜ UI ํผํฌ๋จผ์Šค๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

ํ™”๋ฉด ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•ด๋‹น ๊ธฐ์ค€์„ ๋„˜์–ด์„œ๊ฒŒ ๋˜๋ฉด ํ™”๋ฉด ์ง€์—ฐ(Jank)์ด ๋ฐœ์ƒํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ข‹์ง€ ์•Š์€ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ฒŒ ๋˜๋ฉฐ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ์‚ฌ์ „์— ํ•ด๊ฒฐํ•˜์—ฌ ์ตœ์ ์˜ ํผํฌ๋จผ์Šค๋ฅผ ๋ฐœํœ˜ํ•˜๊ธฐ ์œ„ํ•ด CPU ์ง‘์•ฝ์ ์ธ ์ž‘์—…์ด๋‚˜ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋“ฑ์˜ ๋ณต์žกํ•˜๊ณ  ๋ฌด๊ฑฐ์šด ์ž‘์—…์„ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread)์™€ ๋ณ„๋„์˜ ๋…๋ฆฝ์ ์ธ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•˜์—ฌ Jank๋ฅผ ์ค„์ด๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‘๋‹ต์„ฑ์„ ์œ ์ง€ํ•˜๋Š”๋ฐ Isolate ๊ฐœ๋…์ด ํ•„์š”ํ•œ ๊ฒƒ์ด๋‹ค.

์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ๊ฐ€ ?

Isolate์™€ ์ผ๋ฐ˜์ ์ธ ์ž‘์—…์€ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ์ง€๋ฅผ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋กœ ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ž.

์˜ˆ์ œ๋Š” ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ์ธ๋ฐ, CPU ์ง‘์•ฝ์ ์ธ ๋ฌธ์ œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์žˆ์–ด UI๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ˜์‘ํ•˜๋Š”์ง€๋ฅผ ๋น„๊ตํ•œ ์˜ˆ์ œ์ด๋‹ค.

๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•œ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•ด์ฃผ๋Š” ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ์ธ๋ฐ, ์ด ๋•Œ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „๊นŒ์ง€ ๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ๋ฅผ ๋…ธ์ถœ์‹œ์ผœ UI์˜ ์ฐจ์ด์ ์„ ๋‹จ๋ฒˆ์— ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค.

while (index < 10000000000) {
	index++;
}

Nomal ์ž‘๋™ ๋ฐฉ์‹์—๋Š” UI๊ฐ€ ๋ฉˆ์ถ”๋Š” ํ˜„์ƒ(์ฆ‰์‹œ ์ž‘๋™ํ•˜๋ฉด ๋กœ๋”ฉ ์ธํ‹ฐ์ผ€์ดํ„ฐ๊ฐ€ ์•ˆ๋ณด์ž„;)์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚ด ์ฃผ๊ธฐ ์œ„ํ•ด์„œ 1์ดˆ์˜ ๋”œ๋ ˆ์ด ํ›„ ์ž‘๋™ํ•˜๋„๋ก ํ•˜์˜€๊ณ , Isolate ๋ฐฉ์‹์€ UI๊ฐ€ ๋ฉˆ์ถ”์ง€ ์•Š๊ธฐ์— ์ฆ‰์‹œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜์˜€๋‹ค.

Nomal Isolate

๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด์„œ๋„ Isolate ๊ธฐ๋Šฅ์˜ ์žฅ์ ์„ ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

๊ธฐ๋Šฅ์€ ๋‹จ์ˆœํ•˜๋”๋ผ๋„ 100์–ต ๋ฒˆ์˜ ๋ฐ˜๋ณต๋ฌธ์ด ์ž‘๋™๋˜๊ธฐ์— ์ž‘์—…์„ ์™„๋ฃŒํ•˜๊ธฐ ๊นŒ์ง€๋Š” ๋งค์šฐ ๊ธด ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค.

๋‹ค๋ฅธ ์˜ˆ์ œ๋ฅผ ๋ณด๋„๋ก ํ•˜์ž.

์ด๋ฒˆ ์˜ˆ์ œ๋Š” ์œ„์—์„œ ์‚ฌ์šฉํ•œ ์˜ˆ์ œ์™€ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ์ด์ง€๋งŒ UI๊ฐ€ ๋ฉˆ์ถ”๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒ ํ–ˆ์„ ๋•Œ์— ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€๋ฅผ ๋น„๊ตํ•œ ์˜ˆ์ œ์ด๋‹ค.

Nomal Isolate

Nomal ๋ฐฉ์‹์—์„œ๋Š” UI๊ฐ€ ๋ฉˆ์ถ”๊ณ  ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋ฐ˜์‘์„ ์—…๋ฐ์ดํŠธํ•˜์ง€ ๋ชปํ•˜๋‹ค๊ฐ€ ๋ฐ˜๋ณต๋ฌธ์ด ์ข…๋ฃŒ ๋˜์—ˆ์„ ๋•Œ์— ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์ผ ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ๊ฐ€ ์„œ๋ฒ„์— ๋Œ€ํ•œ ์š”์ฒญ์ด์—ˆ๋‹ค๋ฉด ์ด๋Š” ์‹ฌ๊ฐํ•œ ์ƒํ™ฉ์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋ฐ˜๋ฉด Isolate์—์„œ๋Š” ์›ํ™œํ•˜๊ฒŒ UI ์—…๋ฐ์ดํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ CPU ์ง‘์ค‘ ์ž‘์—…์„ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread)์—์„œ ํ•˜๊ฒŒ ๋˜๋ฉด ํ”„๋ ˆ์ž„์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•œ 16ms(์ตœ๋Œ€ 8.3ms) ๋‚ด์— UI ์—…๋ฐ์ดํŠธ๋ฅผ ์™„๋ฃŒํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— UI๊ฐ€ ๋ฉˆ์ถ”๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
๋ฐ˜๋ฉด Isolate๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ณ„๋„์˜ ๋…๋ฆฝ์ ์ธ ํ™˜๊ฒฝ์—์„œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ธฐ์— UI ์Šค๋ ˆ๋“œ(UI Thread)๋ฅผ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๊ณ  ๋งค๋„๋Ÿฌ์šด UI๋ฅผ ๋‚˜ํƒ€๋‚ด ์ฃผ๋ฉด์„œ ๊ฒฉ๋ฆฌ๋œ ๊ณต๊ฐ„์—์„œ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด๋‹ค.

์ผ๋‹จ์€ Isolate๊ฐ€ ๋ฌด์—‡์ด๊ณ , ์™œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€์™€ ์‹œ๊ฐ์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ฐจ์ด๊ฐ€ ์žˆ๋Š”์ง€ ์–ด๋Š ์ •๋„๋Š” ์ดํ•ด๋Š” ํ–ˆ์„ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•œ๋‹ค.
*์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค๋ฉด, ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋ฉด์„œ ์ดํ•ดํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค !

์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ๋‚ด์šฉ์œผ๋กœ๋งŒ ๋ณธ๋‹ค๋ฉด Isolate๋Š” ๋ฌด์กฐ๊ฑด ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋Šฅ ์ฒ˜๋Ÿผ๋ณด์ธ๋‹ค.

๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread)์— ๋ฐฉํ•ด๋ฅผ ํ•˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ์–ผ๋งˆ๋“ ์ง€ ๋ณต์žกํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€ ?

๊ณผ์—ฐ ๋ฌด์กฐ๊ฑด ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋Šฅ์ผ๊นŒ ..? ์–ผ๋งˆ๋‚˜ ๋ณต์žกํ•˜๊ณ  ๋ฌด๊ฑฐ์šด ์ž‘์—…์ด์–ด์•ผ ํ• ๊นŒ ..?

์ฃผ์˜ํ•  ์ 

Isolate๋Š” ์ถฉ๋ถ„ํžˆ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์ด๊ณ , ์„œ๋น„์Šค๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ํ›Œ๋ฅญํ•œ ํ•ด๊ฒฐ์ฑ…์ด ๋  ์ˆ˜๋„ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๊ณผ ์–ด๋Š ์ผ€์ด์Šค์—์„œ ๋„์ž…ํ•ด์•ผ ํ• ์ง€ ? ๋“ฑ์˜ ๊ณ ๋ฏผํ•˜์—ฌ์•ผ ํ•˜๋Š” ๋ฌธ์ œ๋“ค์ด ์žˆ๋‹ค.

Isolate ๊ธฐ๋Šฅ์„ ํ•„์š”๋กœ ํ•˜๋Š” ์ผ€์ด์Šค์—๋Š” ์–ด๋–ค ์ž‘์—…๋“ค์ด ์žˆ๋Š”์ง€ ๋จผ์ € ์•Œ์•„๋ณด์ž.

๋Œ€ํ‘œ์ ์ธ ์ž‘์—…์€ CPU ์ง‘์•ฝ์ ์ธ ์ž‘์—…๋“ค์ด ์žˆ๋‹ค.

๊ณ ํ•ด์ƒ๋„ ์ด๋ฏธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ž‘์—…์ด๋‚˜, ๋Œ€๊ทœ๋ชจ ํŒŒ์ผ์˜ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”, ๋ณต์žกํ•œ ์—ฐ์‚ฐ ์ž‘์—… ๋“ฑ์ด ๋Œ€ํ‘œ์ ์œผ๋กœ CPU ์ž์›์„ ๋งŽ์ด ์†Œ๋ชจํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์ด๋ฏ€๋กœ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread)๊ฐ€ ์ฐจ๋‹จ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ทธ ์™ธ์—๋„ ์ˆ˜๋งŽ์€ ์ž‘์—…๋“ค์ด ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread)์— ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด์„œ ์ด ๋ชจ๋“  ์ž‘์—…๋“ค์„ ๋ฌด์กฐ๊ฑด Isolate๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

Isolate๋กœ ๊ตฌ์ถ•ํ•˜๊ฒŒ ๋˜๋ฉด ๊ณ ๋ คํ•ด์•ผ ํ•  ๋ฌธ์ œ์ ๋“ค์—๋Š” ์–ด๋–ค ๊ฒƒ๋“ค์ด ์žˆ์„๊นŒ ?

์œ„์—์„œ๋„ ์„ค๋ช…ํ•œ ๋‚ด์šฉ์ด์ง€๋งŒ Isolate๋Š” ๋ณ„๋„์˜ ๋…๋ฆฝ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ง์ ‘์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜์ง€ ๋ชปํ•˜๊ณ , ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ํ†ตํ•ด ๊ณต์œ ๋ฅผ ํ•ด์•ผํ•œ๋‹ค.
๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ ์ง๋ ฌํ™”/์—ญ์งˆ๋ ฌํ™”์˜ ๊ณผ์ •์ด ํ•„์š”ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ์ด ๋•Œ์— ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ํŒจ์‹ฑํ•˜๊ฒŒ ๋˜๋ฉด ์˜คํžˆ๋ ค ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ์–ด์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์€ ๋‹จ์ˆœํ•œ ๋ฐ์ดํ„ฐ๋งŒ์„ ์ „์†กํ•œ๋‹ค.

๋…๋ฆฝ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ฐ€์ง„๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๋ณด๋ฉด Isolate ์ƒ์„ฑ์‹œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ์˜๋ฏธ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ์ •์ ์ธ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋””๋ฐ”์ด์Šค๋ผ๋ฉด ์ œํ•œ์ ์ธ ์ƒํ™ฉ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

์ด ์™ธ์—๋„ ๋””๋ฒ„๊น…, ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ, ๋™๊ธฐํ™” ํƒ€์ด๋ฐ ๋“ฑ์˜ ๊ณ ๋ คํ•ด์•ผ ํ•  ๋ฌธ์ œ๋“ค์ด ์žˆ๋‹ค.

์‹ค์ œ๋กœ Isolate๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์„ ์ž‘๋™์‹œํ‚ค๋Š” ๋ฐ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๊ณ  ๊ฐ ํ™˜๊ฒฝ๋งˆ๋‹ค์˜ ์„œ๋น„์Šค ๊ทœ๋ชจ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— Isolate ๋„์ž…์‹œ ์ˆ˜ ๋งŽ์€ ํ…Œ์ŠคํŠธ์™€ ๋””๋ฒ„๊น… ํ›„ ๋„์ž…์„ ๊ณ ๋ คํ•ด๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

๋ณธ๊ฒฉ์ ์œผ๋กœ Flutter์—์„œ Isolate๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

Flutter์—์„œ๋Š” spawn, compute ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ๋ณ„๋„์˜ ๋…๋ฆฝ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

spawn, compute ๋ชจ๋‘ ๋…๋ฆฝ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฐ๊ฐ์˜ ๋ฐฉ์‹์—๋Š” ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

spawn์€ Isolate๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ณ  ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ณ , ๋…๋ฆฝ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ(Memory) ๊ณต๊ฐ„๊ณผ ์Šค๋ ˆ๋“œ(Thread)๋ฅผ ๊ฐ€์ง€๊ณ  ์‹คํ–‰๋˜์–ด ๋ณต์žกํ•˜๊ณ  ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ๋ฐ˜๋ฉด, compute๋Š” ๊ณ ์ˆ˜์ค€์˜ API๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•จ์ˆ˜ ํ˜•ํƒœ๋กœ Isolate ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉฐ, ์‹œ์Šคํ…œ์ด ์ž๋™์œผ๋กœ Isolate์˜ ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค (๋‹น์—ฐํžˆ compute๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋…๋ฆฝ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ์™€ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ง).

์ฆ‰ spawn์„ ์‚ฌ์šฉํ•˜๋ฉด Isolate๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ๋“ฑ์˜ ๋ชจ๋“  ๊ด€๋ฆฌ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ์˜ ์ „๋‹ฌ์€ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ํ†ตํ•ด์„œ๋งŒ ์ด๋ฃจ์–ด์ง„๋‹ค. ๋ฐ˜๋ฉด compute๋Š” ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread)์— ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋œ๋‹ค.

๋‹จ์ˆœํ•œ ๋ณ‘๋ ฌ ์ž‘์—…์€ compute๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ณต์žกํ•œ ๋ณ‘๋ ฌ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค๋ฉด spawn์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ํ•ฉํ•˜๋‹ค.

spawn

์šฐ์„  ๋ณต์žกํ•œ spawn ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ๋ถ€ํ„ฐ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

spawn ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์„ ์•Œ์•„์•ผ compute ๋ฐฉ์‹์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ ๋˜๋Š”์ง€๋ฅผ ๋‹จ๋ฒˆ์— ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์žกํ•œ ๊ฒƒ๋ถ€ํ„ฐ ๋ฐฐ์›Œ๋ณด์ž !

๊ณผ์ •

spawn์„ ์‚ฌ์šฉํ•œ Isolate ์‹คํ–‰ ์ ˆ์ฐจ ๋ฐ ์„ค๋ช…์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ณด๋„๋ก ํ•˜์ž.

1. Isolate ์ƒ์„ฑ

  • spawn ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด Isolate ์ƒ์„ฑ
  • ์‹คํ–‰๋  ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ , ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ

2. ์‹คํ–‰ํ™˜๊ฒฝ

  • ๋…๋ฆฝ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„๊ณผ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ง์œผ๋กœ ๋‹ค๋ฅธ Isolate์™€๋Š” ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋œ ํ™˜๊ฒฝ
  • ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(Main Thread)์™€๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ณต์œ ๋˜์ง€ ์•Š๊ธฐ์— ๋ณ€์ˆ˜๋‚˜ ๊ฐ์ฒด๋ฅผ ์ง์ ‘์ ์œผ๋กœ ๊ณต์œ  ๋ถˆ๊ฐ€

3. ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ (Message Passing)

  • ๋ฐ์ดํ„ฐ ๊ตํ™˜ ๋ฐ ์ „๋‹ฌ์ด ๊ฐ€๋Šฅํ•˜๊ณ , ์ž‘์—… ๊ฒฐ๊ณผ๋ฅผ Main Isolate๋กœ ์ „๋‹ฌ
  • Send Port, Receive Port๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ ์†ก/์ˆ˜์‹  ์ง„ํ–‰

4. ์ž‘์—…์‹คํ–‰

  • ๋…๋ฆฝ๋œ ํ™˜๊ฒฝ์—์„œ ํ• ๋‹น๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰
  • ๋ณต์žกํ•œ ๊ณ„์‚ฐ, ํŒŒ์ผ I/O, ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋“ฑ์˜ ์ž‘์—…

5. ์ž‘์—… ์ข…๋ฃŒ ๋ฐ ์ž์› ํ•ด์ œ

  • ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ž์‹ ์„ ์ข…๋ฃŒํ•˜์—ฌ ์ž์›์„ ํ•ด์ œํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ฐ˜๋‚ฉ

๊ฐ„๋‹จํ•˜๊ฒŒ ์ ˆ์ฐจ๋ฅผ ๋ณด๋ฉด ์œ„์˜ ์ˆœ์„œ๋Œ€๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

spawn์„ ์‚ฌ์šฉํ•ด Isolate๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋ฉด ๋” ์ด์ƒ ์‚ฌ์šฉ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋Š” ์‹œ์ ์—๋Š” ๋ฐ˜๋“œ์‹œ Isolate๋ฅผ ํ•ด์ œํ•˜์—ฌ์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ๊ผญ ๊ธฐ์–ตํ•˜์‹œ๊ธธ ๋ฐ”๋ž€๋‹ค.

Main Isolate ์™ธ์— ์ถ”๊ฐ€์ ์œผ๋กœ ์ƒ์„ฑ๋œ Isolate๋Š” Dart VM์˜ GC(Garbage Collector) ๋Œ€์ƒ์ด ์•„๋‹ˆ๊ณ  ๋‚ด๋ถ€ ๊ฐ์ฒด๋งŒ GC(Garbage Collector)์˜ ๋Œ€์ƒ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์œผ๋กœ ํ•ด์ œ๋˜์ง€ ์•Š์•„ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

Garbage Collection(GC) : ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์œผ๋กœ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ์ž๋™์œผ๋กœ ํ•ด์ œํ•˜๋Š” ์—ญํ• 

Code

spawn์€ Dart ์–ธ์–ด์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ํฌํ•จ๋œ ๊ธฐ๋Šฅ์œผ๋กœ ๋ณ„๋„๋กœ ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

spawn ํ•จ์ˆ˜๋Š” entryPoint, message๋ฅผ ํ•„์ˆ˜๋กœ ์„ค์ •ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

entryPoint๋Š” ์ƒˆ๋กœ ์ƒ์„ฑ๋œ Isolate์—์„œ ๊ฐ€์žฅ ๋จผ์ € ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๋กœ ํ•ด๋‹น Isolate๊ฐ€ ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ์ •์˜ํ•ด ์ฃผ๋ฉด ๋˜๊ณ , message๋Š” ์ด ํ•จ์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๋กœ, entryPoint์— ์ „๋‹ฌํ•  ์ธ์ž(argument)๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

๋”ฐ๋ผ์„œ, spawn ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ entryPoint์—๋Š” ์‹คํ–‰ํ•  ์ž‘์—…์„ ์ •์˜ํ•œ ํ•จ์ˆ˜๋ฅผ, message์—๋Š” ๊ทธ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ๊ฐ’์„ ์„ค์ •ํ•ด ์ฃผ๋ฉด ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ธฐ๋ณธ ํ˜•ํƒœ๋Š” ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Isolate.spawn(entryPoint, message);

entryPoint ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๋„๋ก ํ•˜์ž.

Isolate์—์„œ ์ž‘๋™๋  ๋ฌด๊ฑฐ์šด ์ž‘์—…์„ ์œ„ํ•ด์„œ ๋ฃจํ”„๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๋„๋ก ํ•˜๊ฒ ๋‹ค.

static void _runIsolate(SendPort message) {
	int current = 0;
	while (current < 10000000000) {
      current++;
    }
}

์ด์–ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์— ๋Œ€ํ•ด์„œ๋„ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

message์—๋Š” entryPoint์˜ ์ธ์ž ๊ฐ’์„ ์„ค์ •ํ•˜๊ฒŒ๋” ๋˜์–ด์žˆ๋Š”๋ฐ, SendPort ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

entryPoint์˜ ์ˆ˜ํ–‰ ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” message๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๋„๋ก ํ•˜์ž.

SendPort ๊ฐ์ฒด์˜ send ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

  static void _runIsolate(SendPort message) {
    int current = 0;
    while (current < 10000000000) {
      current++;
    }
    message.send(current);
  }

๋ฐ˜ํ™˜๋œ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์‹ ํ•˜๋„๋ก ํ•ด๋ณด์ž.

ReceivePort ๊ฐ์ฒด์˜ sendPort๋ฅผ spawn ์ƒ์„ฑ์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , receivePort์˜ listen stream์„ ๊ตฌ๋…ํ•ด ๋ฐ˜ํ™˜ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์‹  ๋ฐ›์œผ๋ฉด ๋œ๋‹ค.

Future<void> _isolate() async {
	final ReceivePort receivePort = ReceivePort();
	Isolate.spawn(_runIsolate, receivePort.sendPort);
    receivePort.listen((message) {
      print(message);
    });
}

์ด๋ฒˆ์—” spawn ์ƒ์„ฑ์‹œ ๋ฉ”์‹œ์ง€๋ฅผ Isolate์— ์ดˆ๊ธฐ ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

send ํ•จ์ˆ˜๋Š” Isolate๋กœ ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ ๋ฐ›๋Š” ๊ฒƒ์ด๋ผ๋ฉด ์ด๋ฒˆ์—” Isolate์— ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

์ด๋Ÿฌํ•œ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์€ Dart ์–ธ์–ด์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐ์ฒด ๋˜ํ•œ ๊ฐ€๋Šฅํ•˜๋‹ค.

Isolate์˜ ๊ฒฐ๊ณผ๋ฅผ Main Isolate์—์„œ ์ „๋‹ฌ ๋ฐ›์„ ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด, SendPort ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ธฐ์— ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  Future<void> _isolate() async {
    Isolate.spawn(_runIsolate, 99);
  }

  static void _runIsolate(int initialCount) {
    int current = initialCount;
    while (current < 10000000000) {
      current++;
    }
    print("current : $current, initialCount : $initialCount");
    // flutter: current : 10000000000, initialCount : 99
  }

๋ฌธ์žํ˜•์„ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Future<void> _isolate() async {
	Isolate.spawn(_runIsolate, "TYGER");
}

static void _runIsolate(String message) {
	print("$message Velog !!");
    // flutter: TYGER Velog !!
}

์ •์ˆ˜ํ˜•, ๋ฌธ์žํ˜• ์™ธ์—๋„ ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ๋ชจ๋‘ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ Isolate๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๊ธธ ์›ํ•  ๊ฒƒ์ด๋‹ค.
๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” SendPort ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, Isolate์—๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ๊ฒฐ๊ณผ ๊ฐ’๋„ ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ๋งŒ๋“ค์–ด ๋ณด๋„๋ก ํ•˜์ž.

SendPort์™€ ์ดˆ๊ธฐ ๊ฐ’์„ ๊ฐ€์ง€๋Š” Map ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์ž.

final ReceivePort receivePort = ReceivePort();
final Map<String, dynamic> _data = {
	"port": receivePort.sendPort,
	"count": 99,
};

ํƒ€์ž…์บ์ŠคํŒ…์„ ์‚ฌ์šฉํ•ด SendPort ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌ ๋ฐ›์•„ send ํ•จ์ˆ˜์— ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

static void _runIsolate(Map<String, dynamic> data) {
	SendPort sendPort = data["port"] as SendPort;
	int current = data["count"];
    while (current < 10000000000) {
      current++;
    }
    sendPort.send(current);
}

์œ„์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๊ตฌ๋…ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ SendPort๋ฅผ ์ƒ์„ฑํ•œ ReceivePort ๊ฐ์ฒด์˜ listen์„ ํ†ตํ•ด ์ˆ˜์‹ ํ•˜๋ฉด ๋œ๋‹ค.

Future<void> _isolate() async {
	final ReceivePort receivePort = ReceivePort();
	final Map<String, dynamic> _data = {
      "port": receivePort.sendPort,
      "count": 99,
    };
    Isolate.spawn(_runIsolate, _data);
    receivePort.listen((message) {
      print(message);
    });
}

Map ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‹น์—ฐํžˆ class๋กœ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

class IsolateMessage {
  final SendPort sendPort;
  final int current;

  const IsolateMessage({
    required this.sendPort,
    required this.current,
  });
}

class๋ฅผ ์‚ฌ์šฉํ•ด IsolateMessage ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ค€ ๋’ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Future<void> _isolate() async {
	final ReceivePort receivePort = ReceivePort();
	final IsolateMessage isolateMessage = IsolateMessage(sendPort: receivePort.sendPort, current: 99);
	Isolate.spawn(_runIsolate, isolateMessage);
	receivePort.listen((message) {
      	print("Result : $message");
        // flutter: Result : 10000000000
	});
}

IsolateMessage ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด SendPort์˜ send ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

static void _runIsolate(IsolateMessage message) {
    int current = message.current;
    while (current < 10000000000) {
      current++;
    }
    message.sendPort.send(current);
  }

Isolate์˜ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ดค๋Š”๋ฐ, ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” send ํ•จ์ˆ˜์—๋„ Dart ์–ธ์–ด์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…๊ณผ ๊ฐ์ฒด ๋ชจ๋‘ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

class๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์ž.

class IsolateResult {
  final int result;

  const IsolateResult({required this.result});
}

๊ฐ์ฒด๋ฅผ send ํ•จ์ˆ˜์— ํŒจ์‹ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

static void _runIsolate(IsolateMessage message) {
	int current = message.current;
    while (current < 10000000000) {
      current++;
    }
    IsolateResult result = IsolateResult(result: current);
    message.sendPort.send(result);
}

๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์€ Isolate ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด๊ณ , ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— SendPort, ReceivePort๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์ดํ•ดํ•˜๊ณ  ์žˆ์œผ๋ฉด ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ํฌ๋‹ค๋ฉด ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”์‹œ Main Isolate๊ฐ€ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋™์•ˆ ์ง€์—ฐ(Jank)์ด ๋ฐœ์ƒํ•ด UI๊ฐ€ ๋Š๋ ค์ง€๊ฑฐ๋‚˜ ๋ฒ„๋ฒ…์ผ ์ˆ˜ ์žˆ์–ด ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋„๋ก ์ถฉ๋ถ„ํžˆ ๊ณ ๋ คํ•˜์—ฌ ์„ค๊ณ„ํ•˜์—ฌ์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ์ฃผ์˜ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

๋งŒ์•ฝ์— ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์‚ฌ์šฉํ•ด Isolate๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์ง€ ์•Š์•„๋„ ๋˜๋Š” ์ผ€์ด์Šค๋ผ๋ฉด ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ ?

entryPoint์—์„œ ์•„๋ฌด๋Ÿฐ ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๋„๋ก ํ•˜๊ณ  message๋ฅผ null๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด Isolate์˜ ์ž‘์—…์„ ํ™•์ธํ•  ์ˆ˜ ์—†์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Isolate๋‚ด์—์„œ๋Š” Main Isolate์˜ UI๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋‹ค.

 Future<void> _isolate() async {
    Isolate.spawn(_runIsolate, null);
}

static void _runIsolate(_) {
	int current = 0;
	while (current < 10000000000) {
      current++;
    }
}

๊ทธ๋Ÿผ์—๋„ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ReceivePort๋ฅผ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์—ด์–ด๋‘˜ ํ•„์š”๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด์–ด์„œ ์œ„์—์„œ๋„ ์–ธ๊ธ‰ํ•œ ๋‚ด์šฉ์ด์ง€๋งŒ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑ๋œ Isolate๋Š” Dart VM์˜ GC(Garbage Collector) ๋Œ€์ƒ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋ถ€๋ถ„์„ ์–ธ๊ธ‰ํ–ˆ์—ˆ๋‹ค.

๋ฐ˜๋“œ์‹œ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•„์š”์— ์˜ํ•ด์„œ ์ƒ์„ฑ์„ ํ–ˆ๋‹ค๋ฉด ํ•ด์ œ๋„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

ํ•ด์ œ๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

Isolate๋ฅผ ํ•ด์ œํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•˜๋‹ค. kill ํ•จ์ˆ˜๋งŒ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด Isolate๋ฅผ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.

isolate.kill();

Isolate๋Š” Future ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์‹œ ์ธ์Šคํ„ด์Šค(Instance)๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์ƒ์„ฑ์„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค.

final Isolate isolate = await Isolate.spawn(_runIsolate, null);

๋ฐ˜ํ™˜๋œ ์ธ์Šคํ„ด์Šค(Instance)๋ฅผ ์‚ฌ์šฉํ•ด Isolate๋ฅผ ํ•ด์ œํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

final Isolate isolate = await Isolate.spawn(_runIsolate, null);
isolate.kill();

ํ•ด์ œ๋˜๋Š” ์‹œ์ ์ด ์ค‘์š”ํ•˜๊ฒŒ ๋œ๋‹ค. ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ ๋ฐ›๊ณ  ๋‚˜์„œ ํ•ด์ œ๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.

ReceivePort๋ฅผ Isolate ๋‚ด์—์„œ ์—ด์–ด ๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์‹œ์ง€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๊ธฐ ์ „์— ๋จผ์ € Isolate๊ฐ€ ํ•ด์ œ๋œ๋‹ค๋ฉด ReceivePort์˜ ๊ฒฐ๊ณผ๊ฐ€ ์ˆ˜์‹ ๋˜์ง€ ์•Š๋Š”๋‹ค.

ReceivePort์˜ ์ˆ˜์‹ ์„ ๋ฐ›๊ณ ๋‚˜์„œ ํ•ด์ œํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

Future<void> _isolate() async {
    final ReceivePort receivePort = ReceivePort();
    final Isolate isolate =
        await Isolate.spawn(_runIsolate, receivePort.sendPort);
    receivePort.listen((message) {
      print(message);
      isolate.kill();
    });
}

๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์‚ฌ์šฉํ•  ๋•Œ์— ์ฃผ์˜ํ•  ์ ์ด ํ•œ ๊ฐ€์ง€ ๋” ์žˆ๋Š”๋ฐ, ๋ฐ”๋กœ ReceivePort ๋˜ํ•œ ๋‹ซ์•„์ค˜์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

Isolate๋ฅผ ํ•ด์ œํ•˜๊ฒŒ ๋˜๋ฉด ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ReceivePort๋Š” GC(Garbage Collector)์— ์˜ํ•ด ์ž๋™์œผ๋กœ ํ•ด์ œ๊ฐ€ ๋˜์ง€๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ๋‹ซ์•„์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ReceivePort๋Š” close ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํฌํŠธ๋ฅผ ๋‹ซ์„ ์ˆ˜ ์žˆ๋‹ค.

Future<void> _isolate() async {
	...
    receivePort.listen((message) {
      print(message);
      
      receivePort.close();
      isolate.kill();
    });
}

์ƒ์„ฑ๋œ Isolate๋ฅผ ํ•ด์ œํ•˜๊ณ , ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์œ„ํ•œ ReceivePort๋ฅผ ๋‹ซ์•„ ์ž์›์„ ๋ช…ํ™•ํžˆ ํ•ด์ œํ•˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋ฉฐ, ์ฝ”๋“œ์˜ ์•ˆ์ •์„ฑ์„ ๋†’ํž ์ˆ˜ ์žˆ๋‹ค.

์ผ๋ถ€ Isolate๊ฐ€ ๋ฐ˜๋ณต์ ์ด๊ฑฐ๋‚˜ ์ž์ฃผ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด ๋งค๋ฒˆ ์—ด๊ณ  ๋‹ซ๋Š” ๊ฒƒ์ด ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์œ ํ•  ์ˆ˜ ์žˆ๊ธฐ์— ์•ˆ์ •์ ์ธ ํ•ด์ œ ์‹œ์ ์„ ๊ณ ๋ คํ•˜์—ฌ ํšจ์œจ์ ์ธ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ฏผํ•ด๋ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค.

spawn ๋ฐฉ๋ฒ•์˜ ์˜ต์…”๋„์— ๋Œ€ํ•ด์„œ๋„ ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ž.

paused

paused๋Š” Boolean ํƒ€์ž…์œผ๋กœ Isolate์˜ ์‹คํ–‰ ์ƒํƒœ๋ฅผ ์ œ์–ดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ๊ธฐ๋ณธ ๊ฐ’์€ false ์ƒํƒœ์ด๊ณ , true๋กœ ์„ค์ •ํ•œ๋‹ค๋ฉด spawn์œผ๋กœ Isolate๋ฅผ ์ƒ์„ฑํ•  ๋•Œ์— ์ผ์‹œ ์ •์ง€ ์ƒํƒœ๋กœ ์ƒ์„ฑ์ด ๋˜์–ด ๋ช…์‹œ์ ์œผ๋กœ ์‹คํ–‰์„ ํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋‚จ์•„ ์žˆ๊ฒŒ๋œ๋‹ค.
Isolate ์ƒ์„ฑ ํ›„ ์ดˆ๊ธฐํ™” ์ž‘์—…์ด๋‚˜ ํ™˜๊ฒฝ ์„ค์ • ๋“ฑ์˜ ์ž‘์—…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ์ „ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋Œ€๊ธฐ ์ƒํƒœ๋ฅผ ํ•ด์ œํ•˜๊ณ  ์žฌ๊ฐœ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ์— resume ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

Future<void> _isolate() async {
  final Isolate isolate = await Isolate.spawn(
    _entryPoint,
    message,
    paused: true,
  );
  isolate.resume(isolate.pauseCapability!);
}

resume ํ•จ์ˆ˜ ์‚ฌ์šฉ์‹œ ์ƒ์„ฑ๋œ Isolate์˜ pauseCapability๋ฅผ ์‚ฌ์šฉํ•ด ๊ถŒํ•œ์„ ์ œ๊ณตํ•˜๋ฉด ๋œ๋‹ค.

errorsAreFatal

ํ•ด๋‹น ์˜ต์…˜์€ ์ƒ์„ฑ๋œ Isolate์˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜๊ฐ€ ์น˜๋ช…์ (fetal)์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
Boolean ํƒ€์ž…์œผ๋กœ ๊ธฐ๋ณธ ๊ฐ’์€ true์ด๋ฉฐ, ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ์‹œ Isolate๋Š” ์ฆ‰์‹œ ์ข…๋ฃŒ๋œ๋‹ค. ๋งŒ์ผ ์ฆ‰์‹œ ์ข…๋ฃŒ๊ฐ€ ๋˜๊ธธ ์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด false๋ฅผ ์ œ๊ณตํ•˜๋ฉด ๋˜๊ณ  ์ด ๊ฒฝ์šฐ Isolate๋Š” ๊ณ„์† ์‹คํ–‰๋˜๊ธฐ์— ํ›„์† ์ž‘์—…์„ ๋ณ„๋„๋กœ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

onExit

onExit๋Š” ๋ช…์นญ์—์„œ๋„ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด Isolate ์ข…๋ฃŒ ์‹œ์ ์„ ์ˆ˜์‹ ํ•˜๊ธฐ ์œ„ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ์ด๋‹ค. ํ•ด๋‹น ์•Œ๋ฆผ์˜ ๋ฉ”์‹œ์ง€๋Š” ํŠน๋ณ„ํ•œ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ kill ํ•จ์ˆ˜ ์‹คํ–‰์‹œ๋‚˜ ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๊ฐ€ ๋˜์—ˆ์„ ๋•Œ์— ํ˜ธ์ถœ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
์ข…๋ฃŒ ์‹œ์ ์„ ํ˜ธ์ถœ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ํ›„์† ์ž‘์—… ๋“ฑ์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ์œ„์—์„œ ๋ฐฐ์› ๋˜ ReceivePort์˜ SendPort๋ฅผ ์ƒ์„ฑํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ spawn์˜ message์˜ ํฌํŠธ์™€ ์„œ๋กœ ๋‹ค๋ฅธ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

Future<void> _isolate() async {
	final exitPort = ReceivePort();

	final Isolate isolate = await Isolate.spawn(
    	_entryPoint,
    	message,
    	onExit: exitPort.sendPort,
  	);

	exitPort.listen((_) {
    	exitPort.close();
  	});
}

onError

onError๋„ onExit์™€ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ๋™์ผํ•˜๊ณ  ์—๋Ÿฌ ๋ฐœ์ƒ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ์ž๋™์œผ๋กœ ๋ฉ”์‹œ์ง€๋กœ ์ „๋‹ฌํ•ด ์ฃผ์ง€๋งŒ, send๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘ ์ „๋‹ฌ ๋ฐ›์„ ์ˆ˜๋„ ์žˆ๋‹ค.
์—๋Ÿฌ ๋ฐœ์ƒ์‹œ errorsAreFatal์˜ ์„ค์ •์— ๋”ฐ๋ผ ์ฆ‰์‹œ ์ข…๋ฃŒ ์‹œํ‚ค๊ฑฐ๋‚˜ ์•„๋‹ˆ๋ฉด ์ข…๋ฃŒ๋ฅผ ์‹œํ‚ค์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, onExit์˜ ์ข…๋ฃŒ ์‹œ์  ๋“ฑ์„ ํ˜ธ์ถœํ•ด์„œ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋ฉด ์—๋Ÿฌ์— ๋”ฐ๋ฅธ Isolate ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Future<void> _isolate() async {
	final errorPort = ReceivePort();

	final Isolate isolate = await Isolate.spawn(
    	_entryPoint,
    	message,
    	onError: errorPort.sendPort,
  	);

	errorPort.listen((message) {
   		print("error : $message");
        // flutter: error : [type 'int' is not a subtype of type 'String' in type cast, #0   
        
    	errorPort.close();
  	});
}

debugName

๋งˆ์ง€๋ง‰์œผ๋กœ debugName์€ ๋””๋ฒ„๊น…์‹œ Isolate๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ์‹๋ณ„์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์„ค์ •์ด๋‹ค. ๋””๋ฒ„๊น… ๋„๊ตฌ๋‚˜ IDE ์‚ฌ์šฉ์‹œ ํšจ์œจ์ ์œผ๋กœ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์™ธ์—๋„ ์ƒ์„ฑํ•œ Isolate์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ์—๋„ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.

addOnExitListener์™€ addErrorListener๋Š” Isolate ์ƒ์„ฑ ์‹œ spawn ํ•จ์ˆ˜์—์„œ ์ œ๊ณตํ•˜๋Š” ์˜ต์…”๋„ ํŒŒ๋ผ๋ฏธํ„ฐ์ธ onExit์™€ onError์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ๊ฐ Isolate๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ์™€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ํ•ด๋‹น SendPort๋กœ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” ์—ญํ• ์„ ํ•˜๊ฒŒ๋˜๋ฉฐ, removeOnExitListener์™€ removeErrorListener๋Š” ๊ฐ๊ฐ addOnExitListener์™€ addErrorListener๋กœ ์ถ”๊ฐ€ํ•œ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
errorsAreFatal์˜ ๊ธฐ๋Šฅ๊ณผ ๋™์ผํ•œ setErrorsFatal ํ•จ์ˆ˜๋„ ์žˆ๋‹ค.

compute

์ด๋ฒˆ์—” compute ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

compute๋Š” ๊ณ ์ˆ˜์ค€์˜ API๋กœ์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•จ์ˆ˜ ํ˜•ํƒœ๋กœ Isolate ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ์‹œ์Šคํ…œ์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

๊ตฌ์กฐ ์ž์ฒด๊ฐ€ ๋‹จ์ˆœํ•˜๊ณ  ์‹ฌํ”Œํ•œ ํ˜•ํƒœ์ด๋‹ค.

compute๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Isolate์˜ ์ƒ์„ฑ ๋ฐ ํ•ด์ œ, ReceivePort, SendPort๋ฅผ ์‚ฌ์šฉํ•œ ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(Message Passing)์„ ์ž๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ์— ์ˆ˜ํ–‰ํ•  ์ž‘์—…๊ณผ ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๋งŒ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

await compute(_callback, message);

callback์— ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ๋งŒ๋“ค์–ด ์ฃผ๋„๋ก ํ•˜์ž.

spawn ์‚ฌ์šฉ์‹œ์—๋Š” ReceivePort, SendPort๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ ํ•˜์˜€์ง€๋งŒ, compute๋Š” ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

static int _runIsolate(int value) {
	int current = value;
	while (current < 10000000000) {
      current++;
    }
    return current;
}

์ •์ˆ˜ํ˜• ์™ธ์—๋„ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์ธ์ž ๊ฐ’์ด๋‚˜ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

int current = await compute(_runIsolate, 10);

compute๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ž‘๋™๋˜๊ธฐ์— then, catchError ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ์ฒ˜๋ฆฌํ•˜์—ฌ๋„ ๋œ๋‹ค.

์ž๋™์œผ๋กœ Isolate๋ฅผ ํ•ด์ œํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์—, spawn ๋ฐฉ์‹๊ณผ ๋น„๊ตํ•˜๋ฉด ์‰ฝ๊ฒŒ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์žฅ์ ์€ ์žˆ์ง€๋งŒ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๋ถ€๋ถ„์ด๋‚˜ ์ œ์–ด์˜ ํ•œ๊ณ„๊ฐ€ ์žˆ์œผ๋‹ˆ ๊ธฐ๋Šฅ์˜ ๊ทœ๋ชจ๋‚˜ ๋ณต์žก์„ฑ, ์—ฌ๋Ÿฌ ์ผ€์ด์Šค ๋“ฑ์„ ๊ณ ๋ คํ•ด์„œ ํšจ์œจ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์ถ•ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

๋งˆ๋ฌด๋ฆฌ

์ด๋ฒˆ ๊ธ€์—์„œ Isolate๊ฐ€ ๋ฌด์—‡์ด๊ณ , Flutter ๊ฐœ๋ฐœ์„ ์œ„ํ•ด์„œ ์™œ ํ•„์š”ํ•œ ๊ฐœ๋…์ธ์ง€, ์–ด๋–ค ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ด์•ผ ๋„์›€์ด ๋˜๊ณ , ์ฃผ์˜ํ•  ์ ์€ ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ์ž‘์„ฑํ•ด ๋ณด์•˜๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ Isolate๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๋„ ์•Œ์•„๋ณด์•˜๋‹ค.

์ข€ ๋” ์‹œ๊ฐ์ ์œผ๋กœ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์‹ค์ œ๋กœ ์ ์šฉํ•ด ๋ณผ ๋งŒํ•œ ๊ธฐ๋Šฅ๋“ค๋กœ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ์ผ€์ด์Šค์—์„œ๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํžˆ ์ด์Šˆ ์—†์ด ๊ธฐ๋Šฅ ์ž‘๋™์ด ๊ฐ€๋Šฅํ•˜๊ณ  ๊ฐ•์ œ๋กœ CPU ์ง‘์•ฝ์ ์ธ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•ด์•ผ๋งŒ Isolate ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์‹œ๊ฐ์ ์ธ ์ฐจ์ด์ ์ด ๋‚˜ํƒ€๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์–‘ํ•œ ์ผ€์ด์Šค์˜ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์ง€ ๋ชปํ•œ ์ ์ด ์•„์‰ฌ์šด ๋ถ€๋ถ„์ด๋‹ค.

์ด ๋ถ€๋ถ„์€ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋  ๋งŒํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์—ฌ๋Ÿฌ ์ผ€์ด์Šค๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด ์ถ”๊ฐ€์ ์œผ๋กœ ๊ธ€์„ ์ž‘์„ฑํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค.

Isolate์— ๋Œ€ํ•ด์„œ ์ž˜๋ชป๋œ ๋‚ด์šฉ์ด ์žˆ๊ฑฐ๋‚˜ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ถ๊ธˆํ•˜์‹  ๋ถ€๋ถ„์€ ํŽธํ•˜๊ฒŒ ๋Œ“๊ธ€ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ํ™•์ธ ํ›„ ๋น ๋ฅธ ๋‹ต๋ณ€ ๋“œ๋ฆฌ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค !

Sample App ..

Git Repository

profile
Flutter Developer

2๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2024๋…„ 9์›” 29์ผ

์ข‹์€ ๋‚ด์šฉ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

1๊ฐœ์˜ ๋‹ต๊ธ€