Alert
์ด ๊ธ์ Claude Code์ ๋์์ ๋ฐ์ ์์ฑ๋์์ต๋๋ค
TL;DR
- Python์ ๋ชจ๋ ๋ณ์๊ฐ ์ฐธ์กฐ์ง๋ง Go๋ ๊ธฐ๋ณธ์ด ๊ฐ ๋ณต์ฌ(call by value)
&๋ก ์ฃผ์๋ฅผ ์ป๊ณ*๋ก ์ญ์ฐธ์กฐํ๋ฉฐ, ํฌ์ธํฐ ์ฐ์ ์ ๋ถ๊ฐ- ํฌ์ธํฐ๋ฅผ ํจ์์ ๋๊ฒจ๋ ํฌ์ธํฐ ๋ณ์ ์์ฒด๋ ๋ณต์ฌ๋๋ฏ๋ก, ํฌ์ธํฐ๋ฅผ ์ฌํ ๋นํ๋ฉด ์๋ณธ์ ์ํฅ ์์
- ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์
*px = ...๋ก ์์ ํด์ผ ์๋ณธ์ด ๋ฐ๋- ์ฌ๋ผ์ด์ค๋ (ํฌ์ธํฐยท๊ธธ์ดยท์ฉ๋) ํค๋๊ฐ ๋ณต์ฌ๋๋ฉฐ, ๊ณต์ฉ API ์ ์ถ๋ ฅ์ ๋งต๋ณด๋ค ๊ตฌ์กฐ์ฒด๊ฐ ์์
- ํฌ์ธํฐ๋ ํ ํ ๋น(escape)์ ๋๋ ค GC ๋ถํ๋ฅผ ํค์ฐ๋ฏ๋ก, ๊ฐ ํ์ ยท๋ฒํผ ์ฌ์ฌ์ฉ์ผ๋ก GC ์ผ๊ฐ์ ์ค์
- Go์์๋ ํฌ์ธํฐ ์ฌ์ฉ์ ์ต์ํํ๋ ๊ฒ์ด ๊ถ์ฅ๋จ
Python์์๋ ๋ณ์๊ฐ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ผ๋ ๊ฑธ ์์ํ์ง ์์๋ ๋๋ถ๋ถ ์ ๋์ํ๋ค. Go๋ ๋ค๋ฅด๋ค. ๊ฐ์ด ๋ณต์ฌ๋๋์ง ์ฐธ์กฐ๊ฐ ์ ๋ฌ๋๋์ง๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ฒฐ์ ํด์ผ ํ๋ค. ์ด ๊ธ์ Python ๊ฐ๋ฐ์๊ฐ Go์ ํฌ์ธํฐ๋ฅผ ์ฒ์ ์ ํ ๋ ํท๊ฐ๋ฆฌ๋ ๋ถ๋ถ์ ์ ๋ฆฌํ๋ค.
1. Python์ ๋ชจ๋ ๊ฒ์ด ์ฐธ์กฐ, Go๋ ๊ธฐ๋ณธ์ด ๊ฐ ๋ณต์ฌ
Python์์๋ ๋ณ์์ ๊ฐ์ ํ ๋นํ๋ฉด ์ค์ ๋ก๋ ๊ฐ์ฒด์ ์ฐธ์กฐ๊ฐ ์ ์ฅ๋๋ค. ํจ์์ ์ธ์๋ฅผ ๋๊ธฐ๋ฉด ๊ทธ ์ฐธ์กฐ๊ฐ ๋ณต์ฌ๋๋ฏ๋ก, ์๋ณธ ๊ฐ์ฒด๋ฅผ ์ง์ ์์ ํ ์ ์๋ค.
# Python
def modify(lst):
lst.append(4)
a = [1, 2, 3]
modify(a)
print(a) # [1, 2, 3, 4] โ ์๋ณธ์ด ๋ฐ๋Go๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ ์ ์ฒด๋ฅผ ๋ณต์ฌํ๋ค. ํจ์์ ๊ตฌ์กฐ์ฒด๋ฅผ ๋๊ธฐ๋ฉด ํต์งธ๋ก ๋ณต์ฌ๋ณธ์ด ๋ง๋ค์ด์ง๋ค.
// Go
func modify(nums [3]int) {
nums[0] = 999
}
func main() {
a := [3]int{1, 2, 3}
modify(a)
fmt.Println(a) // [1 2 3] โ ์๋ณธ ์ ๋ฐ๋. ๋ณต์ฌ๋ณธ์ด ์์ ๋จ
}์ ๋ฆฌํ๋ฉด ์ด๋ ๋ค.
| Python | Go | |
|---|---|---|
| ๋ณ์ ํ ๋น | ๊ฐ์ฒด์ ์ฐธ์กฐ ์ ์ฅ | ๊ฐ ์์ฒด๋ฅผ ์ ์ฅ |
| ํจ์ ์ธ์ ์ ๋ฌ | ์ฐธ์กฐ์ ๋ณต์ฌ | ๊ฐ์ ๋ณต์ฌ |
| ์๋ณธ ์์ | ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ๋ฅ | ํฌ์ธํฐ๋ฅผ ๋ช ์์ ์ผ๋ก ์ฌ์ฉํด์ผ ํจ |
์ฌ๋ผ์ด์ค, ๋งต, ์ฑ๋์ ์์ธ
Go์ ์ฌ๋ผ์ด์ค(
[]int), ๋งต(map), ์ฑ๋(chan)์ ๋ด๋ถ์ ์ฐธ์กฐ๋ฅผ ํฌํจํ๋ ํ์ ์ด๋ค. ์ด๋ค์ ๊ฐ ๋ณต์ฌ๊ฐ ์ผ์ด๋๋ ๋ด๋ถ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ฏ๋ก Python์ ๋ฆฌ์คํธ/๋์ ๋๋ฆฌ์ ๋น์ทํ๊ฒ ๋์ํ๋ค. ์ ์์์์ ๋ฐฐ์ด([3]int)์ ์ด ์ด์ ๋ ์ด ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด์๋ค.
2. &์ * โ ์ฃผ์์ ์ญ์ฐธ์กฐ
ํฌ์ธํฐ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ ์ฅํ๋ ๋ณ์๋ค. Go์์๋ ๋ ๊ฐ์ง ์ฐ์ฐ์๋ก ํฌ์ธํฐ๋ฅผ ๋ค๋ฃฌ๋ค.
&xโ ๋ณ์x์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ์ ธ์ด*pโ ํฌ์ธํฐp๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ ๊ฐ์ ธ์ด (์ญ์ฐธ์กฐ)
x := 10
pointerToX := &x // x์ ์ฃผ์
fmt.Println(pointerToX) // 0xc0000b4008 ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์
fmt.Println(*pointerToX) // 10 (์ญ์ฐธ์กฐ)
*pointerToX = 20
fmt.Println(x) // 20 โ ํฌ์ธํฐ๋ฅผ ํตํด ์๋ณธ ์์ ํฌ์ธํฐ์ zero value๋ nil
Go์ ๋ชจ๋ ํ์
์๋ zero value๊ฐ ์๋ค(02ํธ์์ ๋ค๋ค๋ค). int์ 0, string์ ""์ธ ๊ฒ์ฒ๋ผ. ํฌ์ธํฐ์ zero value๋ **nil**์ด๋ค. ์์ง ์๋ฌด ์ฃผ์๋ ๊ฐ๋ฆฌํค์ง ์๋, โ๋น ํฌ์ธํฐโ ์ํ๋ฅผ ๋ปํ๋ค.
var p *int // ์ ์ธ๋ง ํ๋ฉด nil
fmt.Println(p) // <nil>
fmt.Println(p == nil) // true์ฃผ์ํ ์ ์ nil ํฌ์ธํฐ๋ฅผ ์ญ์ฐธ์กฐํ๋ฉด(*p) ๋ฐํ์ ํจ๋์ด ๋๋ค๋ ๊ฒ์ด๋ค. ๊ฐ๋ฆฌํค๋ ๋์์ด ์๋๋ฐ ๊ทธ ๊ฐ์ ๊บผ๋ด๋ ค ํ๊ธฐ ๋๋ฌธ์ด๋ค.
var p *int
fmt.Println(*p) // panic: runtime error: invalid memory address or nil pointer dereferencePython์ None๊ณผ ๋น์ทํ ์์น๋ค. ๋ค๋ง Python์ None ์์ฒด๊ฐ ํ๋์ ๊ฐ์ฒด๋ผ ๋ณ์์ ๋ด์ ๋๋ ๊ฒ๋ง์ผ๋ก๋ ํฐ์ง์ง ์์ง๋ง, Go์์ nil ํฌ์ธํฐ๋ฅผ ์ญ์ฐธ์กฐํ๋ ๊ฑด ์ฆ์ ํจ๋์ผ๋ก ์ด์ด์ง๋ค. ๊ทธ๋์ ํฌ์ธํฐ๋ฅผ ์ธ์๋ก ๋ฐ๋ ํจ์์์๋ if p == nil์ผ๋ก ๋จผ์ ํ์ธํ๋ ํจํด์ด ํํ๋ค.
Python๊ณผ ๋น๊ต
Python์๋ ํฌ์ธํฐ๊ฐ ์๋ค. id() ํจ์๋ก ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๋ณผ ์๋ ์์ง๋ง, ๊ทธ ์ฃผ์๋ฅผ ํตํด ๊ฐ์ ์ง์ ์กฐ์ํ๋ ๋ฐฉ๋ฒ์ ์๋ค.
x = 10
print(id(x)) # 4345678912 ๊ฐ์ ์ฃผ์
# ํ์ง๋ง ์ด ์ฃผ์๋ก ๊ฐ์ ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ์ ์์C์ ๋น๊ต
C/C++ ๊ฒฝํ์ด ์๋ค๋ฉด &์ *๊ฐ ์น์ํ ๊ฒ์ด๋ค. ๋ค๋ง Go์๋ ๋ ๊ฐ์ง ์ค์ํ ์ฐจ์ด๊ฐ ์๋ค.
- ํฌ์ธํฐ ์ฐ์ ๋ถ๊ฐ โ
p++๊ฐ์ ์ฐ์ฐ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ์ด๋ํ ์ ์๋ค. ์์ ์ฑ์ ์ํ ์ค๊ณ๋ค. - GC๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ด๋ฆฌ โ
free()๋delete๋ฅผ ํธ์ถํ ํ์๊ฐ ์๋ค. Go์ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ์์์ ์ ๋ฆฌํ๋ค.
3. ํจ์์์ ํฌ์ธํฐ ์ฌ์ฉ
์๋ณธ ๊ฐ์ ํจ์ ์์์ ์์ ํ๊ณ ์ถ์ผ๋ฉด ํฌ์ธํฐ๋ฅผ ๋๊ธด๋ค.
func update(px *int) {
*px = 20 // ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ ์์
}
func main() {
x := 10
update(&x)
fmt.Println(x) // 20
}*int์ โ์ฃผ์๋ฅผ ๋ด๋ ํ์
โ์ด๋ค
์ฌ๊ธฐ์ px *int๋ผ๋ ํ๊ธฐ๊ฐ ์ฒ์ ๋ณด๋ฉด ํท๊ฐ๋ฆฐ๋ค. *int์ด๋ผ๋ ํ์
์ด ๊ฐ์ ๋ปํ๋์ง ์ฃผ์๋ฅผ ๋ปํ๋์ง ๋ชจํธํ๊ฒ ๋๊ปด์ง๊ธฐ ๋๋ฌธ์ด๋ค. ๊ฒฐ๋ก ๋ถํฐ ๋งํ๋ฉด *int์ ์ฃผ์๋ฅผ ๋ด๋ ํ์
์ด๋ค.
intํ์ ๋ณ์ โ ์ ์ ๊ฐ์ ๋ด๋๋ค (x := 10โx์์๋10)*intํ์ ๋ณ์ โ int์ ์ฃผ์๋ฅผ ๋ด๋๋ค (px := &xโpx์์๋x๊ฐ ์ฌ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์)
๊ทธ๋์ func update(px *int)์ โpx๋ int์ ์ฃผ์๋ฅผ ๋ฐ๋๋คโ๋ ๋ป์ด๊ณ , px์ ๋ค์ด์ค๋ ๊ฐ์ ์ฒ์๋ถํฐ ๋๊น์ง ์ฃผ์๋ค.
ํท๊ฐ๋ฆฌ๋ ์ง์ง ์ด์ ๋ * ๊ธฐํธ๊ฐ ๋ถ๋ ์์น์ ๋ฐ๋ผ ์ ๋ฐ๋๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
| ์์น | ์์ | ์๋ฏธ |
|---|---|---|
| ํ์ ์ | px *int | โint์ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ ํ์ โ โ ์ฃผ์๋ฅผ ๋ด๋๋ค (์ ์ธ) |
| ๋ณ์ยท๊ฐ ์ | *px = 20 | โ๊ทธ ์ฃผ์๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐโ โ ์ญ์ฐธ์กฐ (์ฐ์ฐ) |
px *int์์*๋ ํ์int์ ๋ถ์ด โint ์ฃผ์ ํ์ โ์ ๋ง๋ ๋ค. ์ฃผ์ ํ ๊ฒน์ ์์ฐ๋ ์ชฝ์ด๋ค.*px์์*๋ ๋ณ์px์ ๋ถ์ด โpx๊ฐ ๋ ์ฃผ์๋ก ์ฐพ์๊ฐ ๊ฐโ์ ๊บผ๋ธ๋ค. ์ฃผ์ ํ ๊ฒน์ ๋ฒ๊ธฐ๋ ์ชฝ์ด๋ค.
๋ฐฉํฅ์ด ๋ฐ๋๋ค. ํ์ ์๋ฆฌ์์๋ ์ฃผ์๋ฅผ ์์ฐ๊ณ , ์ ์๋ฆฌ์์๋ ์ฃผ์๋ฅผ ๋ฒ๊ธด๋ค.
์ฝ๋ ์๋ น
var px *intโ โpx is a pointer to intโ (px๋ int๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ = ์ฃผ์๋ฅผ ๋ด๋๋ค)*pxโ โvalue at pxโ (px๊ฐ ๊ฐ๋ฆฌํค๋ ๊ณณ์ ๊ฐ)์ง ์ฃผ์์ ๋น์ ํ๋ฉด
px๋ ์ข ์ด์ ์ ํ ์ฃผ์์ด๊ณ ,*px๋ ๊ทธ ์ฃผ์๋ก ์ฐพ์๊ฐ ์ง ์์์ ๊บผ๋ธ ๋ฌผ๊ฑด์ด๋ค.&x๋x๋ผ๋ ์ง์ ์ฃผ์๋ฅผ ์์๋ด๋ ์ผ์ด๋ค.
์ด ๊ตฌ๋ถ์ ์ผ๋์ ๋๊ณ ์ ์์์ ํ๋ฆ์ ๋จ๊ณ๋ณ๋ก ๋ณด๋ฉด ์ด๋ ๋ค.
x๋ ๊ฐ10์ ๊ฐ์ง ๋ณ์๋ค (int)&x๋กx์ ์ฃผ์๋ฅผ ๊ตฌํด์update์ ๋๊ธด๋ค (*int๊ฐ, ์ฆ ์ฃผ์)update์์px๋x์ ์ฃผ์๋ฅผ ๋ด๊ณ ์๋ค*px = 20์ผ๋ก ๊ทธ ์ฃผ์์ ์๋ ๊ฐ์20์ผ๋ก ๋ฐ๊พผ๋ค (์ญ์ฐธ์กฐ)main์x๊ฐ20์ด ๋๋ค
4. ํฌ์ธํฐ ๋ณ์ ์์ฒด๋ ๋ณต์ฌ๋๋ค โ ๊ฐ์ฅ ํํ ์ค์
์ด ๋ถ๋ถ์ด ํฌ์ธํฐ๋ฅผ ์ฒ์ ๋ฐฐ์ธ ๋ ๊ฐ์ฅ ํท๊ฐ๋ฆฌ๋ ์ง์ ์ด๋ค. Go๋ ํฌ์ธํฐ๋ฅผ ๋๊ธธ ๋๋ ํฌ์ธํฐ ๋ณ์ ์์ฒด๋ ๋ณต์ฌํ๋ค. ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๋์์ ๊ณต์ ํ ๋ฟ, ํฌ์ธํฐ ๋ณ์ ์์ฒด๋ ๋ณ๊ฐ๋ค.
์ ๋ณ๊ฐ์ธ๊ฐ โ ํฌ์ธํฐ๋ ์๊ธฐ ์ฃผ์์ ์ฌ๋ ๋ณ์๋ค
ํต์ฌ์ ํฌ์ธํฐ ๋ณ์๋ ๊ฒฐ๊ตญ ์๊ธฐ๋ง์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ์ ์ฅ๋ ํ๋ฒํ ๋ณ์๋ผ๋ ์ ์ด๋ค. ๋ด๊ณ ์๋ ๊ฐ์ด โ์ฃผ์โ์ผ ๋ฟ์ด๋ค. ๊ทธ๋์ ํจ์์ ๋๊ธฐ๋ฉด ๊ทธ ๊ฐ(์ฃผ์)์ด ๋ ๋ค๋ฅธ ์์น์ ๋ณต์ฌ๋๋ค.
x := 10
px := &x // px๋ x์ ์ฃผ์๋ฅผ ๋ด๋๋ค
update(px) // px์ '๊ฐ'(์ฃผ์)์ด ํ๋ผ๋ฏธํฐ๋ก ๋ณต์ฌ๋จ์ธ ๋ณ์๊ฐ ๊ฐ์ ๋ค๋ฅธ ์ฃผ์์ ์ฐ๋ค๊ณ ๋ณด๋ฉด ๋ช ํํด์ง๋ค.
| ๋ณ์ | ์ฌ๋ ์ฃผ์(์์) | ๋ด์ ๊ฐ |
|---|---|---|
x | 0x100 | 10 |
px (= &x) | 0x200 | 0x100 โ x์ ์ฃผ์ |
update์ ํ๋ผ๋ฏธํฐ (px ๋ณต์ฌ๋ณธ) | 0x300 | 0x100 โ px์์ ๋ณต์ฌ๋ ๊ฐ์ ์ฃผ์ |
px์ ํ๋ผ๋ฏธํฐ๋ ๊ฐ์ ๊ฐ(0x100)์ ๋ด์ง๋ง, ์๊ธฐ ์์ ์ ์๋ก ๋ค๋ฅธ ๊ณณ(0x200 vs 0x300)์ ์ฌ๋ ๋ณ๊ฐ์ ๋ณ์๋ค. ์ฌ๊ธฐ์ ๋ ๋์์ด ๊ฐ๋ฆฐ๋ค.
*ํ๋ผ๋ฏธํฐ = 20โ ํ๋ผ๋ฏธํฐ๊ฐ ๋ ์ฃผ์0x100์ผ๋ก ์ฐพ์๊ฐ ๊ฐ์ ๊ณ ์นจ โx๊ฐ ๋ฐ๋๋ค (px๋ ๊ฐ์0x100์ ๊ฐ๋ฆฌํค๋ ๊ณต์ ๋จ)ํ๋ผ๋ฏธํฐ = &๋ค๋ฅธ๋ณ์โ ํ๋ผ๋ฏธํฐ๊ฐ ์ฌ๋0x300์ ์ ์ฃผ์๋ฅผ ๋ฎ์ด์ โpx(0x200)๋ ๊ทธ๋๋ก โ ๋ฐ๊นฅ์ ์ํฅ ์์
์ฆ โ๊ฐ๋ฆฌํค๋ ๋์โ์ ๊ณต์ ํ์ง๋ง โํฌ์ธํฐ ๋ณ์ ๊ทธ ์์ฒดโ๋ ๋ณต์ฌ๋ณธ์ด๋ผ ๋ฐ๋ก ๋
ผ๋ค. ๋ง์ฝ ํจ์๊ฐ px๊ฐ ๊ฐ๋ฆฌํค๋ ๋์ ์์ฒด๋ฅผ ๋ฐ๊พธ๊ฒ ํ๋ ค๋ฉด, px๊ฐ ์๋๋ผ px์ ์ฃผ์(&px, ํ์
์ **int)๋ฅผ ๋๊ฒจ์ผ ํ๋ค. ๊ฐ ๋ณต์ฌ ๊ท์น์ ํฌ์ธํฐ๋ผ๊ณ ์์ธ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
Case 1: nil ํฌ์ธํฐ ์ ๋ฌ
func failedUpdate(g *int) {
x := 10
g = &x // g๋ ๋ณต์ฌ๋ณธ. ๋ฐ๊นฅ์ f๋ ์ ๋ฐ๋
}
func main() {
var f *int // nil
failedUpdate(f)
fmt.Println(f) // <nil> โ ์ฌ์ ํ nil
}failedUpdate ์์์ g์ ์ ์ฃผ์๋ฅผ ํ ๋นํด๋, g๋ f์ ๋ณต์ฌ๋ณธ์ด๋ค. f๋ ์ฌ์ ํ nil์ด๋ค.
Case 2: ํฌ์ธํฐ ์ฌํ ๋น vs ์ญ์ฐธ์กฐ ์์
// ์คํจํ๋ ๋ฒ์
func failedUpdate(px *int) {
x2 := 20
px = &x2 // px ๋ณต์ฌ๋ณธ๋ง ๋ฐ๋ โ main์ x๋ ๊ทธ๋๋ก
}
// ์ฑ๊ณตํ๋ ๋ฒ์
func update(px *int) {
*px = 20 // px๊ฐ ๊ฐ๋ฆฌํค๋ ๊ณณ์ ๊ฐ์ ์์ โ main์ x๊ฐ ๋ฐ๋
}
func main() {
x := 10
failedUpdate(&x)
fmt.Println(x) // 10 โ ์ ๋ฐ๋
update(&x)
fmt.Println(x) // 20 โ ๋ฐ๋
}ํต์ฌ ๊ท์น
- ํฌ์ธํฐ๋ฅผ ๋๊ฒจ๋ ํฌ์ธํฐ ๋ณ์ ์์ฒด๋ ๋ณต์ฌ๋๋ค
- ํฌ์ธํฐ ๋ณ์๋ฅผ ๋ค๋ฅธ ์ฃผ์๋ก ์ฌํ ๋น(
px = &x2)ํ๋ฉด ์๋ณธ์ ์ํฅ ์์- ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ ์์ (
*px = 20)ํด์ผ ์๋ณธ์ด ๋ฐ๋
Python ์ฉ์ด๋ก ๋น์ ํ๋ฉด ์ด๋ ๋ค. Python์์ ํจ์ ์์์ lst = [4, 5, 6]์ฒ๋ผ ์ ๋ฆฌ์คํธ๋ฅผ ํ ๋นํ๋ฉด ์๋ณธ์ด ์ ๋ฐ๋๋ ๊ฒ๊ณผ ๊ฐ์ ์๋ฆฌ๋ค. ์ฐธ์กฐ ์์ฒด๋ฅผ ๊ต์ฒดํ ๊ฒ์ด์ง, ์ฐธ์กฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๋์์ ์์ ํ ๊ฒ ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
# Python์์๋ ๊ฐ์ ์๋ฆฌ
def failed_update(lst):
lst = [4, 5, 6] # ์ ๋ฆฌ์คํธ๋ก ๊ต์ฒด โ ์๋ณธ ์ ๋ฐ๋
def update(lst):
lst.append(4) # ๊ธฐ์กด ๋ฆฌ์คํธ๋ฅผ ์์ โ ์๋ณธ ๋ฐ๋
a = [1, 2, 3]
failed_update(a)
print(a) # [1, 2, 3]
update(a)
print(a) # [1, 2, 3, 4]5. ๋งต๊ณผ ์ฌ๋ผ์ด์ค๋ฅผ ํจ์์ ๋๊ธธ ๋
1๋ฒ์์ ์ง์๋ฏ ์ฌ๋ผ์ด์คยท๋งตยท์ฑ๋์ ๊ฐ ๋ณต์ฌ๊ฐ ์ผ์ด๋๋ ๋ด๋ถ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ค. ํจ์์ ๋๊ฒจ ๋ด์ฉ์ ๋ฐ๊พธ๋ฉด ์๋ณธ์ ๋ฐ์๋๋ ์ด์ ๋ค. ์ด ๋์์ 05ํธ์ call by value์์๋ ๋ค๋ค๋๋ฐ, ์ฌ๊ธฐ์๋ ๊ทธ ๊ตฌ์กฐ์ ์ค๋ฌด์์์ ์ฃผ์์ ์ ์ ๋ฆฌํ๋ค.
์ฌ๋ผ์ด์ค๋ (ํฌ์ธํฐ, ๊ธธ์ด, ์ฉ๋) ํค๋๊ฐ ๋ณต์ฌ๋๋ค
์ฌ๋ผ์ด์ค ๊ฐ์ ๋ฐ์ดํฐ ๋ฐฐ์ด ์์ฒด๊ฐ ์๋๋ผ, ๊ทธ ๋ฐฐ์ด์ ๊ฐ๋ฆฌํค๋ ์์ ํค๋๋ค. ์ ํํ๋ ์ธ ๊ฐ์ง ๊ฐ์ผ๋ก ์ด๋ค์ง๋ค.
- ํฌ์ธํฐ โ ์ค์ ๋ฐ์ดํฐ๊ฐ ๋ด๊ธด ๋ฐฐ์ด์ ์์ ์ฃผ์
- ๊ธธ์ด(len) โ ํ์ฌ ์์ ๊ฐ์
- ์ฉ๋(cap) โ ์ฌํ ๋น ์์ด ๋ด์ ์ ์๋ ์ต๋ ๊ฐ์
ํจ์์ ์ฌ๋ผ์ด์ค๋ฅผ ๋๊ธฐ๋ฉด ์ด ํค๋ ์ธ ๊ฐ์ด ๋ณต์ฌ๋๋ค. ๋ณต์ฌ๋ณธ์ ํฌ์ธํฐ๋ ์๋ณธ๊ณผ ๊ฐ์ ๋ฐฐ์ด์ ๊ฐ๋ฆฌํค๋ฏ๋ก, ์์๋ฅผ ์์ ํ๋ฉด ์๋ณธ์ ๋ฐ์๋๋ค.
func zeroFirst(s []int) {
s[0] = 0 // ๊ฐ์ ๋ฐฐ์ด์ ๊ฐ๋ฆฌํค๋ ์๋ณธ์ ๋ฐ์
}
nums := []int{1, 2, 3}
zeroFirst(nums)
// nums == [0 2 3]๋ฐ๋ฉด append๋ ๋ณต์ฌ๋ณธ ํค๋์ ๊ธธ์ด๋ง ๋๋ฆฌ๊ฑฐ๋, ์ฉ๋์ด ๋ชจ์๋ผ๋ฉด ์์ ์ ๋ฐฐ์ด์ ํ ๋นํ๋ค. ์ด๋ ์ชฝ์ด๋ ์๋ณธ ํค๋์ ๊ธธ์ด๋ ๊ทธ๋๋ก๋ผ ์ถ๊ฐ๋ถ์ด ๋ณด์ด์ง ์๋๋ค. (์ด ๋์์ 03ํธ์ ์ฌ๋ผ์ด์ฑยท์ ์ฅ ๊ณต๊ฐ ๊ณต์ ์ ์ด์ด์ง๋ค.)
func addItem(s []int) {
s = append(s, 99) // ๋ณต์ฌ๋ณธ ํค๋๋ง ๋ฐ๋
}
nums := []int{1, 2, 3}
addItem(nums)
// nums == [1 2 3] โ 99 ์ ๋ณด์๋งต๋ ๊ฐ์ ์๋ฆฌ๋ค. ๋งต ๊ฐ์ ๋ด๋ถ ํด์ ํ ์ด๋ธ์ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๋ผ์, ๋ณต์ฌ๋ผ๋ ๊ฐ์ ํ ์ด๋ธ์ ๊ณต์ ํ๋ค. ๊ทธ๋์ ํจ์ ์์์ ์ถ๊ฐยท์ญ์ ํ ํญ๋ชฉ์ด ์๋ณธ์ ๋ฐ์๋๋ค.
๊ณต์ฉ API์์๋ ๋งต์ ์ ๋ ฅยท๋ฐํ์ผ๋ก ์ฐ์ง ๋ง๋ผ
๋งต์ด ๊ณต์ ๋๊ณ ๊ตฌ์กฐ๋ ๋์จํ๋ค๋ ์ ๋๋ฌธ์, ์ค๊ณํ ๋ ์ฃผ์ํด์ผ ํ๋ค. ํนํ ๊ณต์ฉ API์ ์ ๋ ฅ ํ๋ผ๋ฏธํฐ๋ ๋ฐํ๊ฐ์ผ๋ก ๋งต์ ์ฐ๋ ๊ฒ์ ํผํ๋ ๊ฒ ์ข๋ค. ๋์ ๊ตฌ์กฐ์ฒด๋ฅผ ์ด๋ค.
// ๊ถ์ฅํ์ง ์์ โ ์ด๋ค ํค๊ฐ ์ ํจํ์ง ์๊ทธ๋์ฒ์ ๋๋ฌ๋์ง ์๋๋ค
func NewUser(data map[string]string) User { ... }
// ํธ์ถํ๋ ์ชฝ: "name"? "Name"? "username"? ๋ฌด์์ ๋ฃ์ด์ผ ํ๋
// ์คํ๊ฐ ๋๋ ์ปดํ์ผ๋ฌ๊ฐ ์ก์์ฃผ์ง ์๋๋ค// ๊ถ์ฅ โ ํ๋๊ฐ ์๊ทธ๋์ฒ์ ๋ช
์๋๊ณ ์ปดํ์ผ๋ฌ๊ฐ ๊ฒ์ฆํ๋ค
type UserInput struct {
Name string
Email string
}
func NewUser(in UserInput) User { ... }์ฐจ์ด๋ ๋ถ๋ช ํ๋ค.
- ์๊ธฐ ๋ฌธ์ํ โ ๊ตฌ์กฐ์ฒด๋ ์ด๋ค ํ๋๊ฐ ์๋์ง ํ์ ์ ์๋ง ๋ด๋ ์๋ค. ๋งต์ ์ฝ๋๋ฅผ ์ฝ์ด์ผ ์ ํจํ ํค๋ฅผ ์ ์ ์๋ค.
- ์ปดํ์ผ๋ฌ ๊ฒ์ฆ โ ๊ตฌ์กฐ์ฒด ํ๋๋ช ์ ์ปดํ์ผ ํ์์ ๊ฒ์ฌ๋๋ค. ๋งต ํค๋ ์คํ๊ฐ ๋๋ ๋ฐํ์๊น์ง ๋ชจ๋ฅธ๋ค.
- ์๋ณธ ๋ณดํธ โ ๋งต์ ๋๊ธฐ๋ฉด ํธ์ถ๋ ํจ์๊ฐ ์์๋ก ํค๋ฅผ ์ถ๊ฐยท์ญ์ ํ ์ ์๋ค. ๊ตฌ์กฐ์ฒด ๊ฐ์ ๋ณต์ฌ๋๋ฏ๋ก ์๋ณธ์ด ์์ ํ๋ค.
๋งต์ ์ปดํ์ผ ํ์์ ํค๋ฅผ ์ ์ ์๋, ์ง์ง ๋์ ์ธ ๋ฐ์ดํฐ์๋ง ์ฐ๋ ๊ฒ ๋ง๋ค. ํ๋๊ฐ ์ ํด์ ธ ์๋ค๋ฉด ๊ตฌ์กฐ์ฒด๊ฐ ๊ฑฐ์ ํญ์ ๋ซ๋ค.
6. ํฌ์ธํฐ๋ ์ตํ์ ์๋จ
Go ์ปค๋ฎค๋ํฐ์์๋ ํฌ์ธํฐ ์ฌ์ฉ์ ์ต์ํํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค. ์ด์ ๋ ๋ช ํํ๋ค.
- ๋ฐ์ดํฐ ํ๋ฆ์ด ๋ณต์กํด์ง๋ค โ ํฌ์ธํฐ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด์ ์ด๋์ ๊ฐ์ด ๋ฐ๋๋์ง ์ถ์ ํ๊ธฐ ์ด๋ ค์์ง๋ค
- GC ๋ถํ๊ฐ ์ฆ๊ฐํ๋ค โ ํ์ ํ ๋น๋ ํฌ์ธํฐ๊ฐ ๋ง์์๋ก ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ํ ์ผ์ด ๋์ด๋๋ค
- ๋์์ฑ์์ ์ํํ๋ค โ ํฌ์ธํฐ๋ฅผ ํตํด ๊ณต์ ์ํ๋ฅผ ๋ง๋ค๋ฉด ๊ฒฝ์ ์กฐ๊ฑด(race condition)์ด ๋ฐ์ํ๊ธฐ ์ฝ๋ค
ํฌ์ธํฐ ๋์ ๊ฐ์ ๋ฐํํ๋ ํจํด
๊ตฌ์กฐ์ฒด๋ฅผ ํจ์์ ๋๊ฒจ์ ์์ ํ๋ ๋์ , ํจ์ ์์์ ์๋ก ๋ง๋ค์ด์ ๋ฐํํ๋ ๊ฒ์ด ๊น๋ํ๋ค.
// ํฌ์ธํฐ๋ฅผ ์ฐ๋ ๋ฐฉ์
func initUser(u *User) {
u.Name = "Alice"
u.Age = 30
}
// ๊ฐ์ ๋ฐํํ๋ ๋ฐฉ์ (๊ถ์ฅ)
func newUser() User {
return User{
Name: "Alice",
Age: 30,
}
}ํฌ์ธํฐ๊ฐ ํ์ํ ๊ฒฝ์ฐ
๋ฌผ๋ก ํฌ์ธํฐ๊ฐ ๋ฐ๋์ ํ์ํ ์ํฉ๋ ์๋ค.
- ์ธํฐํ์ด์ค ์ถฉ์กฑ โ ๋ฉ์๋์ ๋ฆฌ์๋ฒ๊ฐ ํฌ์ธํฐ ํ์ ์ด์ด์ผ ํ๋ ๊ฒฝ์ฐ
- JSON ๋ง์ฌ๋ง โ
null๊ณผ zero value๋ฅผ ๊ตฌ๋ถํด์ผ ํ ๋ - ํฐ ๊ตฌ์กฐ์ฒด โ ๋ณต์ฌ ๋น์ฉ์ด ์ค์ธก์ผ๋ก ๋ฌธ์ ๊ฐ ๋ ๋
์ด๋ฐ ์ผ์ด์ค๋ ๋ณ๋ ๊ธ์์ ๋ค๋ฃฌ๋ค.
7. Go์ ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ๋ฉ๋ชจ๋ฆฌ
ํฌ์ธํฐ๋ฅผ ์ต์ํํ๋ผ๋ ์กฐ์ธ(6๋ฒ)์ ๋ฐฐ๊ฒฝ์๋ Go์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ๋ฐฉ์์ด ์๋ค. Go๋ ๊ฐ๋น์ง ์ปฌ๋ ํฐ(GC)๋ฅผ ๊ฐ์ง ์ธ์ด์ด๊ณ , ํฌ์ธํฐ๋ฅผ ์ด๋ป๊ฒ ์ฐ๋๋๊ฐ GC ๋ถํ์ ์ง์ ์ํฅ์ ์ค๋ค.
garbage์ ์คํยทํ
garbage๋ ํ๋ก๊ทธ๋จ์์ ๋ ์ด์ ๋๋ฌํ ์ ์๋(unreachable) ๋ฉ๋ชจ๋ฆฌ๋ค. ์ ์ญ ๋ณ์๋ ์คํ ์ค์ธ ํจ์์ ์ง์ญ ๋ณ์์์ ์ถ๋ฐํด ํฌ์ธํฐ๋ฅผ ๋ฐ๋ผ๊ฐ๋ ๋ฟ์ง ์๋ ๋ฐ์ดํฐ๋ฅผ ๋งํ๋ค. C์ฒ๋ผ ์ง์ freeํ์ง ์์๋, Go ๋ฐํ์์ด ์ด๋ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐพ์ ์๋์ผ๋ก ํ์ํ๋ค.
๋ฉ๋ชจ๋ฆฌ๊ฐ ์ด๋์ ํ ๋น๋๋์ง๊ฐ ์ค์ํ๋ค.
- ์คํ(stack) โ ํจ์์ ์ง์ญ ๋ณ์ยทํ๋ผ๋ฏธํฐ๊ฐ ์ฌ๋ผ๊ฐ๋ ์์ญ. ํ ๋น์ด ์ธ๊ณ (์คํ ํฌ์ธํฐ๋ง ์ด๋), ํจ์๊ฐ ๋๋๋ฉด ์๋์ผ๋ก ํด์ ๋๋ค. GC๊ฐ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์๋ค.
- ํ(heap) โ ํจ์๊ฐ ๋๋๋ ์ด์๋จ์์ผ ํ๋ ๋ฐ์ดํฐ๊ฐ ๊ฐ๋ ์์ญ. GC๊ฐ ์ถ์ ํ๊ณ ํ์ํด์ผ ํ๋ค. ํ ํ ๋น์ด ๋ง์์๋ก GC๊ฐ ํ ์ผ์ด ๋์ด๋๋ค.
escape analysis โ ๋ฌด์์ด ํ์ผ๋ก ๊ฐ๋๊ฐ
Go ์ปดํ์ผ๋ฌ๋ escape analysis๋ก ๊ฐ์ ์คํ์ ๋์ง ํ์ ๋์ง ๊ฒฐ์ ํ๋ค. ๊ธฐ์ค์ ๊ฐ ์์ฒด๊ฐ ์๋๋ผ, ๊ทธ ๋ณ์๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฐธ์กฐ๊ฐ ํจ์ ๋ฐ๊น์ง ์ด์๋จ์์ผ ํ๋๋๋ค. ๊ฐ์ ์ง์ญ ๋ณ์๋ผ๋ ๊ฐ์ผ๋ก ๋ฐํํ๋ฉด ์คํ์ ๋จธ๋ฌผ๊ณ , ์ฃผ์๋ก ๋ฐํํ๋ฉด ํ์ผ๋ก ๊ฐ๋ค(โescapeโ).
func valueReturn() int {
x := 10
return x // ๊ฐ์ ๋ณต์ฌ๋ณธ๋ง ๋๊ฐ โ x๋ ์คํ์ ๋จธ๋ฌพ, ํ ํ ๋น ์์
}
func pointerReturn() *int {
x := 10
return &x // x์ ์ฃผ์๊ฐ ๋ฐ์ผ๋ก ๋๊ฐ โ x๋ ํ์ผ๋ก escape
}๋ ํจ์์ ์ฐจ์ด๋ ํจ์๊ฐ ๋๋๋ ์๊ฐ์ ๋๋ฌ๋๋ค.
valueReturnโ ๋๋๊ธฐ ์ง์ ์x์ ๊ฐ(10)์ด ํธ์ถ ์ธก์ผ๋ก ๋ณต์ฌ๋๊ณ , ํจ์ ์คํ ํ๋ ์์ ํต์งธ๋ก ์ฌ๋ผ์ง๋ค. ํธ์ถ์๋ ์ด๋ฏธ ๋ณต์ฌ๋ณธ์ ๋ค๊ณ ์์ผ๋x๊ฐ ์์ด์ ธ๋ ๋ฌธ์ ์๋ค. ๊ทธ๋์ ์คํ์ ๋ฌ๋ ๋๋ค.pointerReturnโ ํธ์ถ์๊ฐx์ ์ฃผ์๋ฅผ ๋ค๊ณ ์๋๋ฐ, ํจ์๊ฐ ๋๋๋ฉด์ ๊ทธ ์ฃผ์์ ์คํ ์ฌ๋กฏ์ด ์ฌ๋ผ์ง๋ฉด ๊ฐ๋ฆฌํฌ ๊ณณ์ด ์์ด์ง๋ค(C๋ผ๋ฉด dangling pointer ๋ฒ๊ทธ๋ค). ๊ทธ๋์ ์ปดํ์ผ๋ฌ๋x๋ฅผ ์ฒ์๋ถํฐ ํ์ ์ฌ๋ ค ํจ์๊ฐ ๋๋๋ ์ด์์๊ฒ ๋ง๋ ๋ค.
์ฆ ๊ฐ ๋ณต์ฌ๋ escape๋ฅผ ์ผ์ผํค์ง ์๊ณ , ์ฃผ์(ํฌ์ธํฐ)๊ฐ ํ๋ ์ ๋ฐ์ผ๋ก ์์ด๋๊ฐ ๋๋ง ํ์ผ๋ก ๊ฐ๋ค. return &x๋ฟ ์๋๋ผ &x๋ฅผ ์ ์ญ ๋ณ์์ ์ ์ฅํ๊ฑฐ๋, ๋ฐ์ผ๋ก ํ์ถํ๋ ํด๋ก์ ๊ฐ x๋ฅผ ์บก์ฒํ๋ ๊ฒฝ์ฐ๋ ๊ฐ์ ์ด์ ๋ก escapeํ๋ค. ํ ํ ๋น์ด ๋๋ฉด GC ๋น์ฉ์ด ๋ฐ๋ผ์ค๋ฏ๋ก, ํฌ์ธํฐ๋ฅผ ๋จ๋ฐํ๋ฉด ๊ทธ๋งํผ GC ๋ถํ๊ฐ ์ปค์ง๋ค โ 6๋ฒ์์ โGC ๋ถํ๊ฐ ์ฆ๊ฐํ๋คโ๊ณ ํ ์ด์ ๋ค.
์ด๋ค ๊ฐ์ด escapeํ๋์ง๋ ์ปดํ์ผ๋ฌ์๊ฒ ๋ฌผ์ด๋ณผ ์ ์๋ค.
go build -gcflags="-m" main.go
# pointerReturn์์๋ง "moved to heap: x" ๊ฐ ๋ฌ๋คGC ๋ถํ๋ฅผ ์ค์ด๋ ํจํด
๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๋ฐฐ์นํ๋๋๋ก ํ ํ ๋น๊ณผ GC ๋ถํ๋ฅผ ์ค์ผ ์ ์๋ค.
๊ฐ ํ์
๊ณผ ์ฐ์ ๋ฉ๋ชจ๋ฆฌ. ๊ตฌ์กฐ์ฒด ์ฌ๋ผ์ด์ค([]Point)๋ ๋ฐ์ดํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ฐ์์ผ๋ก ๋์ด๊ณ ํ ๋น๋ ํ ๋ฒ์ด๋ค. ๋ฐ๋ฉด ํฌ์ธํฐ ์ฌ๋ผ์ด์ค([]*Point)๋ ์์๊ฐ ๋ฐ๋ก ํ์ ํ ๋น๋๊ธฐ ์ฌ์, GC๊ฐ ์ถ์ ํ ๋์์ด ๊ทธ๋งํผ ๋๊ณ ์บ์ ํจ์จ๋ ๋จ์ด์ง๋ค. ํน๋ณํ ์ด์ ๊ฐ ์์ผ๋ฉด ๊ฐ ์ฌ๋ผ์ด์ค๊ฐ ๋ซ๋ค.
๋ฒํผ ์ฌ๋ผ์ด์ค ์ฌ์ฌ์ฉ. ๋ฐ๋ณต๋ฌธ์์ ๋งค๋ฒ ์ ์ฌ๋ผ์ด์ค๋ฅผ ํ ๋นํ๋ฉด ๊ทธ๋งํผ garbage๊ฐ ์์ธ๋ค. ์ฌ๋ผ์ด์ค ํ๋๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋ฒํผ๋ก ์ฌ์ฌ์ฉํ๋ฉด ํ ๋น์ด ํ ๋ฒ์ผ๋ก ์ค๋ค.
// ๋งค ๋ฐ๋ณต๋ง๋ค ์๋ก ํ ๋น โ garbage ๋์
func process(r io.Reader) {
for {
buf := make([]byte, 1024) // ๋ฐ๋ณต๋ง๋ค ํ ๋น
n, err := r.Read(buf)
if n > 0 {
handle(buf[:n])
}
if err != nil {
break
}
}
}
// ๋ฒํผ ํ๋๋ฅผ ์ฌ์ฌ์ฉ โ ํ ๋น ํ ๋ฒ
func process(r io.Reader) {
buf := make([]byte, 1024) // ํ ๋ฒ๋ง ํ ๋น
for {
n, err := r.Read(buf) // ๊ฐ์ ๋ฒํผ์ ๋ฎ์ด์
if n > 0 {
handle(buf[:n])
}
if err != nil {
break
}
}
}Go GC์ ์ฑํฅ โ ์ ์ง์ฐ ์ฐ์
Go์ GC๋ ๋์(concurrent) ์ผ์ mark-and-sweep ๋ฐฉ์์ด๋ค. ํ๋ก๊ทธ๋จ์ ๋ฉ์ถ๊ณ ํ๊บผ๋ฒ์ ์ฒญ์ํ๋ ๋์ , ํ๋ก๊ทธ๋จ๊ณผ ๋์์ ๋๋ฉด์ ์ฐ๋ ๊ธฐ๋ฅผ ํ์ยทํ์ํ๋ค. ์ค๊ณ ์ฒ ํ์ ๋ฎ์ ์ง์ฐ์๊ฐ(low latency) ์ฐ์ ์ด๋ค. ์ ๊น ๋ฉ์ถ๋ stop-the-world ๊ตฌ๊ฐ์ ๊ทน๋๋ก ์งง๊ฒ ์ ์งํ๋ค(Go 1.8 ์ดํ ์๋ธ๋ฐ๋ฆฌ์ด ์์ค, ๋ณดํต ์๋ฐฑ ๋ง์ดํฌ๋ก์ด. ํ ํฌ๊ธฐ์ ๋ถํ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค). ๋์ ์ ์ฒด ์ฒ๋ฆฌ๋(throughput)์ ์ฝ๊ฐ ํฌ์ํ๋ ํธ๋ ์ด๋์คํ๋ฅผ ํํ๋ค. ์งง๊ณ ์์ธก ๊ฐ๋ฅํ ๋ฉ์ถค์ด ์๋ฒ ์๋ต์ฑ์ ์ค์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ ๊ฐ์ฒด๋ฅผ ์ฎ๊ธฐ์ง ์๋(non-compacting) ๋ฐฉ์์ด๋ผ, GC๊ฐ ๋์๋ ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ์ฃผ์๊ฐ ๋์ค์ ๋ฐ๋์ง ์๋๋ค.
๋์์ ์กฐ์ ํ๋ ํ๊ฒฝ ๋ณ์๊ฐ ๋ ์๋ค.
GOGCโ ๋ค์ GC๋ฅผ ์ธ์ ๋๋ฆด์ง ์ ํ๋ค. ๊ธฐ๋ณธ๊ฐ100์ ๋๋ต โ์ง์ GC ํ ์ด์๋จ์ ํ๋งํผ ์๋ก ํ ๋น๋๋ฉด(์ฆ ํ์ด ์ฝ ๋ ๋ฐฐ๊ฐ ๋๋ฉด) ๋ค์ GC๋ฅผ ๋๋ฆฐ๋คโ๋ ๋ป์ด๋ค. ๊ฐ์ ๋์ด๋ฉด GC๊ฐ ๋ ์์ฃผ ๋๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ์ฐ๋ฉฐ, ๋ฎ์ถ๋ฉด ์์ฃผ ๋๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋๋ค.GOMEMLIMITโ ์ํํธ ๋ฉ๋ชจ๋ฆฌ ํ๋(Go 1.19+). ํ์ด ์ด ํ๋์ ๊ฐ๊น์์ง๋ฉด GC๊ฐ ๋ ์ ๊ทน์ ์ผ๋ก ์ผํด์ ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ๋ฅผ ๋ง๋๋ค. ์ปจํ ์ด๋์ฒ๋ผ ๋ฉ๋ชจ๋ฆฌ ์ํ์ด ์๋ ํ๊ฒฝ์์ OOM ๋ฐฉ์ง์ ์ด๋ค.
GOGC ํธ๋ฆฌ๊ฑฐ๋ฅผ ๋ ์ ํํ
์์ โํ์ด ์ฝ ๋ ๋ฐฐโ๋ ์ง๊ด์ฉ ๊ทผ์ฌ๋ค. Go 1.18๋ถํฐ ์ค์ ํธ๋ฆฌ๊ฑฐ ๊ธฐ์ค์ ์ด์์๋ ํ๋ฟ ์๋๋ผ GC roots(๊ณ ๋ฃจํด ์คํยท์ ์ญ ํฌ์ธํฐ)๊น์ง ํฌํจํ๋ค. ์ ํํ ๊ณต์์
๋ชฉํ ํ = ์ด์์๋ ํ + (์ด์์๋ ํ + GC roots) ร GOGC / 100์ด๊ณ , GC roots๊ฐ ์์ ๋ ๊ทผ์ฌ์ ์ผ๋ก โ์ด์์๋ ํ์ ๋ ๋ฐฐโ๊ฐ ๋๋ค. (์ถ์ฒ: go.dev/doc/gc-guide)
Python์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ๋น๊ต
CPython์ ์ฐธ์กฐ ์นด์ดํ ์ด ๊ธฐ๋ณธ์ด๊ณ , ์ํ ์ฐธ์กฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ณ๋ GC๊ฐ ๋ณด์กฐ๋ก ๋๋ค. ์ฐธ์กฐ ์นด์ดํธ๊ฐ 0์ด ๋๋ ์ฆ์ ํด์ ๋๋ ๊ตฌ์กฐ๋ผ ์์ธก ๊ฐ๋ฅํ์ง๋ง, ์นด์ดํธ๋ฅผ ๊ฐฑ์ ํ๋ ๋น์ฉ์ด ์์ ๋ ๋ค. Go๋ ์ฐธ์กฐ ์นด์ดํ ์์ด ๋์ mark-sweep์ผ๋ก๋ง ๋๋ฉฐ, ๊ฐ ํ์ ๊ณผ ์คํ ํ ๋น์ ์ ๊ทน ํ์ฉํด ์ ์ด์ GC๊ฐ ๊ฑด๋๋ฆด ๋์์ ์ค์ด๋ ์ชฝ์ผ๋ก ์ค๊ณ๋๋ค.
Python ๊ฐ๋ฐ์๋ฅผ ์ํ ํ ์ค ์์ฝ
Python์์๋ ์ ๊ฒฝ ์ ์จ๋ ๋๋ ๊ฒ์ Go์์๋ ๋ช ์์ ์ผ๋ก ๋ค๋ค์ผ ํ๋ค. ๊ฐ์ด ๋ณต์ฌ๋๋์ง, ์ฐธ์กฐ๊ฐ ์ ๋ฌ๋๋์ง๋ฅผ ์ฝ๋์์ ์ง์ ๊ฒฐ์ ํ๋ ๊ฒ์ด Go ๋ฐฉ์์ด๋ค.