[Python] GC์˜ ๊ตฌ์กฐ

20์„ธ๊ธฐ๋ง-21์„ธ๊ธฐ์— ๋‚˜์˜จ ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด๊ฐ€ ๊ทธ๋ ‡๋“ฏ์ด, ํŒŒ์ด์ฌ ๋˜ํ•œ ๋Ÿฐํƒ€์ž„ GC์— ์˜ํ•ด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ด€๋ฆฌ๋˜๋Š” ์–ธ์–ด๋‹ค.

Python๋„ ๊ตฌํ˜„์ฒด๋งˆ๋‹ค GC ์›๋ฆฌ๊ฐ€ ๋‹ค๋ฅธ๋ฐ, ์—ฌ๊ธฐ์„œ๋Š” CPython์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ฆฌํ•œ๋‹ค.

Python์˜ GC๋Š” ๋‹ค๋ฅธ ์–ธ์–ด๋“ค์— ๋น„ํ•˜๋ฉด ์ „๋ฐ˜์ ์œผ๋กœ ์—‰์„ฑํ•˜๊ฑฐ๋‚˜ ๋ถ€์‹คํ•œ ๋ถ€๋ถ„์ด ๋งŽ๋‹ค.
๊ทธ๋ž˜์„œ ๋ฉ”๋ชจ๋ฆฌ ์••๋ ฅ์ด ์‹ฌํ•œ ์žฅ๊ธฐ์‹คํ–‰ํ˜• ํ”„๋กœ๊ทธ๋žจ์—๋Š” ๋ณ„๋กœ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค.




Reference Counting

ํŒŒ์ด์ฌ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Reference Counting ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์˜ ํ• ๋‹น์„ ๊ด€๋ฆฌํ•œ๋‹ค.

์›๋ฆฌ๋Š” C++์˜ shared_ptr, Rust์˜ Rc, Swift์˜ ๊ธฐ๋ณธ ํฌ์ธํ„ฐ์™€ ๊ฑฐ์˜ ๋™๋“ฑํ•˜๋‹ค.

https://www.codementor.io/@arch/variable-references-in-python-u9z8j2gk0
ํฌ์ธํ„ฐ ๊ฐ์ฒด ๋‚ด๋ถ€์— ์ฐธ์กฐ ๊ฐฏ์ˆ˜๋ฅผ ์ €์žฅํ•˜๊ณ , ํฌ์ธํ„ฐ๊ฐ€ ๋ณต์ œ๋ ๋•Œ๋งˆ๋‹ค ์นด์šดํŠธ๋ฅผ ์ฆ๊ฐ€, ๋ณต์ œ๋œ ๋ณ€์ˆ˜๊ฐ€ ํ•ด์ œ๋ ๋•Œ๋งˆ๋‹ค ์นด์šดํŠธ๋ฅผ ๊ฐ์†Œ์‹œ์ผœ์„œ 0์ด ๋˜๋ฉด ๊ฐ์ฒด๋ฅผ ํŒŒ๊ดดํ•˜๋Š” ์ •์ฑ…์ด๋‹ค.

๊ตฌํ˜„ ์ž์ฒด๊ฐ€ ๋‹จ์ˆœํ•˜๊ณ  GC์— ๋น„ํ•˜๋ฉด ๊ณต๊ฐ„ ํšจ์œจ์„ฑ์ด๋‚˜ ์‹คํ–‰์†๋„๊ฐ€ ์ข‹๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

๋ฌธ์ œ๋Š”, ์ƒํ˜ธ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํƒœ์—์„œ์˜ ์ฒ˜๋ฆฌ๊ฐ€ ๋งค์šฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
Reference Count๋Š” ๋ณ€์ˆ˜๊ฐ€ "ํ•ด์ œ๋ ๋•Œ" ์นด์šดํŠธ๋ฅผ ๊ฐ์†Œ์‹œ์ผœ์„œ ํŒŒ๊ดดํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, ์„œ๋กœ๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ํ•ด์ œ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š์•„์„œ ๋ฌดํ•œ ๋Œ€๊ธฐ์ƒํƒœ์— ๋น ์งˆ ์ˆ˜ ์žˆ๋‹ค.

https://velog.io/@snack/OS-ARCAutomatic-Reference-Counting
A์™€ B ๋ณ€์ˆ˜๊ฐ€ ๋‘˜๋‹ค ํ•ด์ œ๋˜๋”๋ผ๋„, A๋Š” B๊ฐ€ ํ•ด์ œ๋˜์ง€ ์•Š์•˜์œผ๋‹ˆ ์นด์šดํŠธ๊ฐ€ 1์ด๊ณ , B๋„ A๊ฐ€ ์•„์ง ํ•ด์ œ๋˜์ง€ ์•Š์•˜์œผ๋‹ˆ ์นด์šดํŠธ๊ฐ€ 1์ธ ๋์—†๋Š” ์ˆ˜๋ ์— ๋น ์ง€๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋ž˜์„œ C++/Rust/Swift ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์ฐธ์กฐ ๊ฐœ์ˆ˜์— ํฌํ•จ๋˜์ง€ ์•Š๋Š” Weaked Pointer ๋‹จ์œ„๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฌธ์ œ๋ฅผ ์กฐ๊ธˆ ๋ณต์žกํ•˜๊ฒŒ ํ•ด๊ฒฐํ•œ๋‹ค.

ํ•˜์ง€๋งŒ Python์€ ์—ฌ๊ธฐ์„œ GC ์Šคํ…์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ˆ„์ˆ˜๋ฅผ ํ”ผํ•œ๋‹ค.




์™œ Reference Counting์ธ๊ฐ€?

๋ณดํ†ต GC๊ฐ€ ๋‹ฌ๋ฆฐ ์–ธ์–ด๋“ค์€ mark and sweep ๊ธฐ๋ฐ˜์˜ ๊ธฐ์ˆ ๋“ค๋งŒ์„ ํ™œ์šฉํ•ด์„œ GC๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.
Reference Counting๊ณผ Mark and Sweep์„ ์Šค๊นŒ์„œ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ๊ฐ€ ํ”์น˜๋Š” ์•Š๋‹ค.

Reference Counting๋ฅผ ํฌ๊ธฐํ•˜์ง€ ์•Š๊ณ  GC๋ฅผ ์šฐ๊ฒจ๋„ฃ์€ ๊ฒƒ์—๋Š” ์—ญ์‚ฌ์ ์ธ ์ด์œ ๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ค‘ ํ•˜๋‚˜๋Š” ํ•˜์œ„ํ˜ธํ™˜์ด๋‹ค.
RC๋Š” ์‹ค์ œ ์ฝ”๋“œ์— ์‚ฝ์ž…๋˜๋Š” ๋™์ž‘์ด๋ฏ€๋กœ ์„ฃ๋ถˆ๋ฆฌ ์ œ๊ฑฐํ•œ๋‹ค๋ฉด ๋ฐ”์ด๋„ˆ๋ฆฌ ํ˜ธํ™˜์„ฑ์ด ๊นจ์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Reference Counting ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„ํ•œ ๋ฐ์„œ ๋‚˜์˜ค๋Š” ์žฅ์ ๋„ ์žˆ๋‹ค.
์ˆœํ™˜์ฐธ์กฐ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฐ€์ • ํ•˜์—์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ํ•ด์ œ๊ฐ€ ๊ฑฐ์˜ ์ฆ‰์‹œ ์ผ์–ด๋‚œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. Stop the World ๋ฌธ์ œ๋„ ์ ๋‹ค.




์„ธ๋Œ€๋ณ„(Generational) GC

๋Œ€๋‹ค์ˆ˜์˜ GC ์–ธ์–ด๋“ค์€ ์„ธ๋Œ€๋ณ„ GC ์ด๋ก ์„ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ํŒŒ์ด์ฌ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค.

์„ธ๋Œ€๋ณ„ GC๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝํ—˜์—์„œ ์šฐ๋Ÿฌ๋‚œ ๊ฐ€์„ค์„ ํ† ๋Œ€๋กœ ํ•œ๋‹ค.

1. ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด๋Š” ๊ธˆ๋ฐฉ ์ฃฝ๋Š”๋‹ค.
2. GC์—์„œ ์‚ด์•„๋‚จ์€ ํšŸ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก, ๊ทธ ๊ฐ์ฒด๋Š” ๋” ์˜ค๋ž˜ ์‚ด์•„์žˆ์„ ํ™•๋ฅ ์ด ์ปค์ง„๋‹ค.

์ด๋Ÿฌํ•œ ๊ฒฝํ—˜์— ํž˜์ž…์–ด ํŒŒ์ด์ฌ๋„ ์‹ ์„ธ๋Œ€์™€ ๊ตฌ์„ธ๋Œ€๋ฅผ ๋ณ„๋„์˜ ๊ณต๊ฐ„์— ์ €์žฅํ•˜๋ฉฐ ๊ด€๋ฆฌํ•œ๋‹ค.
๊ณ„์†ํ•ด์„œ ์‚ด์•„๋‚จ์„ ํ™•๋ฅ ์ด ๋†’์€ ๊ฐ์ฒด๋งŒ ๊ตฌ์„ธ๋Œ€ ์˜์—ญ์— ๋ชจ์•„๋‘๊ณ , ๋‚˜๋จธ์ง€๋ฅผ ์‹ ์„ธ๋Œ€์— ๋‘๊ณ ์„œ ์ง‘์ค‘ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์„ธ๋Œ€ ๊ตฌ๋ถ„์€ ๋‹ท๋„ท์ฒ˜๋Ÿผ 0, 1, 2์˜ 3๊ฐ€์ง€๋‹ค.
0์„ธ๋Œ€์—์„œ ์‹œ์ž‘ํ•ด์„œ ํ•œ๋ฒˆ ์ƒ์กดํ•˜๋ฉด 1, ๋‘๋ฒˆ ์ƒ์กดํ•˜๋ฉด 2์„ธ๋Œ€๋กœ ๊ฐ€๋Š” ํ˜•ํƒœ๋‹ค.

0์„ธ๋Œ€๋Š” ์œ„์— ์„ค๋ช…ํ–ˆ๋˜ Reference Count ๊ธฐ๋ฐ˜์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋Š” ๋Œ€์ƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ 1์„ธ๋Œ€๋กœ ๊ฐ€๋Š”๊ฑด ์ˆœํ™˜์ฐธ์กฐ๋กœ ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ๋‹ค.
1์„ธ๋Œ€์™€ 2์„ธ๋Œ€์— ๋Œ€ํ•ด์„œ๋Š” Mark and Sweep ๊ธฐ๋ฐ˜์œผ๋กœ GC๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.




Mark and Sweep ์•Œ๊ณ ๋ฆฌ์ฆ˜

ํ˜„๋Œ€ GC์˜ ๊ทผ๊ฐ„์ด ๋œ ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๋‹ค.
1960๋…„์— ๋ฆฌ์Šต์˜ ์ฐฝ์‹œ์ž ๋งค์นด์‹œ๊ฐ€ ๋งŒ๋“ค์—ˆ๋‹ค.

Java์—์„œ๋„ ๋ช‡๋ช‡ GC ๊ธฐ๋ฒ•์€ ๋งˆํฌ์•ค ์Šค์œ• ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๊ณ , ํŒŒ์ด์ฌ์€ ์ง€๊ธˆ๋„ ์ด๊ฑธ ์“ด๋‹ค.

https://blog.naver.com/sssang97/221567636644

๋งˆํฌ์•ค์Šค์œ•์€ ์ดˆ๊ธฐ์— ๋‚˜์˜จ ๋ฐฉ๋ฒ•๋ก ์ธ๋งŒํผ ๊ตฌ์กฐ๊ฐ€ ๋งค์šฐ ๋‹จ์ˆœํ•˜๋‹ค.

๋ฃจํŠธ๊ฐ์ฒด๋“ค๋ถ€ํ„ฐ ํ•œ๋ฐ”ํ€ด ๋บ‘ ๋Œ๋ฉด์„œ ์ฐธ์กฐ๋˜๊ณ  ์žˆ๋Š”์ง€๋ฅผ ์ฒดํฌํ•˜๊ณ , ์ฐธ์กฐ๋˜์ง€ ์•Š์€๊ฑธ ์‹น ์ง€์›Œ๋ฒ„๋ฆฐ๋‹ค๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค.

๊ตฌํ˜„ํ•˜๊ธฐ์—๋Š” ํŽธ๋ฆฌํ•˜์ง€๋งŒ ๋‹จ์ ์ด ๋งŽ์•„์„œ Java์˜ ๊ฒฝ์šฐ์—๋Š” ๊ทผ๋ž˜์— ์ด ๊ตฌ์กฐ๋ฅผ ๊ฑฐ์˜ ๋ฒ„๋ ธ๋‹ค.

๋งค GC ํƒ€์ž„๋งˆ๋‹ค ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ํ’€์Šค์บ”ํ•˜๋ฉด์„œ ์ฐ๊ณ , ๋˜ ํ’€์Šค์บ”ํ•˜๋ฉด์„œ ์ง€์›Œ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ปค์ง€๋ฉด ๊ฐ๋‹น์ด ์•ˆ๋œ๋‹ค.

๊ฒŒ๋‹ค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ํŒŒํŽธํ™”๋„ ์‹ฌํ•˜๋‹ค. ๊ทธ๋ƒฅ ์ผ๋‹จ ์ง€์šฐ๊ณ  ๋ณด๋Š”๊ฒŒ ์ตœ์ข… ๋ชฉ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ์กฐ๊ฐ๋ชจ์Œ๊ฐ™์€๊ฑธ ๊ณ ๋ คํ•˜์ง€๋„ ์•Š์•˜๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ํŒŒํŽธํ™”๊ฐ€ ๋ˆ„์ ๋ ์ˆ˜๋ก ์—ฐ์†๋œ ํฐ ๊ณต๊ฐ„์ด ์—†์–ด์ ธ์„œ ๋นˆ ๊ณต๊ฐ„์„ ์ฐพ๊ธฐ๋„ ํž˜๋“ค๊ณ , ์ถ”๊ฐ€์ ์ธ ์ •๋ฆฌ์ž‘์—…์ด ํ•„์š”ํ•ด์งˆ ์ˆ˜๋„ ์žˆ๋‹ค.




Memory Compaction ์—†์Œ

ํŒŒ์ด์ฌ์€ ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์†”๋ฃจ์…˜์„ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค.

๋ณดํ†ต์˜ GC ์–ธ์–ด๋“ค์€ Mark and Sweep๊ณผ ๋™์‹œ์— memory compaction์„ ์ˆ˜ํ–‰ํ•ด์„œ ์ •์ง€์‹œ๊ฐ„์ด ์ƒ๊ธฐ๋Š” ๋Œ€์‹ ์— ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋ฅผ ๋ง‰๋Š”๋ฐ, ํŒŒ์ด์ฌ์€ ๊ทธ๋Ÿฐ๊ฒŒ ์—†๋‹ค.
Stop the World๊ฐ€ ์ ์€ ๋Œ€์‹ , ์žฅ๊ธฐ์‹คํ–‰ํ˜• ํ”„๋กœ๊ทธ๋žจ์ด๋ผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.




GIL(Global Interpreter Lock)

GIL์€ Python์˜ ์›์ฃ„ ์ค‘ ํ•˜๋‚˜๋‹ค.

์ด๊ฑด ์‚ฌ์‹ค ๊ตฌํ˜„์„ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฒฝ์„ ์ณ๋‘๊ณ  ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋‚˜ ๊ธฐํƒ€ ์„ฑ๋Šฅ ์ตœ์ ํ™”์—์„œ์˜ ์†์‹ค์„ ๊ฐ์ˆ˜ํ•œ ๊ฒƒ์— ๊ฐ€๊น๋‹ค.
๊ทธ๋ž˜์„œ ํ˜„์žฌ๋Š” GIL์„ ์ œ๊ฑฐํ•˜๋ ค๊ณ  ์‹œ๋„๋Š” ํ•˜๊ณ  ์žˆ์œผ๋‚˜, ์–ผ๋งˆ๋‚˜ ์ž˜ ๋ ์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค.

์•„๋ฌดํŠผ ํ˜„์žฌ Python์˜ GC๋„ GIL์— ์˜์กดํ•˜๋Š” ๋ถ€๋ถ„์ด ๋งŽ๋‹ค.

GIL์˜ ํฐ ์กด์žฌ๋ชฉ์  ์ค‘ ํ•˜๋‚˜๋Š” Reference Count๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ์˜ ํšจ์œจ์„ฑ๊ณผ ์•ˆ์ „์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.

์นด์šดํŠธ ๊ฐ’์„ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์—์„œ๋„ ์œ ํšจํ•˜๊ฒŒ ๋งŒ๋“ค๋ ค๋ฉด ์ถ”๊ฐ€์ ์ธ ๋™๊ธฐํ™”๋‚˜ ๋ฝ ์ž‘์—…์ด ํ•„์š”ํ•œ๋ฐ, ๊ทธ๊ฑธ ํ•˜์ง€ ์•Š๋Š” ๋Œ€์‹ ์— ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ๋กœ ๊ณ ์ •ํ•ด๋ฒ„๋ฆฐ ๊ฒƒ์ด๋‹ค.



์ฐธ์กฐ
https://stackoverflow.com/questions/21934/why-java-and-python-garbage-collection-methods-are-different
https://www.winterjung.dev/python-gc/
https://stackoverflow.com/questions/9062209/why-does-python-use-both-reference-counting-and-mark-and-sweep-for-gc
https://dev.to/karishmashukla/how-python-uses-garbage-collection-for-efficient-memory-management-270h
https://velog.io/@vhzpt109/Python-Garbage-Collector%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0
https://devguide.python.org/internals/garbage-collector/index.html
https://stackoverflow.com/questions/59118749/python-gc-memory-compaction