[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