์ ํฌ ํ์ ๊ธ์ต์ฌ·์ผํ๋ชฐ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ์คํฌ๋ํ ์๋ฒ๋ฅผ ์ด์ํ๊ณ ์์ต๋๋ค. ์ด๋ ๋ ์ฌ๋ฌ ๋์ ์คํฌ๋ํ ์๋ฒ ์ค 3๋ฒ ์๋ฒ ํ ๋๋ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ 1GiB ๊ฐ๊น์ด ์ฅ ์ฑ 21์๊ฐ ๋์ ๋๋ ค์ฃผ์ง ์๋ ์ผ์ด ์์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๊ธฐ๋ํ๊ณ ๋์์ผ ๋ค๋ฅธ ์๋ฒ์ ๊ฐ์ ์์ค์ผ๋ก ๋์์์ต๋๋ค.
GC ๊ฐ ์๋ ๋ฐํ์์์ "๋ฉ๋ชจ๋ฆฌ๊ฐ ๋์์ค์ง ์๋๋ค"๋ ๋ง์ ๋ณดํต ๋ ๊ฐ์ง ์ค ํ๋์
๋๋ค. ๋๊ตฐ๊ฐ ์์ง ๊ทธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ฑฐ๋, ์ฐธ์กฐ๋ ๋๊ฒผ๋๋ฐ ๋ฐํ์์ด OS ์ ๋ฐ๋ฉํ์ง ์๊ณ ์๊ฑฐ๋. ์ด๋ฒ ๊ธ์ ์งํ์ ๋ฉ๋ชจ๋ฆฌ ๋คํ๋ก ์ด ๋์ ๊ฐ๋ฅด๊ณ , ๊ฒฐ๊ตญ ๋ฌธ์์ด์ str[i] ๋ก ํ ๊ธ์์ฉ ์ฝ๋ ํ๋ฒํ ์ฝ๋ ํ ์ค์ด static ์บ์์ ์ ์ ํค๋ฅผ 967๋ง ๊ฐ ์์ ๋ ๋
ผ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ ๋์์๋ค๋ ๊ฒ์ ๋ฐํ๋ธ ๊ธฐ๋ก์
๋๋ค.
๋ ผ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ ๋์(logical memory leak) : GC ๊ฐ ์๋ ์ธ์ด์์, ๋ ์ด์ ์ฐ์ง ์๋ ๊ฐ์ฒด๊ฐ GC ๋ฃจํธ์์ ์ฌ์ ํ ๋ฟ์ ์ ์๋ ์ํ๋ก ๋จ์ ํ์๋์ง ๋ชปํ๋ ๊ฒ. ๋ฉ๋ชจ๋ฆฌ๋ฅผ "์์ด๋ฒ๋ฆฐ" ๊ฒ์ด ์๋๋ผ "๋์ง ๋ชปํ" ๊ฒ์ ๋๋ค.
๊ธ์ ๋ฐฐ๊ฒฝ ๋ฐ ๋ฌธ์ ์ํฉ → ์์ ๋ฐ ํ๋ → ๊ฒฐ๊ณผ ๋ฐ ์ฑ๊ณผ ์์๋ก ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
๐ฉ๋ฐฐ๊ฒฝ ๋ฐ ๋ฌธ์ ์ํฉ
1๏ธโฃ๋ค์ด๊ฐ๊ธฐ ์ ์: JS ๋ฅผ ์คํํ๋ C# ์์ง
์ด ๊ธ์๋ "JS ์์ง", "์์ฑ ํค", "์บ์" ๊ฐ์ ๋ง์ด ๊ณ์ ๋์ต๋๋ค. ์ฌ๋ด ์ ํ๋ฆฌ์ผ์ด์ ์ TypeScript ๋ก ์์ฑํ ๋น์ฆ๋์ค ๋ก์ง์ JavaScript ๋ก ๋น๋ํด ๋๊ณ , ๊ธฐ๋ํ ๋ ๊ทธ JS ๋ฅผ ์ฝ์ด ๋์๋ค๊ฐ ์์ฒญ์ด ์ค๋ฉด ํด๋น ํจ์๋ฅผ ์คํํฉ๋๋ค.

Chrome ์ด๋ Node.js ๊ฐ V8 ์์ง์ผ๋ก JS ๋ฅผ ์คํํ๋ฏ, ์ ํฌ๋ C#(.NET 10)์ผ๋ก ๋ง๋ ์์ฒด JS ์์ง์ผ๋ก JS ๋ฅผ ์คํํฉ๋๋ค.
๊ทธ๋์ JS ์ฝ๋๊ฐ ๋ง๋๋ ๊ฐ์ฒด๋, ์์ง ๋ด๋ถ์ ์บ์๋ ๋ชจ๋ .NET ๊ด๋ฆฌ ํ(managed heap)์ ์๊ธฐ๊ณ .NET GC ๊ฐ ๊ด๋ฆฌํฉ๋๋ค. ์ด๋ฒ ์ฌ๊ณ ๋ฅผ dotnet-dump ๊ฐ์ .NET ์ง๋จ ๋๊ตฌ๋ก ์ถ์ ํ ์ ์์๋ ์ด์ ์
๋๋ค.
2๏ธโฃ3๋ฒ ์๋ฒ๋ง ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋์์ค์ง ์์๋ค
10์ 1์ผ 19์ 25๋ถ๊ฒฝ 3๋ฒ ์๋ฒ์ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ๊ฐ 1.4GiB ์์ 0.48GiB ๋ก ์ฝ 1GiB ๋จ์ด์ง ๋ค ํ๋ณต๋์ง ์์์ต๋๋ค. ์ ๋ฌด๊ฐ ๊ฑฐ์ ์๋ ์ผ๊ฐ๊ณผ ์๋ฒฝ์๋, ๋ค์ ๋ ์ ๋ฌด ์๊ฐ์๋ 0.5GiB ์ํ์ ๋จธ๋ฌผ๋ ๊ณ , ๋ค๋ฅธ ์คํฌ๋ํ ์๋ฒ๋ค์ ํ์์ ๊ฐ์์ต๋๋ค. ์ด ์ํ๋ ์ฝ 21์๊ฐ ์ด์ด์ง๋ค๊ฐ 10์ 2์ผ 17์๊ฒฝ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๊ธฐ๋ํ๊ณ ๋์์ผ ํ๋ ธ์ต๋๋ค.

| ํญ๋ชฉ | ๊ฐ |
| 3๋ฒ ์๋ฒ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ (10-01 19:25) | 1.4 GiB → 0.48 GiB (์ฝ 1 GiB ๊ฐ์) |
| ํ๋ณต๋์ง ์๊ณ ์ ์ง๋ ์๊ฐ | ์ฝ 21์๊ฐ (10-02 17์ ์ฌ๊ธฐ๋๊น์ง) |
| ์๋ฒ ์ฌ์ | 4์ฝ์ด / 8GB |
| ๊ฐ์ ์ญํ ์๋ฒ ์ค ์ฆ์์ด ๋ ์๋ฒ | 3๋ฒ 1๋ |
3๏ธโฃGrafana ์งํ๋ก ๋ฒ์ ์ขํ๊ธฐ
๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋จ์ด์ง 19์ 25๋ถ ์๋ค 5๋ถ์ ํ๋ํด ๋ดค์ต๋๋ค.

- ๋ฉ๋ชจ๋ฆฌ : 19์ 25๋ถ 26์ด๋ถํฐ 3๋ฒ๋ง ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ๊ฐ 1.5GiB → 0.5GiB ๋ก ๋จ์ด์ก์ต๋๋ค.
- CPU : ๊ฐ์ ์๊ฐ ์ฝ 20%p ์ฌ๋ผ 55 ~ 58% ๊ตฌ๊ฐ์์ ์ฝ 40์ด ๋จธ๋ฌผ๋ ์ต๋๋ค(์ต๊ณ 58.4%).
- Paging File : ์ฝ 8% → 12% ๋ก ์ฌ๋์ต๋๋ค.
- Processor Queue Length : 7๋ฒ ์๋ฒ์ ๋น์ทํ์ต๋๋ค.
ํ ํฝ ์ฌ๋ฌ ๊ฐ๋ฅผ ๋์์ ์๋นํด์ ์ผ์ด ๋ง์์ง ๊ฒ์ด๋ผ๋ฉด ๋๊ธฐ ํ ๊ธธ์ด๋ ํจ๊ป ๋์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ๊ทธ๋ ์ง ์์์ผ๋ "ํ ํฝ ๋ฉ์ธ์ง ์ฌ๋ฌ ๊ฐ"๊ฐ ์๋๋ผ ํ ํฝ ๋ฉ์ธ์ง ํ๋์์ ๋ฌด๊ฑฐ์ด ์ฐ์ฐ์ด ์ผ์ด๋ฌ๋ค๊ณ ์ถ์ ํ์ต๋๋ค.

๋คํธ์ํฌ์์๋ ๊ฐ์ ๊ทธ๋ฆผ์ด ๋์์ต๋๋ค. 19์ 25๋ถ 30์ด์ 3๋ฒ ์๋ฒ๋ก 26.3Mb/s ์์ ์คํ์ดํฌ(๊ฐ์ ์๊ฐ 7๋ฒ์ 12.5kb/s)๊ฐ ์์๊ณ , ์ฝ 50์ด ๋ค 3๋ฒ๋ง ์ฝ 17Mb/s ์ก์ ์คํ์ดํฌ๊ฐ ์์์ต๋๋ค.
์์ ์ ์ธ๋ถ ์์ง์ฒ์์ ๋งค์ฐ ํฐ ์๋ต์ ๋ฐ์๋ค๋ ๋ป์ด๊ณ , ์ก์ ์ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์์ปค ์๋ฒ์ ๋๊ธฐ๋ ค๊ณ ๋ฉ์์ง ํ ํ ์ด๋ธ์ ํฐ ์ฐ๊ธฐ๋ฅผ ํ๋ค๋ ๋ป์ผ๋ก ํด์ํ์ต๋๋ค.
4๏ธโฃ์์์ ์ ๊ณ ๋๋ชฐ ์ฃผ๋ฌธ ์์ง ํ ๊ฑด
์ธ๋ถ ์๋ต ํฌ๊ธฐ๋ฅผ ์ง์ ๋จ๊ธฐ๋ ์งํ๋ ์์ด์, ๊ทธ ์๊ฐ์ ์กด(Zone: ์ฌ๋ด์์ ์ฐ๋ ์ด์ ๊ตฌ์ญ)๋ณ๋ก ๋ฉ์์ง ํ๋ก ๋ฐํ๋ ํ ํฝ์ ๋ชจ๋ํฐ๋ง ํ๋ ๋ฉ๋ด๋ก ์กฐํํด ๋ดค์ต๋๋ค. ๋๋ถ๋ถ์ ์กด์ 10๊ฐ ๋ฏธ๋ง์ด์๋๋ฐ, ํ ํ์ฌ์์๋ง 19์ 26๋ถ 22์ด์ ํ ํฝ 385๊ฐ๊ฐ ํ๊บผ๋ฒ์ ๋ฐํ๋์ต๋๋ค. ๋ฐํํ ์๋ฒ๋ ์ญ์ 3๋ฒ์ด์์ต๋๋ค.

ํ ํฝ ๋ฉ์ธ์ง๋ฅผ ํ์ธํด ๋ณด๋ ์ผํ๋ชฐ ์ค์ ์ ๊ณตํ๋ ์ธ๋ถ์์ง์ฒ์ธ ๊ณ ๋๋ชฐ ์ฃผ๋ฌธ ์์ง 1๊ฑด์ด์์ต๋๋ค. ์กฐํ๋ฅผ ํตํด ์ป์ ์์ง ๋ฐ์ดํฐ ๊ฒฐ๊ณผ๋ 10๊ฑด์ฉ ์๋ผ ํ ํฝ ํ๋๋ก ๋ฐํํ๋ฏ๋ก, 385๊ฐ ํ ํฝ ๋ฉ์ธ์ง๋ฉด ํ ๋ฒ์ ์ต๋ 3,850๊ฑด์ ์์งํ๋ค๋ ๋ป์ ๋๋ค. ๊ฒ๋ค๊ฐ ๊ณ ๋๋ชฐ์ ์๋ต์ JSON ์ด ์๋๋ผ XML ๋ก ์ค์ ํ๊ทธ ๋๋ฌธ์ ์๋ต์ด ํจ์ฌ ํฝ๋๋ค.
์์ ํธ๋ํฝ์ด ๊ทธ๋ ๊ฒ ์ปธ๋ ์ด์ ๊ฐ ์ฌ๊ธฐ์ ์ค๋ช ๋ฉ๋๋ค.
ํ์ง๋ง ์ด๊ฒ์ผ๋ก ์ค๋ช ๋๋ ๊ฑด "์์งํ๋ ๋์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ง์ด ์ผ๋ค"๊น์ง์ ๋๋ค. ์์ญ MB ์๋ต์ด UTF-16 ๋ฌธ์์ด๋ก ๋ ๋ฐฐ๊ฐ ๋๊ณ , ํํฐ๋ฅผ ๊ฑฐ์น ๋ณต์ฌ๋ณธ๊ณผ XML DOM ๊น์ง ํ๊บผ๋ฒ์ ์๊ธฐ๋ ์๊ฐ์ ์ผ๋ก ์ปค์ง๋ ๊ฑด ์์ฐ์ค๋ฝ์ต๋๋ค. ์์ ์ด ๋๋ ๋ค์๋ 21์๊ฐ ๋์ ๋๋ ค์ฃผ์ง ์์ ๊ฒ์ ์ ํ ๋ค๋ฅธ ๋ฌธ์ ์์ต๋๋ค.
5๏ธโฃ ๋คํ๋ฅผ ๋จ๊ธฐ ์ ์ ์ธ์ด ๊ฐ์ค
๊ณ ๋๋ชฐ ์์ง ๋น์ฆ๋์ค ๋ก์ง(TS)๊ณผ ์ผํ๋ชฐ ๊ณตํต ๋ก์ง์ ์ฝ์ด ๋ดค์ง๋ง, ์์ง ๋ฐ์ดํฐ๋ฅผ static ์ด๋ ๋ชจ๋ ์ ์ญ์ ๋ค๊ณ ์๋ ์ฝ๋๋ ์์์ต๋๋ค. ๊ทธ๋์ ๊ฐ์ค์ ์ธ ๊ฐ ์ธ์ ์ต๋๋ค.
| ๊ฐ์ค | ๋ด์ฉ | ๋น์ ํ๋จ |
| โ ์ด์ ์๋ ์ฐธ์กฐ | ์ด๋๊ฐ์์ ํฐ ์๋ต ๋ฌธ์์ด์ด๋ XML DOM ์ ๊ณ์ ์ฐธ์กฐํ๊ณ ์๋ค | ๋น์ฆ๋์ค ์ฝ๋์์๋ ๋ชป ์ฐพ์. ํ๋ ์์ํฌ·์์ง ์ชฝ์ ๋ฏธํ์ธ |
| โก LOH ์กฐ๊ฐํ / ํ ๋ฏธ๋ฐ๋ฉ | ์ฐธ์กฐ๋ ๋๊ฒผ์ง๋ง ์์ญ MB ๋ฌธ์์ด์ด LOH ์ ์ฌ๋ผ๊ฐ๋ค ๋น ์ง๋ฉฐ ์กฐ๊ฐ๋, ๋น ๊ณต๊ฐ์ OS ์ ๋๋ ค์ฃผ์ง ๋ชปํ๋ค | ์ฒ์์๋ ๊ฐ์ฅ ์ ๋ ฅ |
| โข ๋ค์ดํฐ๋ธ ๋ฉ๋ชจ๋ฆฌ | GC ๊ฐ ๊ด๋ฆฌํ์ง ์๋ ๋ค์ดํฐ๋ธ ๋ฒํผ๊ฐ ๋จ์ ์๋ค | ๋คํ ์์ด๋ ๊ฐ๋ฆด ์ ์์ |
๊ทธ๋ฐ๋ฐ ์๋ฒ์ runtimeconfig.json ์ ๋ณด๋ GC ์ค์ ์ด ์์ด Workstation GC ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋๊ณ ์์์ต๋๋ค. "ํ์๋ ํ๋๋ฐ OS ์ ๋ฐ๋ก ๋๋ ค์ฃผ์ง ์๋" ์ฑํฅ์ ์ฝ์ด๋ง๋ค ํ์ ํฌ๊ฒ ์ก๋ Server GC ์ชฝ ์ด์ผ๊ธฐ์ด๊ณ , ๊ฒ๋ค๊ฐ 21์๊ฐ ๋์ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ฐ๋ฅ์ด์์ผ๋ GC ๋ ๊ทธ์ฌ์ด ์ฌ๋ฌ ๋ฒ ๋์์ ๊ฒ๋๋ค. ๊ทธ๋ฐ๋ฐ๋ 1GiB ๊ฐ ๊ทธ๋๋ก์๋ค๋ฉด โก ๋ณด๋ค๋ โ ์ด์ ์๋ ์ฐธ์กฐ ์ชฝ์ ๋ฌด๊ฒ๊ฐ ์ค๋ ธ์ต๋๋ค.
๋ค๋ง ๋๊ฐ ์ฅ๊ณ ์๋์ง๋ ์ฝ๋๋ฅผ ๋์ผ๋ก ์ซ์์๋ ๊ฐ๋ฆด ์ ์์์ต๋๋ค. ๊ทธ๋์ ๊ฐ์ ํ์์ ์ผ๋ถ๋ฌ ์ฌํํ๊ณ , ๊ทธ ์๊ฐ์ ํ์ ๋คํ๋ก ๋ ์ ์ง์ ๋ณด๊ธฐ๋ก ํ์ต๋๋ค.
๐์์ ๋ฐ ํ๋
1๏ธโฃ์ธก์ ๋๊ตฌ: ์ถ์ด 2๊ฐ + ๋คํ
๋คํ๋ ํ ์๊ฐ์ ์ฌ์ง์ด๋ผ, ๊ทธ๊ฒ๋ง์ผ๋ก๋ "์ฌํ์ด ๋๋์ง"์กฐ์ฐจ ์ ์ ์์ต๋๋ค. ๊ทธ๋์ ์๊ฐ ํ๋ฆ์ ๋จ๊ธฐ๋ ๋๊ตฌ ๋ ๊ฐ๋ฅผ ํจ๊ป ์ผ ๋๊ณ , ์ ํด์ง ์์ ์ ๋คํ๋ฅผ ๋ด์ต๋๋ค.
| ๋๊ตฌ | ๋จ๊ธฐ๋ ๊ฒ | ๋ตํ๋ ์ง๋ฌธ |
| typeperf | ํ๋ก์ธ์ค Private Bytes, Working Set, ์๋ฒ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ, CPU ๋ฅผ 5์ด๋ง๋ค | OS ๊ด์ . ์ธ์ , ์ผ๋ง๋ ๋๊ณ ์ค์๋ |
| dotnet-counters | ์ธ๋๋ณ GC ํ ํฌ๊ธฐ, GC ํ์, ๋ฉ์ถค ์๊ฐ, ํ ๋น๋์ 5์ด๋ง๋ค | ๋ฐํ์ ๊ด์ . ๊ด๋ฆฌ ํ์ด ๋์๋, GC ๋ ๋์๋ |
| dotnet-dump | ๊ทธ ์๊ฐ์ ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ ์ ์ฒด(.dmp) | ํ ์. ๋ฌด์จ ๊ฐ์ฒด๊ฐ ๋ช ๊ฐ ์๊ณ ๋๊ฐ ์ฐธ์กฐํ๋ |
typeperf "\Process(<ํ๋ก์ธ์ค๋ช
>)\Private Bytes" "\Process(<ํ๋ก์ธ์ค๋ช
>)\Working Set" "\Memory\Available MBytes" "\Processor(_Total)\% Processor Time" -si 5 -o mem.csv
dotnet-counters collect -p <PID> --counters System.Runtime --refresh-interval 5 --format csv -o counters.csv
dotnet-dump collect -p <PID> -o dump2_after.dmp
Private Bytes ์ GC ํ์ ๊ฐ์ด ๋ณด๋ฉด ๋ฐฉํฅ์ด ์ ํด์ง๋๋ค. Private Bytes ๋ง ์ค๋ฅด๊ณ GC ํ์ด ๊ทธ๋๋ก๋ฉด ๋ค์ดํฐ๋ธ ๋ฉ๋ชจ๋ฆฌ, ๋์ด ๊ฐ์ด ์ค๋ฅด๋ฉด ๊ด๋ฆฌ ํ์ ์ด์ ์๋ ์ฐธ์กฐ๊ฐ ์๋ค๋ ๋ป์ ๋๋ค.
์์ ๊ด๋ฆฌ์๋ tasklist ์ ๋ฉ๋ชจ๋ฆฌ ๊ฐ(Working Set)์ ์ฐ์ง ์์์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ์๋ฒ์์๋ ๋์คํฌ๋ก ๋ฐ๋ ค๋ ์ค์ด๋ ๊ฒ์ฒ๋ผ ๋ณด์ผ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
2๏ธโฃ์ฌํ ํ๊ฒฝ: ๋ชฉ์๋ฒ์ ํฐ ์๋ต
์ด์ ์๋ฒ์์ ์ผ๋ถ๋ฌ ์ฌ๊ณ ๋ฅผ ๋ผ ์๋ ์์ผ๋ ํ ์คํธ ์คํฌ๋ํ ์๋ฒ์์ ๊ฐ์ ์ํฉ์ ๋ง๋ค์์ต๋๋ค.
- ์๋ต ํ์ผ : ์ค์ ๊ณ ๋๋ชฐ ์ฃผ๋ฌธ ๋ฐ์ดํฐ ์กฐํ HTTP Response ํ๋๋ฅผ ๊บผ๋ด, ํค๋์ ๋ฉํ ์ ๋ณด๋ ๊ทธ๋๋ก ๋๊ณ ์ฃผ๋ฌธ ๋ชฉ๋ก๋ง ์ฌ๊ณ ๋น์ ์์ค(3,850ํ)์ผ๋ก ๋๋ ธ์ต๋๋ค.
- ๋ชฉ์๋ฒ : ์ PC ์ ์์ Node.js ์๋ฒ๋ฅผ ๋์, ์์ฒญ์ด ์ค๋ฉด ๊ทธ ํ์ผ์ XML ๋ก ์๋ตํ๊ฒ ํ์ต๋๋ค. ํ ์คํธ ์๋ฒ๊ฐ ๋คํธ์ํฌ๋ฅผ ํ๊ณ ์ PC ๋ก ์์ฒญ์ ๋ณด๋ด๊ฒ ํด์ ์ค์ ํต์ ๊ณผ ์ต๋ํ ๋น์ทํ๊ฒ ๋ง์ท์ต๋๋ค.
- ์์ ๋น๋ : ๊ณ ๋๋ชฐ ์ ๊ท ์ฃผ๋ฌธ ์กฐํ URL ๋ง ๋ชฉ์๋ฒ ์ฃผ์๋ก ๋ฐ๊ฟ ํ ์คํธ ์๋ฒ์ ๋ฐฐํฌํ์ต๋๋ค. ์๋ต์ ๋ฐ์ ๋ค์ ์ฒ๋ฆฌ ๊ฒฝ๋ก๋ ์ด์๊ณผ ๊ฐ์ต๋๋ค.

3๏ธโฃํ ์คํธ ์๋๋ฆฌ์ค
- ๊ธฐ๋ก ์์ + ์๋ฐ์
: typeperf, dotnet-counters ๋ฅผ ์ผ ๋๊ณ ์นด๋·์ํ·์ผํ๋ชฐ ์กฐํ๋ฅผ ์ฌ๋ฌ ๋ฒ ๋๋ ค ๋ฉ๋ชจ๋ฆฌ๊ฐ ํํํด์ง ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. ๊ธฐ๋ ์งํ์ ์์ฐ์ค๋ฌ์ด ์ฆ๊ฐ๋ฅผ ์์ง ๋๋ฌธ์ผ๋ก ์คํดํ์ง ์๊ธฐ ์ํด์์
๋๋ค.
- ์์ง ์ ๋คํ : ์์
์ด ์๋ ์๊ฐ์ ๋น๋๋ค. "์๋ ์๋ ๊ฒ"๊ณผ "์๋ก ์๊ธด ๊ฒ"์ ๊ฐ๋ฅด๋ ๊ธฐ์ค์
๋๋ค.
- ๊ณ ๋๋ชฐ ์์ง 1ํ : ๋ชฉ์๋ฒ ์ฝ์์ ์์ฒญ๊ณผ ์๋ต ํฌ๊ธฐ๊ฐ ์ฐํ๋์ง ๋ด
๋๋ค.
- +10๋ถ ๋คํ : ๊ทธ์ฌ์ด ๋ค๋ฅธ ์กฐํ๋ฅผ ๋ช ๋ฒ ๋๋ ค GC ๊ฐ ๋ ๊ธฐํ๋ฅผ ์ค๋๋ค. GC ๋ ์๊ฐ์ด ์ง๋๋ค๊ณ ๋๋ ๊ฒ ์๋๋ผ ํ ๋น์ด ์์ฌ์ผ ๋๊ธฐ ๋๋ฌธ์
๋๋ค. "์์ง GC ๊ฐ ์ ๋์์ ๋จ์ ๊ฒ"๊ณผ "GC ๊ฐ ๋์๋ ๋จ๋ ๊ฒ"์ ๊ฐ๋ฅด๊ธฐ ์ํ ๋คํ์
๋๋ค.
- +30๋ถ ๋คํ : ๋ค์ ์์ฒญ์ ๋ณด๋ด๊ณ ๋ง์ง๋ง ๋คํ๋ฅผ ๋น๋๋ค. "์ ์ ๋จ์ ๊ฒ"์ธ์ง "์๊ตฌํ ๋จ๋ ๊ฒ"์ธ์ง๋ฅผ ํ๋จํฉ๋๋ค.
ํ์ ๊ธฐ์ค์ ์คํ ์ ์ ์ ํด ๋์ต๋๋ค. ์์ง 10๋ถ ๋ค ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ธฐ์ค์ ์ผ๋ก ๋์์ค๋ฉด ์ฌํ ์คํจ, ์ฌ๋ผ๊ฐ ์ฑ ์ ์ง๋๋ฉด ์ฌํ ์ฑ๊ณต์ ๋๋ค.
4๏ธโฃ1์ฐจ ์ฌํ(30MB): ํ ์คํธ ์๋ฒ๊ฐ ์ฐ๋ฌ์ก๋ค
์ด์๊ณผ ์ต๋ํ ๊ฐ๊ฒ ํ๋ ค๊ณ 30MB ์๋ต์ผ๋ก ์์ํ๋๋ฐ, ํ ์คํธ ์คํฌ๋ํ ์๋ฒ๊ฐ ๋ฒํฐ์ง ๋ชปํ์ต๋๋ค. ์ด์ ์๋ฒ๋ 4์ฝ์ด / 8GB ์ธ๋ฐ ํ ์คํธ ์๋ฒ๋ 4์ฝ์ด / 4GB ์๊ณ , ์์ง ์ ๋ถํฐ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฝ 0.9GB ๋ฟ์ด์์ต๋๋ค. (์ด ์ผ ๋ค๋ก ์ธํ๋ผ ํ์์ ์ ์ด์ ๊ฐ์ฉ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋๋ฌด ์ ์ ๊ฒ ๊ฐ๋ค๊ณ ํ ์คํธ ์๋ฒ๋ 8GB ๋ก ๋๋ ค ์ฃผ์ จ์ต๋๋ค.)
์๋ฐํ๋ .NET ์ OutOfMemoryException ์ด ์๋๋ผ ์๋ฒ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ณ ๊ฐ๋์ด ์๊ฒฉ ์ธ์
๊น์ง ๋ฌด๋์ง ๊ฒ์
๋๋ค. .NET ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ ์ํ์ด ์์ด์ ํ๋ก์ธ์ค๋ ์กฐ์ฉํ ๊ณ์ ์ปค์ง๊ณ , ์๋ฒ์ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ๋จผ์ ์ฃฝ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด ์คํจํ ์คํ์ด ์คํ๋ ค ๊ฒฐ์ ์ ์ธ ์๋ฃ๋ฅผ ๋จ๊ฒผ์ต๋๋ค. "์์ง๋ ์ ๋๋๋ค?" ์ถ์ด ์์ง ๋์ค์ ๋ ๋ ์ค๊ฐ ๋คํ(5.85GB)์, ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ถ์ก๊ณ ์๋ ๊ฐ์ฒด์ ๊ทธ ์๊ฐ ์คํ ์ค์ด๋ ํจ์๊ฐ ๊ทธ๋๋ก ์ฐํ ์์์ต๋๋ค. ์ด ๋คํ์์ ์บ์ ๋ ธ๋๋ ์ด๋ฏธ ์ฝ 2,039๋ง ๊ฐ์์ต๋๋ค. ๋ค์์ ๋ค์ ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค.
5๏ธโฃ2์ฐจ ์ฌํ(10MB): ์ฌํ ์ฑ๊ณต
์๋ต์ 10MB ๋ก ์ค์ด์ ์์ง์ ์ ์ ์๋ฃ๋๊ณ (ํ ํฝ 134๊ฑด ๋ฐํ), 10๋ถ ๋ค์ 30๋ถ ๋ค ๋คํ๋ ์จ์ ํ ๋ด์ต๋๋ค.
| ์์ | Private Bytes | GC 2์ธ๋ ํ | ์๋ฒ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ |
| 21:16 ์๋ฐ์ ์ค | 1,715 MB | 1,627 MB | 1,126 MB |
| 21:20 ์์ง ์์ | 1,780 MB | 1,638 MB | 564 MB |
| 21:23 ์์ง ์ค ์ต๊ณ ์ | 3,721 MB | 3,355 MB | 74 ~ 400 MB |
| 21:38 +10๋ถ ๋คํ ์ง์ | 3,420 MB | 3,087 MB | 927 MB |
| 21:43 72์ด์ง๋ฆฌ ์ ์ฒด GC ๋ค | 3,305 MB | 3,034 MB | 940 MB |
| 22:11 ๊ธฐ๋ก ์ข ๋ฃ | 3,306 MB | 3,050 MB | 297 MB |
์์ง์ด ๋๋ ๋ค ์ ์ฒด GC ๊ฐ 21:41, 21:43, 22:02 ์ธ ๋ฒ ๋์๊ณ , 21:43 ์ ๊ฒ์ 72์ด ๋์ ์์ปค๋ฅผ ๋ฉ์ถ blocking GC ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ๋ 2์ธ๋ ํ์ ์ฝ 3,034MB ์ ๊ณ ์ ๋์ต๋๋ค. ๊ธฐ์ค ๋๋น ์ฝ 1,407MB ๊ฐ GC ๋ฅผ ์ธ ๋ฒ ๊ฑฐ์น๊ณ ๋ ๋จ์ ๊ฒ์ ๋๋ค.
Private Bytes ์ฆ๊ฐ 1,585MB ์ค GC ํ ์ปค๋ฐ ์ฆ๊ฐ๊ฐ 1,521MB ์์ผ๋ ๋ค์ดํฐ๋ธ ๋ฉ๋ชจ๋ฆฌ(๊ฐ์ค โข)๋ ์ฃผ ์์ธ์ด ์๋์์ต๋๋ค. ๊ด๋ฆฌ ํ ์์ ๋ฌด์ธ๊ฐ๊ฐ ์ด์ ์๋ค๋ ๋ป์ด๊ณ , ์ด์ ๋คํ์์ ์ฐพ์ผ๋ฉด ๋ฉ๋๋ค.
6๏ธโฃ๋คํ ๋ถ์: ํฐ ๊ฒ์์ ์์ ๊ฒ์ผ๋ก
์๋๋ ์์ ์ ์ฌํ์ 30๋ถ ๋ค ๋คํ๋ฅผ ๋ถ์ํ ๊ณผ์ ์ ๋๋ค. ๋ณด๋ค๊ฐ ์์ธํ๊ฒ ๋ฉ๋ชจ๋ฆฌ ๋คํ๋ฅผ ๋ถ์ํ๋ ๋ด์ฉ์ ๋ฐ๋ก ๊ธ๋ก ์์ฑํด๋์ต๋๋ค. ์๋ ๊ธ์์ ๋ณด์ค ์ ์์ต๋๋ค.
https://programmer-may.tistory.com/286
๋ฉ๋ชจ๋ฆฌ ๋คํ ์ง์ ์ด์ด ๋ณด๊ธฐ : dotnet-dump analyze์ WinDbg ๋ก ๋ฉ๋ชจ๋ฆฌ ๋์ ์ถ์ ํ๊ธฐ
10์ 2์ผ ์ด์ ์ค์ธ ์คํฌ๋ํ ์๋ฒ์ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ฐ์๊ธฐ ๋ ๋จ์ด์ง ๋ค ์ ํ๋ฆฌ์ผ์ด์ ์ฌ๊ธฐ๋ํ ๋๊น์ง ๋จ์ด์ง ์ํ๋ก ์ ์ง๊ฐ ๋๋ ์ผ์ด ์์์ต๋๋ค. ์์ธ์ ์ฝ๋ ํ ์ค๊ณผ ์ฌ๋ด ์ ํ๋ฆฌ์ผ์ด์ ์
programmer-may.tistory.com
โ ํ์ด ์ผ๋ง๋ ํฐ๊ฐ — eeheap -gc
๊ด๋ฆฌ ํ์ ์ ์ฒด ํฌ๊ธฐ, ์ธ๋๋ณ ์์ญ, GC ๋ชจ๋๋ฅผ ํ ๋ฒ์ ๋ณด์ฌ ์ฃผ๋ ๋ช ๋ น์ ๋๋ค. ์ด ๋คํ๊ฐ ์ ๋ง ๋ฌธ์ ์ํ๋ฅผ ์ฐ์ ๊ฒ์ธ์ง๋ถํฐ ํ์ธํฉ๋๋ค.

- Number of GC Heaps: 1 → ํ์ด ํ๋์ด๋ Workstation GC ๊ฐ ๋ง์ต๋๋ค(Server GC ๋ฉด ์ฝ์ด ์๋งํผ ๋์ต๋๋ค).
- 2์ธ๋(generation 2) ์์ญ ์ค์ด ํ๋ฉด์ ๊ฐ๋ ์ฑ์๋๋ค. ์ค๋ ์ด์๋จ์ ๊ฐ์ฒด๊ฐ ์์ฌ ์๋ค๋ ๋ป์ ๋๋ค.
- GC Allocated Heap Size 3,360,537,568 B (์ฝ 3.36 GB). ์์ง ์ ์ฝ 1.7GB ์ ๋ ๋ฐฐ์ ๋๋ค.
- Large object heap ์์ญ ์ค ํ๋๊ฐ 95,991,648 B(์ฝ 96 MB)์ธ๋ฐ, ์ด๊ฒ ๋ค์์ ๋์ฌ ๋ฒํท ๋ฐฐ์ด์ ๋๋ค.
โก ๋ฌด์จ ํ์
์ด ์ฐจ์งํ๊ณ ์๋ — dumpheap -stat
ํ ์ ์ฒด๋ฅผ ํ์ด ํ์ ๋ณ ๊ฐ์์ ์ด ๋ฐ์ดํธ๋ฅผ ์ง๊ณํฉ๋๋ค. ํฌ๊ธฐ ์ค๋ฆ์ฐจ์์ด๋ผ ๋งจ ์๋๊ฐ ๊ฐ์ฅ ํฐ ํ์ ์ ๋๋ค.

| ํ์ | ๊ฐ์ | ์ด ํฌ๊ธฐ |
| System.Int32 | ์ฝ 968๋ง ๊ฐ (9,677,949) | 232,270,776 B (์ฝ 232 MB) |
| JSKey | ์ฝ 978๋ง ๊ฐ (9,778,329) | 391,133,160 B (์ฝ 391 MB) |
| System.String | ์ฝ 1,006๋ง ๊ฐ (10,062,683) | 392,637,270 B (์ฝ 393 MB) |
| ConcurrentDictionary<Object, JSKey>+Node | ์ฝ 978๋ง ๊ฐ (9,777,304) | 469,310,592 B (์ฝ 469 MB) |
| ํ ์ ์ฒด | ์ฝ 5,847๋ง ๊ฐ (58,470,268) | 3,317,109,799 B (์ฝ 3.32 GB) |
์ฌ๊ธฐ์ ๊ฐ์ฅ ์ค์ํ ๊ด์ฐฐ์ ์๋ก ๋ค๋ฅธ ๋ค ํ์ ์ ๊ฐ์๊ฐ ์ ๋ถ 970๋ง ~ 1,000๋ง์ผ๋ก ๋น์ทํ๋ค๋ ์ ์ ๋๋ค. ๊ฐ์๊ฐ ๋ง์๋จ์ด์ง๋ฉด "ํ๋๋ฅผ ๋ง๋ค ๋๋ง๋ค ๋๋จธ์ง๋ ํ๋์ฉ ๋ฐ๋ผ ์๊ธฐ๋ ๋ฌถ์"์ด๋ผ๋ ์ ํธ์ ๋๋ค. ๋ค ์ค๋ง ๋ํด๋ ์ฝ 1,485MB ์ ๋๋ค.
๊ฒ๋ค๊ฐ System.Int32 ๊ฐ ํ์ 968๋ง ๊ฐ ์๋ค๋ ๊ฒ ์์ฒด๊ฐ ์ด์ํฉ๋๋ค. ์ ์๋ ์๋ ํ ๊ฐ์ฒด๊ฐ ์๋๋๋ค. object ์๋ฆฌ์ ๋ค์ด๊ฐ๋๋ผ ๋ฐ์ฑ(boxing)๋ ์ ์๋ผ๋ ๋ป์
๋๋ค. ์ด ๋ฐ์ดํธ๋ฅผ ๊ฐ์๋ก ๋๋๋ฉด Node 48B, JSKey 40B, Int32 24B ์
๋๋ค.
โข Node ํ๋๋ฅผ ์ด์ด ๋ณธ๋ค — dumpheap -mt → dumpobj
ํ์ ์ด๋ฆ๋ง์ผ๋ก๋ ์์ ๋ฌด์์ด ๋ค์๋์ง ๋ชจ๋ฆ ๋๋ค. Node ์ค์ ์ฒซ ์ด์ด ํ์ ์๋ณ์์ธ MT(MethodTable) ์ ๋๋ค. ์ด MT ๋ก ๊ฐ์ฒด ์ฃผ์ ๋ชฉ๋ก์ ๋ฝ๊ณ , ๊ทธ์ค ํ๋๋ฅผ ์ด์ด ๋ดค์ต๋๋ค.
> dumpheap -mt 7ffe38582198 -short
> dumpobj 02c2319c4008

Size 48 bytes ๋ก ์์์ ๋๋ ๋ณธ ๊ฐ๊ณผ ๊ฐ๊ณ , ํ๋๋ _key(object), _value(JSKey), _next(๋ค์ Node), _hashcode(Int32) ๋ค ๊ฐ์
๋๋ค. ๋ชฉ๋ก ์ค๊ฐ์์ ๊ณ ๋ฅด๊ฒ 22๊ฐ๋ฅผ ๋ฝ์ ์ด์ด ๋ณด๋ 21๊ฐ์ ํค๊ฐ ์ ์์๊ณ , ๊ฐ์ 1,025 ~ 9,568,797 ์ฌ์ด์์ต๋๋ค.
โฃ ๋๊ฐ ๋ถ์ก๊ณ ์๋ — gcroot
GC ๋ ๋ฃจํธ(static ํ๋, ์ค๋ ๋ ์คํ, ํธ๋ค)์์ ์ฐธ์กฐ๋ฅผ ๋ฐ๋ผ๊ฐ ๋ฟ๋ ๊ฐ์ฒด๋ง ์ด๋ ค ๋ก๋๋ค. ์ด๋ค ๊ฐ์ฒด๊ฐ ์ ์ง์์ง๋ค๋ฉด ๋ฃจํธ์์ ๊ทธ ๊ฐ์ฒด๊น์ง ๊ฒฝ๋ก๊ฐ ์๋ค๋ ๋ป์ด๊ณ , gcroot ๊ฐ ๊ทธ ๊ฒฝ๋ก๋ฅผ ๋ณด์ฌ ์ค๋๋ค. "๋๊ฐ ์ฅ๊ณ ์๋๊ฐ"์ ์ง์ ๋ตํ๋ ๋ช
๋ น์
๋๋ค.
> gcroot 02c2319c4008

HandleTable (strong handle)
→ System.Object[]
→ ConcurrentDictionary<Object, JSKey> (02c15e8de438)
→ ConcurrentDictionary+Tables (02c1fa6e6b98)
→ ConcurrentDictionary+VolatileNode[] (02c207400048)
→ ConcurrentDictionary+Node (02c2319c4008)
์์์ ์๋๊ฐ ์ฐธ์กฐ ๋ฐฉํฅ์
๋๋ค. strong handle → Object[] ๋ ๋ฐํ์์ด static ํ๋๋ฅผ ๋ณด๊ดํ๋ ๋ฐฐ์ด์
๋๋ค. ๋ฃจํธ๊ฐ ์ด๊ฒ์ด๋ฉด "static ์ด ๋ถ์ก๊ณ ์๋ค"๋ ๋ป์ด๊ณ , ํ๋ก์ธ์ค๊ฐ ๋๋ ๋๊น์ง ํ๋ฆฌ์ง ์์ต๋๋ค. ๊ฒฝ๋ก๋ ํ๋๋ฟ์ด๋ ๋ณด์ ์๋ ์ฌ์ ํ๋์
๋๋ค.
ConcurrentDictionary ํด๋์ค ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ์์ค์ฝ๋๋ฅผ ์ ์ฒด ๊ฒ์ ํด๋ณด๋ ์์ง ์์ค์ JSKey._cache ํ๋ ์๋ฃํ์ด ConcurrentDictionary ์ด์์ต๋๋ค. ์ด ๋์
๋๋ฆฌ๊ฐ JSKey._cache ๋ผ๊ณ ์ถ์ธก ํ์ต๋๋ค.
โค .NET 10 ConcurrentDictionary ๋ ์ด๋ป๊ฒ ์๊ฒผ๋
๋ค์ ๋จ๊ณ๋ก ๊ฐ๊ธฐ ์ ์ ์ฌ์ ์ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ์ ๊น ๋ณด๊ฒ ์ต๋๋ค. .NET 10 ์ ConcurrentDictionary<TKey, TValue> ์์ค๋ฅผ ๋ณด๋ฉด ๊ฐ์ฒด๊ฐ ์ธ ๊ฒน์ผ๋ก ๋์ด ์์ต๋๋ค.
- ๋ณธ์ฒด :
_tables,_budget,_growLockArray,_comparerIsDefaultForClasses,_initialCapacity. ์ค์ ๋ฐ์ดํฐ๋_tables๊ฐ ๊ฐ๋ฆฌํค๋ Tables ์ ์์ต๋๋ค. - Tables :
_buckets(๋ฒํท ๋ฐฐ์ดVolatileNode[]),_locks(์ ๊ธ ๊ฐ์ฒด ๋ฐฐ์ด),_countPerLock(์ ๊ธ ๊ตฌ๊ฐ๋ณ ํญ๋ชฉ ์),_comparer,_fastModBucketsMultiplier. - Node : ํญ๋ชฉ ํ๋.
_key,_value, ๊ฐ์ ๋ฒํท์ ๊ฑธ๋ฆฐ ๋ค์ ํญ๋ชฉ_next,_hashcode.
๋ฒํท ๋ฐฐ์ด ์ ์ฒด๋ฅผ ์ ๊ธ ๋ช ๊ฐ๋ก ๋๋ ๋งก๊ธฐ๊ณ , ๊ฐ ์ ๊ธ์ด ์๊ธฐ ๊ตฌ๊ฐ์ ํญ๋ชฉ ์๋ฅผ _countPerLock ์ ๋ฐ๋ก ์
๋๋ค. ๊ทธ๋์ Count ๋ _countPerLock ์ ๊ฐ์ ์ ๋ถ ๋ํ ๊ฒ์
๋๋ค. ํ ๊ตฌ๊ฐ์ ํญ๋ชฉ ์๊ฐ _budget(๋ฒํท ์ ÷ ์ ๊ธ ์)์ ๋์ผ๋ฉด ๋ฒํท ๋ฐฐ์ด์ ์ฝ ๋ ๋ฐฐ๋ก ํค์ฐ๊ณ , ์ค์ค๋ก ์ค์ด๋ค์ง๋ ์์ต๋๋ค.

โฅ ์ฌ์ ์ด ์ค์ค๋ก ์ผ ๊ฐ์์ ๋ง์ถฐ ๋ณธ๋ค — dumpobj → dumparray
ํ์์ ์ผ Node 978๋ง ๊ฐ๊ฐ ์ ๋ง ์ ๋ถ ์ด ์ฌ์ ํ๋์ ๋ค์ด ์๋์ง ํ์ธํ๋ ค๋ฉด, ์ฌ์ ์ด ์ง์ ์ธ์ด ๋ _countPerLock ์ ์ด์ด ๋ณด๋ฉด ๋ฉ๋๋ค.
> dumpobj 02c15e8de438 # ์ฌ์ ๋ณธ์ฒด → _tables ์ฃผ์
> dumpobj 000002c1fa6e6b98 # Tables → _buckets, _locks, _countPerLock ์ฃผ์
> dumparray -details 000002c1fa6e6b70

๋ณธ์ฒด์ _initialCapacity ๊ฐ 1931 ์
๋๋ค. ์์ง ์์ค์ new ConcurrentDictionary<object, JSKey>(ProcessorCount(), 1931) ์ ๊ฐ์์, ์์ค ์ชฝ์์๋ ์ด ์ฌ์ ์ด _cache ์์ ํ ๋ฒ ๋ ํ์ธํ์ต๋๋ค. _budget 2,999,737 ์ ๋ฒํท 11,998,949์นธ ÷ ์ ๊ธ 4๊ฐ์ ๋ง์ต๋๋ค.

2,444,090 + 2,443,997 + 2,444,692 + 2,444,525 = 9,777,304
์ฌ์ ์ด ์ค์ค๋ก ์ผ ํญ๋ชฉ ์๊ฐ dumpheap -stat ์์ ์ผ Node ์(9,777,304)์ ์ ํํ ์ผ์นํฉ๋๋ค. 978๋ง ๊ฐ Node ๋ ์ ๋ถ ์ด ์ฌ์ ํ๋์ ๋ค์ด ์๊ณ , ๋ค๋ฅธ ๊ณณ์ผ๋ก ์์ด ๋๊ฐ ๊ฒ์ ์์ต๋๋ค.
โฆ ๋ค๋ฅธ ์ฉ์์๋ฅผ ์ง์ด๋ค — dumpheap -stat -min 1000000
๋จ์ ๊ฐ์ค โ (ํฐ ์๋ต ๋ฌธ์์ด์ด ๋ถ์กํ ์๋ค)๊ณผ โก(LOH ์กฐ๊ฐํ)๋ฅผ ์ง์ ํ์ธํ๋ ค๊ณ 1MB ์ด์์ธ ๊ฐ์ฒด๋ง ๋ดค์ต๋๋ค. ํฐ ๋ฌธ์์ด์ด ๋จ์ ์๋ค๋ฉด ์ฌ๊ธฐ ๋์ค๊ณ , ์กฐ๊ฐํ๊ฐ ์ฌํ๋ฉด Free(๋น ๊ณต๊ฐ)๊ฐ ํฌ๊ฒ ๋์ต๋๋ค.

- System.String ์ค์ด ์์ต๋๋ค. 10MB ์๋ต ๋ฌธ์์ด(UTF-16 ์ผ๋ก ์ฝ 19MB)์ ์ด๋ฏธ ํ์๋์ต๋๋ค. ๊ฐ์ค โ ์ค "์๋ต ๋ฌธ์์ด์ ๋ถ์ก๊ณ ์๋ค"๋ ๊ธฐ๊ฐ์ ๋๋ค.
- Free ๋ 9,453,840 B(์ฝ 9.45 MB). LOH ์ฝ 152MB ์ค ๋น ๊ณต๊ฐ์ด 10MB ๋ ์ ๋๋ ์กฐ๊ฐํ๊ฐ ์๋๋๋ค. ๊ฐ์ค โก ๋ ๊ธฐ๊ฐ์ ๋๋ค.
- ๊ฐ์ฅ ํฐ ๊ฐ์ฒด๋
VolatileNode[]1๊ฐ, 95,991,616 B(์ฝ 96 MB). ํญ๋ชฉ์ด 978๋ง ๊ฐ๋ผ ์ฝ 1,200๋ง ์นธ๊น์ง ์๋ ์ฌ์ ์ ๋ฒํท ๋ฐฐ์ด์ ๋๋ค.
์ ๋ฆฌํ๋ฉด, ํ์ ๋จ์ 1.4GB ์ ์ ์ฒด๋ static ํ๋ JSKey._cache ๊ฐ ๋ถ์ก๊ณ ์๋ ์ ์ ํค ์ฝ 978๋ง ๊ฐ์์ต๋๋ค. ์ฒ์์ ๊ฐ์ฅ ์ ๋ ฅํ๋ค๊ณ ๋ดค๋ LOH ์กฐ๊ฐํ๋ ํ๋ ธ์ต๋๋ค.
7๏ธโฃ์์ง ์์ค์์ JSKey ์บ์ ์ฐพ๊ธฐ
๋คํ๊ฐ ์๋ ค ์ฃผ๋ ๊ฒ์ "์ง๊ธ ๋ฌด์์ด ์๊ณ ๋๊ฐ ๋ถ์ก๊ณ ์๋๊ฐ"๊น์ง์
๋๋ค. "๋๊ฐ ๋ง๋ค์๋๊ฐ"๋ ๋ด๊ธฐ์ง ์์ต๋๋ค. ๊ทธ๋์ ์์ง ์์ค์์ JSKey._cache ์ ๋ฌด์์ด ๋ค์ด๊ฐ๋์ง ์ฐพ์๋ดค์ต๋๋ค.
JavaScript ์์ a[b] ๋ "a ๋ผ๋ ๊ฐ์ฒด์์ b ๋ผ๋ ์ด๋ฆ์ ์์ฑ์ ์ฝ์ด๋ผ"์
๋๋ค. a ๊ฐ ๊ฐ์ฒด๋ ๋ฐฐ์ด์ด๋ ๋ฌธ์์ด์ด๋ ๋ฌธ๋ฒ์ ํ๋์ด๊ณ , arr[3] ๋ ๊ท๊ฒฉ์์ผ๋ก๋ ์ด๋ฆ์ด "3" ์ธ ์์ฑ์ ์ฝ๋ ๊ฒ์
๋๋ค. ์์ง์ ์์ฑ์ ์ฐพ๊ธฐ ์ ์ ๊ทธ ์ด๋ฆ์ ๋ด๋ถ ํค ๊ฐ์ฒด๋ก ๋ฐ๊พธ๋๋ฐ, ์ ํฌ ์์ง์์๋ ๊ทธ๊ฒ JSKey ์
๋๋ค.
// JSKey.cs - ์ ๊ฑฐ ๋ก์ง์ด ์๋ static ์ฌ์
private static ConcurrentDictionary<object, JSKey> _cache = new ConcurrentDictionary<object, JSKey>(ProcessorCount(), 1931);
private static JSKey[] _indexCache = new JSKey[1025];
public static JSKey Intern(int key)
{
if (key >= 0 && key <= 1024) {
return _indexCache[key]; // ์์ ์ ์: ๋ฏธ๋ฆฌ ๋ง๋ ๊ฒ ์ฌ์ฌ์ฉ
}
return _cache.GetOrAdd(key, static (o) => new JSKey((int)o)); // 1025 ์ด์: ์ฌ์ ์ ์๊ตฌ ๋ฑ๋ก
}
์์ฑ ์ด๋ฆ ํค("orderNo" ๊ฐ์ ๊ฒ)๋ ์์ค์ ์ ํ ๋งํผ๋ง ์์ด์ ์บ์ํด ๋๋ฉด ์ด๋์ด๊ณ , ์ค์ ๋ก ์ฝ 10๋ง ๊ฐ์์ ๋ฉ์ถฅ๋๋ค. ๋ฌธ์ ๋ ์ด ์ ์ ๋ฅผ ๊นจ๋ ํค, ์ฆ ์
๋ ฅ ๋ฐ์ดํฐ์ ๊ธธ์ด๋งํผ ์ข
๋ฅ๊ฐ ๋์ด๋๋ ์ ์ ํค๊ฐ ๊ฐ์ ์บ์์ ๋ค์ด์ฌ ๋์
๋๋ค. 0 ~ 1024 ๋ ๊ณ ์ ๋ฐฐ์ด์ด ์ฒ๋ฆฌํ์ง๋ง 1,025 ์ด์์ ์ ๋ถ _cache ์ ์๊ตฌ ๋ฑ๋ก๋ฉ๋๋ค. ์ฌ์ ์ ํค ํ์
์ด object ๋ผ์ ์ ์๋ ๋ฐ์ฑ๋๊ณ , JSKey ๋ ์ ์๋ฅผ ๋ฌธ์์ด๋ก๋ ๋ค๊ณ ์์ต๋๋ค. ๋คํ์์ ๋ณธ Node · Int32 · JSKey · String ๋ค ๋ฌถ์์ด ์ ํํ ์ด๊ฒ์
๋๋ค.

| ๊ธ์ ํ๋์ ์๊ธฐ๋ ๊ฐ์ฒด | ํฌ๊ธฐ | ์ ์๊ธฐ๋ |
| Node | 48 B | ์ฌ์ ์ ํญ๋ชฉ ํ๋ |
| ๋ฐ์ฑ๋ Int32 | 24 B | ํค ํ์ ์ด object ๋ผ์ ์ ์๋ฅผ ํฌ์ฅ |
| JSKey | 40 B | ์บ์์ ๊ฐ |
| String | ์ฝ 36 B | ์ ์๋ฅผ "2954227" ๊ฐ์ ๋ฌธ์์ด๋ก๋ ๋ณด๊ด |
| ๋ฒํท ๋ฐฐ์ด ์ง๋ถ | ์ฝ 10 B | ์ฝ 96MB ๋ฐฐ์ด์ ํญ๋ชฉ ์๋ก ๋๋ ๋ชซ |
| ํฉ๊ณ | ์ฝ 158 B | ์๋ต 100๋ง ๊ธ์๋น ์ฝ 150MB ๊ฐ ์๊ตฌ ์ ์ |
8๏ธโฃ๊ณ ๋๋ชฐ ์์ง ๋ก์ง์์ str[i] ์ฐพ๊ธฐ
์ด์ ๊ณ ๋๋ชฐ ์์ง ๊ฒฝ๋ก์์ 1,025 ์ด์ ์ ์๋ก ๋ฌด์ธ๊ฐ[i] ์ ์ ๊ทผํ๋ ๊ณณ์ ์ฐพ์์ผ ํ์ต๋๋ค. ๋ก์ง์ ๋ฐ๋ผ๊ฐ๋ฉฐ ํ์ด ๋ณด๋ ์์ค ๋ ๊ฑฐ์ ์ฝ๋ ์ค์ ์๋ต ์ ์ฒด๋ฅผ ๊ธ์ ๋จ์๋ก ๋๋ ์ฝ๋๋ XML ์ ์๋ชป๋ ๋ฌธ์๋ฅผ ๊ฑธ๋ฌ ๋ด๋ filterBadXMLCharactors ํจ์ ํ๋๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. 1์ฐจ ์ฌํ์ ์ค๊ฐ ๋คํ๋ฅผ clrstack -all ๋ก ๋ณด๋ ์์ง ์ค๋ ๋๋ ์ ํํ ์ด ํจ์ ์์ ์์์ต๋๋ค.
// ์์ ์
for (let i = 0; i < xml_string.length; i++) {
current = xml_string.charCodeAt(i); // ๋ฉ์๋ ํธ์ถ. i ๋ ์ธ์์ผ ๋ฟ → ํค๋ฅผ ๋ง๋ค์ง ์์
if (_.vIsEquals(current, [0x9, 0xa, 0xd]) || (current >= 0x20 && current <= 0xd7ff) || ...) {
filtered_string.append(xml_string[i]); // ์์ฑ ์ ๊ทผ. i ๊ฐ ์์ฑ ํค๊ฐ ๋จ → 1,025 ์ด์์ด๋ฉด ์๊ตฌ ๋ฑ๋ก
}
}

10MB ์ง๋ฆฌ XML ์๋ต ๋ฌธ์์ด์ ํ ๊ธ์์ฉ xml_string[i] ๋ก ์ฝ์ผ๋ฉด์, ๊ธ์ ๋ฒํธ๋ง๋ค JSKey ๋ฅผ ํ๋์ฉ ๋ง๋ค์ด static ์ฌ์ ์ ๋ฃ๊ณ ์๋ ๊ฒ์
๋๋ค. ์ด ์ถ๋ก ์ ์ซ์๋ก ๊ฒ์ฆํด ๋ดค์ต๋๋ค.
๋ค๋ง ํ ๋คํ์๋ ํค๊ฐ ์ธ์ ๋ค์ด์๋์ง ๊ธฐ๋ก๋์ง ์๊ณ , ๊ฐ์ ์ฌ์ ์ ์์ฑ ์ด๋ฆ ํค๊น์ง ์์ฌ ์์ต๋๋ค. ๊ฒ๋ค๊ฐ 10MB ์ฌํ ๋๋ ์์ง ์ ๋คํ๋ฅผ ๋น ๋จ๋ ค์, Node ์๋ฅผ ๋นผ์ ๋น๊ตํ๋ฉด ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๊ธฐ์ค๊ฐ์ ์จ์ผ ํฉ๋๋ค. ๊ทธ๋์ ์ ์ ํค์๋ง ์๊ธฐ๋ ๋ฐ์ฑ๋ Int32 ๊ฐ์๋ก ๋ง์ถฐ ๋ดค์ต๋๋ค. ์ฌ์ ์ ํค ํ์
์ด object ๋ผ์ ์ ์ ํค๋ง๋ค ๋ฐ์ฑ ๊ฐ์ฒด๊ฐ ํ๋์ฉ ์๊ธฐ๊ณ , ๋ฌธ์์ด ํค์๋ ์๊ธฐ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
| ํญ๋ชฉ | ๊ฐ |
| 10MB ์๋ต์ ๊ธ์ ์ | ์ฝ 967๋ง ๊ฐ (9,673,214) |
| ์์ธกํ ์ ์ ํค ์ : ๊ธ์ ์ − 1,025 (๊ณ ์ ๋ฐฐ์ด ๋ชซ) | ์ฝ 967๋ง ๊ฐ (9,672,189) |
| ์ค์ธก : ์์ ์ 30๋ถ ๋ค ๋คํ์ ๋ฐ์ฑ Int32 | ์ฝ 968๋ง ๊ฐ (9,677,949) |
| ์ค์ธก − ์์ธก | 5,760๊ฐ |
| ์ฐธ๊ณ : ์์ ํ ๋คํ 3์ฅ์ ๋ฐ์ฑ Int32 (์ ์ ํค๊ฐ ์์ด์ง ์์ ํ์ ๊ฐ) | 5,420 ~ 6,201๊ฐ |
์ค์ธก์ด ์์ธก๋ณด๋ค 5,760๊ฐ ๋ง์๋ฐ, ์ด ์ฐจ์ด๊ฐ ํ์ ๋ฐ์ฑ Int32 ๊ฐ์ ๋ฒ์ ์์ ๋ค์ด๊ฐ๋๋ค. ์ฆ "์ ์ ํค ์ฝ 967๋ง ๊ฐ + ํ์์ ์๋ Int32 ์ฝ 5,800๊ฐ"๋ก ์ค๋ช
๋ฉ๋๋ค. ํ์ ๊ฐ์ ๋ค๋ฅธ ํ๋ก์ธ์ค์์ ๋น๋ ค ์จ ๊ฒ์ด๋ผ ํค๋ฅผ ํ๋ํ๋ ์ผ ์ฆ๋ช
์ ์๋์ง๋ง, ์ฝ 967๋ง์ด๋ผ๋ ๊ท๋ชจ๊ฐ ์๋ต ๊ธ์ ์์ ์ผ์นํฉ๋๋ค. "์๋ต ๋ฌธ์์ด ์ ์ฒด๋ฅผ 0 ๋ถํฐ ๋๊น์ง [i] ๋ก ์ฝ์ ๋ฃจํ"๋ก ๋ฒ์๋ฅผ ์ขํ๊ธฐ์๋ ์ถฉ๋ถํ์ต๋๋ค.
์ด ๋์๋ ํ์๊ฐ ์๋๋ผ "์ง๊ธ๊น์ง ์ฒ๋ฆฌํ ๊ฐ์ฅ ๊ธด ๋ฌธ์์ด"์ ๋น๋กํ๋ค๋ ์ ๋ ํน์ดํฉ๋๋ค. ํค๊ฐ ๊ธ์ ๋ฒํธ๋ผ์ ๊ฐ์ ๊ธธ์ด๋ฅผ ๋ค์ ์ฒ๋ฆฌํ๋ฉด ์ด๋ฏธ ์๋ ํค๋ฅผ ์๋๋ค. ๊ทธ๋์ ํ์ ์์ ์ผ๋ก๋ ์ ํ ๋์ง ์๋ค๊ฐ, ์ ๋ํ ๊ธด ์๋ต์ด ํ ๋ฒ ๋ค์ด์ฌ ๋๋ง ๊ณ๋จ์ฒ๋ผ ์ค๋ฆ ๋๋ค. ์ฌ๋ฌ ๋ ์ค 3๋ฒ ์๋ฒ๋ง ๊ทธ๋ฌ๋ ๊ฒ๋ ๊ทธ ๋๋ ์๋ต์ ์ฒ๋ฆฌํ ์๋ฒ๊ฐ 3๋ฒ๋ฟ์ด์๊ธฐ ๋๋ฌธ์ ๋๋ค.
9๏ธโฃ์์ : ๋ฌธ์์ด์ ์ธ๋ฑ์ค ํค๋ก ์ฝ์ง ์๊ฒ ๋ฐ๊พธ๊ธฐ
"์ด๊ฒ ๋ฌธ์ ๋ ๋นผ์"๋ก ๋๋ด๊ธฐ ์ ์, ์ด ํํฐ๊ฐ ์ ๋ค์ด์๋์ง๋ถํฐ ํ์ธํ์ต๋๋ค. ์์ ์ ๊ณ ๊ฐ์ด ์ฃผ๋ฌธ ์ํ๋ช
์ XML ์ ์ฌ ์ ์๋ ์ ์ด ๋ฌธ์(0x08 ๋ฑ)๋ฅผ ๋ฃ์ด XML ํ์ฑ ์์ธ๊ฐ ๋ ์ผ์ด ์์๊ณ , ๊ทธ๋ฐ ๋ฌธ์๋ฅผ ๋ฏธ๋ฆฌ ๊ฑธ๋ฌ ๋ด๋ ค๊ณ ๋ฃ์ ํจ์์์ต๋๋ค. ๋ชฉ์ ์ ํ์ํ๊ณ , ๋ฌธ์ ๋ ๊ตฌํ ๋ฐฉ์๊ณผ "ํญ์ ํธ์ถ"ํ๋ ์กฐ๊ฑด์ด์์ต๋๋ค.
| ์ | ํ๋จ |
xml_string[i] → charAt(i) |
๋ฉ์๋ ํธ์ถ์ด๋ผ ํค๋ฅผ ๋ง๋ค์ง ์์ ๋์๋ ๋งํ๋๋ค. ํ์ง๋ง ๊ธ์ ๋จ์ ๋ฐ๋ณต๋ฌธ๊ณผ "ํญ์ ํธ์ถ"์ ๊ทธ๋๋ก์ ๋๋ค. |
| ์ฑํ | ๋จผ์ ํ์ฑํ๊ณ , ์คํจํ์ ๋๋ง ์ ๊ท์์ผ๋ก ๊ธ์ง ๋ฌธ์๋ฅผ ์ง์ด ๋ค ํ ๋ฒ ๋ ํ์ฑํฉ๋๋ค. ์ ์ ์๋ต์ ๋ฐ๋ณต๋ฌธ๋ ์นํ๋ ๊ฑฐ์น์ง ์๊ณ , ์ ๊ท์ ์นํ์ ์์ง์ C# ์ชฝ์์ ํ ๋ฒ์ ์ฒ๋ฆฌ๋์ด JS ํค๋ฅผ ๋ง๋ค์ง ์์ต๋๋ค. |
// ์์ ํ (์์ง)
private static readonly INVALID_XML_CHARS = /[\x00-\x08\x0B\x0C\x0E-\x1F๏ฟพ๏ฟฟ]/g;
static parseXml(response_body: string): XmlDocument {
try {
return ShoppingUtil.loadXml(xml_string); // โ ์ ์ ์๋ต์ ์ฌ๊ธฐ์ ๋
} catch {
const stripped = xml_string.replace(ShoppingUtil.INVALID_XML_CHARS, ''); // โก ์คํจํ์ ๋๋ง ๊ธ์ง ๋ฌธ์ ์ ๊ฑฐ
return ShoppingUtil.loadXml(stripped);
}
}
์ผํ๋ชฐ๋ง๋ค ๊ฐ์ ๊ฐ๊ณ ์๋ XML ํ์ฑ ์ ํธ๋ ์ด ๊ณตํต parseXml ํ๋๋ก ๋ชจ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ์์ ์ ๋ค์ ํ
์คํธ ์๋ฒ์ ๋ฐฐํฌํด์, ์ ์ถํ ์์ธ์ด ์ง์ง ์์ธ์ด ๋ง๋์ง ๊ฐ์ ์๋๋ฆฌ์ค๋ก ๋๊ฐ์ด ๊ฒ์ฆํ์ต๋๋ค.
๐๊ฒฐ๊ณผ ๋ฐ ์ฑ๊ณผ
1๏ธโฃ๊ฐ์ ์กฐ๊ฑด ์ฌ๊ฒ์ฆ: ๋ ผ๋ฆฌ์ ๋์ 99% ์ ๊ฑฐ
์กฐ๊ฑด์ ๊ฐ์ต๋๋ค. ๊ฐ์ ํ
์คํธ ์๋ฒ, ๋ชฉ์๋ฒ์ ๊ฐ์ 10MB ์๋ต(์ฃผ๋ฌธ 670๊ฐ, ์์ง 1,340ํ)์
๋๋ค. ๋ค๋ง ์๋ต ์์ 0x08 ์ ์ผ๋ถ๋ฌ ๋ฃ์ด์ ์ฒซ ํ์ฑ์ด ์คํจํ๊ณ ์ ๊ท์ ๊ฒฝ๋ก๋ฅผ ํ๊ฒ ํ์ต๋๋ค. ์ฆ ๊ณ ์น ์ฝ๋๊ฐ ์ค์ ๋ก ์คํ๋๋ ๊ฒฝ์ฐ๋ฅผ ์์ต๋๋ค. ์ด๋ฒ์๋ ์์ง ์ , 10๋ถ ๋ค, 30๋ถ ๋ค ๋คํ ์ธ ๊ฐ๋ฅผ ๋ชจ๋ ๊ฐ์ ํ๋ก์ธ์ค์์ ๋ด์ต๋๋ค.

์์ ์ ์ 2๋ถ ๋ง์ 3,722MB ๊น์ง ์ฌ๋ผ 30๋ถ ๋ค์๋ 3,300MB ์ ๋จธ๋ฌผ๋ ๊ณ , ์์ ํ๋ 1,915MB ๊น์ง ์ ๊น ์ฌ๋๋ค๊ฐ 30์ด ์์ ์ ์๋ฆฌ๋ก ๋์์์ต๋๋ค.
| ์งํ | ์์ ์ | ์์ ํ | ๋ณํ |
| ์บ์ Node ์ฆ๊ฐ (์์ธ) | +์ฝ 967๋ง ๊ฐ (+9,671,798) | +548๊ฐ | 99.99% ๊ฐ์ |
| ์บ์ ๋ฒํท ๋ฐฐ์ด | 95,991,616 B (์ฝ 96 MB) | 1,251,520 B (์ฝ 1.25 MB, ๊ธฐ๋ ๋ ๊ทธ๋๋ก) | 98.7% ๊ฐ์ |
| GC ํ ์ฆ๊ฐ (์์ง ์ → 30๋ถ ๋ค) | +1,480 MB | +11 MB | 99.3% ๊ฐ์ |
| Private Bytes ์ฆ๊ฐ (์์ง ์ → 30๋ถ ๋ค) | +1,520 MB | +39 MB | 97.4% ๊ฐ์ |
| Private Bytes ์ต๊ณ ์ | 3,721 MB | 1,915 MB | 48.5% ๊ฐ์ |
| ์์ง ๊ตฌ๊ฐ 2์ธ๋ GC ๋ฉ์ถค ํฉ๊ณ | 40.6์ด (์ต์ฅ 19.6์ด) | 5.7์ด (์ต์ฅ 3.2์ด) | 86.0% ๊ฐ์ |
| ์์ง ๋ค ์ ์ฒด GC | 72์ด์ง๋ฆฌ 1ํ | ์์ | – |
| ์์ง ๊ตฌ๊ฐ ํ ๋น๋ | 6.86 GB | 0.31 GB | 95.5% ๊ฐ์ |
| ์ ์ฅ๋ ์์ง ํ | 1,340 | 1,340 (ํน์ ๋ฌธ์ 11๊ฑด ๊ธฐ๋๊ฐ๊ณผ ์ผ์น) | ๊ธฐ๋ฅ ๋์ผ |
์์ง์ด ๋๋ ๋ค์๋ ๋จ๋ GC ํ 1,480MB ๊ฐ 11MB ๋ก ์ค์์ผ๋ ๋ ผ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ ๋์์ 99.3% ๋ฅผ ์์ค ๊ฒ์ ๋๋ค. ๋จ์ 11MB ๋ ์บ์์๋ ๊ด๊ณ๊ฐ ์์ต๋๋ค. ์บ์ Node ๋ 548๊ฐ ๋์๊ณ 10๋ถ ๋ค์ 30๋ถ ๋ค๊ฐ ๊ฐ์์ต๋๋ค. ์๋ต ๊ธ์ ์ 967๋ง๊ณผ ๋ฌด๊ดํ ์๋ผ์, ๊ณ ๋๋ชฐ ํ๋ฌ๊ทธ์ธ ์ฝ๋๊ฐ ์ด ์์ปค์์ ์ฒ์ ์คํ๋๋ฉฐ ๋ฑ๋ก๋ ์์ฑ ์ด๋ฆ์ผ๋ก ๋ณด์ ๋๋ค.
๊ธฐ๋ฅ๋ ๊นจ์ง์ง ์์์ต๋๋ค. ์๋ต์ ์ฌ์ด ๋ ํน์ ๋ฌธ์ ์ผ์ด์ค 11๊ฑด(0x08, 0x01·0x0B·0x0C·0x1F, CDATA ์์ &, ๊ฒฐํฉ ์ด๋ชจ์ง, ํญ·์ค๋ฐ๊ฟ, U+200B·U+FEFF ๋ฑ)์ DB ์์ ๊บผ๋ด ์ฝ๋ํฌ์ธํธ ๋จ์๋ก ๋์กฐํ๊ณ , ๊ธ์ง ๋ฌธ์๋ง ์ง์์ง๊ณ ๋๋จธ์ง๋ ๊ทธ๋๋ก ๋ค์ด์์ต๋๋ค.
2๏ธโฃ๋คํ๋ก ๋ค์ ํ์ธ: ์ฆ์์ด ์๋๋ผ ์์ธ์ด ์ฌ๋ผ์ก๋ค
"๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ๋์๋ค"๋ง ๋ณด๊ณ ๋๋ผ ์๋ ์์์ง๋ง, ๋ฉ๋ชจ๋ฆฌ๋ ์ฌ๋ฌ ์ด์ ๋ก ์ ๋ ์ ์์ต๋๋ค. ๊ทธ๋์ ์์ ์ ๊ณผ ์์ ํ์ 30๋ถ ๋ค ๋คํ๋ฅผ ์ฐฝ ๋ ๊ฐ์ ๋๋ํ ์ด๊ณ ๊ฐ์ ๋ช ๋ น์ ์ณค์ต๋๋ค.

| ํญ๋ชฉ | ์์ ์ | ์์ ํ | ๋ณํ |
| ํ ๊ฐ์ฒด ์ | ์ฝ 5,847๋ง ๊ฐ (58,470,268) | ์ฝ 1,951๋ง ๊ฐ (19,513,305) | 66.6% ๊ฐ์ |
| ํ ํฌ๊ธฐ | 3,317,109,799 B (์ฝ 3.32 GB) | 1,808,771,066 B (์ฝ 1.81 GB) | 45.5% ๊ฐ์ |
| JSKey | ์ฝ 978๋ง ๊ฐ (9,778,329) | ์ฝ 10๋ง ๊ฐ (106,631) | 98.9% ๊ฐ์ |
| ์บ์ Node | ์ฝ 978๋ง ๊ฐ (9,777,304) | ์ฝ 10๋ง ๊ฐ (105,606) | 98.9% ๊ฐ์ |
์ค๋ฅธ์ชฝ์๋ Int32·JSKey·String·Node ๋ค ์ค์ด ๋งจ ์๋์์ ์ฌ๋ผ์ง๊ณ , ๊ธฐ๋ ๋ ์ฝ์ JS ๋ชจ๋์ ๊ตฌ๋ฌธ ํธ๋ฆฌ(AST) ํ์ ์ด ๋งจ ์๋๋ฅผ ์ฐจ์งํฉ๋๋ค. ์ด๊ฒ ์ด ์์ปค์ ์ ์ ์ํ์ ๋๋ค. ์์ชฝ์์ ๋ณํ์ง ์์์ผ ํ AST ๋ฆฌํฐ๋ด ๊ฐ์ฒด ์(์ฝ 144๋ง ๊ฐ)๊ฐ ๊ฑฐ์ ๊ฐ๋ค๋ ์ ์ด, ๋ ๋คํ๋ฅผ ๋๋ํ ๋น๊ตํด๋ ๋๋ค๋ ๊ทผ๊ฑฐ์ ๋๋ค.

์์ธ์ด๋ผ๊ณ ์ง๋ชฉํ ๋ฐ๋ก ๊ทธ ๊ฐ์ฒด(์บ์ Node)์ ์ฆ๊ฐ๊ฐ ์ฝ 967๋ง ๊ฐ → 548๊ฐ๋ก ๋ฐ๋ ๊ฒ์ ํ์ธํ๊ธฐ ๋๋ฌธ์, "์์ธ์ด ์ฌ๋ผ์ ธ์ ์ฆ์์ด ์ฌ๋ผ์ก๋ค"๊ณ ๋งํ ์ ์์์ต๋๋ค.
3๏ธโฃ์ด์ ๋ฐฐํฌ ํ 3๋ฒ ์๋ฒ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ
์์ ์ ์ด์ ์คํฌ๋ํ ์๋ฒ์ ๋ฐฐํฌํ ๋ค, ๋ฐฐํฌ ์ (10์ 13์ผ 15์)๊ณผ ๋ฐฐํฌ ํ(10์ 14์ผ 15์) ๊ฐ์ ์๊ฐ์ Free Memory ๋ฅผ ๋น๊ตํด ๋ณด๋ฉด 3๋ฒ ์๋ฒ์ ๊ฐ์ฉ ๋ฉ๋ชจ๋ฆฌ๊ฐ 584 MiB → 1.20 GiB(์ฝ 1,229 MiB), ์ฝ 2.1๋ฐฐ๊ฐ ๋์์ต๋๋ค.

๋ค๋ง ๊ฐ์ ์๊ฐ ๋ค๋ฅธ ์๋ฒ๋ค์ ๊ฐ๋ ํจ๊ป ์ฌ๋ผ์, ์ด ๊ทธ๋ฆผ ํ ์ฅ์ ์์ ํจ๊ณผ์ ์ฆ๊ฑฐ๋ก ์ผ์ง๋ ์์์ต๋๋ค. ํจ๊ณผ์ ๊ทผ๊ฑฐ๋ ์์ ๊ฐ์ ์กฐ๊ฑด ์ฌ๊ฒ์ฆ๊ณผ ๋คํ ๋น๊ต์ด๊ณ , ์ด์์์๋ 3๋ฒ ์๋ฒ๊ฐ ๋ค๋ฅธ ์๋ฒ๋ค๊ณผ ๋น์ทํ ๋ฒ์(1.20 / 1.37 / 1.44 GiB)๋ก ๋์์จ ๊ฒ์ ํ์ธํ ์ ๋๋ก ๋ด ์ฃผ์๋ฉด ๋ฉ๋๋ค.
4๏ธโฃ์์ง ํ์ ๊ฑด์: 1,024 ๋ฅผ ๋๋ ์ ์ ํค๋ ์บ์ฑํ์ง ์๊ธฐ๋ก
๋น์ฆ๋์ค ์ฝ๋๋ฅผ ๊ณ ์น ๊ฒ์ ๊ธํ ๋ถ์ ๋ ๊ฒ์ด๊ณ , ๊ทผ๋ณธ ์์ธ์ ์์ง์ ์์์ต๋๋ค. str[i] ๋ ES5 ๋ถํฐ ํ์ค์ธ ๊ฐ์ฅ ํํ ํ๊ธฐ์ด๊ณ , Node.js ๋ ๋ธ๋ผ์ฐ์ ์์๋ 10MB ๋ฌธ์์ด์ str[i] ๋ก ๋์๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ด์ง ์์ต๋๋ค. V8 ์ ์ ์ ์ธ๋ฑ์ค ์์ฑ์ ์ด๋ฆ ์๋ ์์ฑ(named properties)๊ณผ ๋ฐ๋ก "elements" ๋ก ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ ํฌ ์ชฝ์ ๋๊ตฌ๋ ํ๋ฒํ๊ฒ str[i] ๋ arr[i] ๋ก ํฐ ๋ฐ์ดํฐ๋ฅผ ๋๋ ์๊ฐ ๊ฐ์ ์ผ์ด ์ฌ๋ฐํ ์ ์๋ ๊ตฌ์กฐ์์ต๋๋ค.
๊ทธ๋์ ์์ง์ ๋ด๋นํ๋ ํ์ ์กฐ์ฌ ๋ด์ฉ๊ณผ ํจ๊ป ์ด๋ ๊ฒ ๊ฑด์ํ์ต๋๋ค.
์์ฑ ์ด๋ฆ ํค๋ฅผ ์ธํฐ๋ํ๋ ๊ฑด ๊ฐ์ ์ด๋ฆ์ด ์์ฒญ๋ง๋ค ๋ฐ๋ณต๋๋ ์ด๋์ด์ง๋ง, ํฐ ์ ์ ํค๋ ์ธํฐ๋์ด ๊ธฐ๋๋ ๋ ์ ์ (ํค์ ์ข ๋ฅ๊ฐ ์ ํํ๋ค, ๊ฐ์ ํค๊ฐ ๋ฐ๋ณตํด์ ์ฐ์ธ๋ค)๋ฅผ ๋ชจ๋ ๋ง์กฑํ์ง ์์ต๋๋ค. 1,025 ์ด์ ์ ์ ํค๋ฅผ ์๊ตฌ ์บ์์ ๋๋ ๊ฒ ์๋ํ ์ค๊ณ์ธ์ง ๊ถ๊ธํฉ๋๋ค.
์์ง ํ์์ ๋ด๋ถ ๋ ผ์๋ฅผ ๊ฑฐ์น ๊ฒฐ๊ณผ, ์ ์ ํค๋ 1,024 ๋ฅผ ๋์ผ๋ฉด ์บ์ฑํ์ง ์๊ณ ์์ฒญ๋ง๋ค JSKey ๊ฐ์ฒด๋ฅผ ์๋ก ๋ง๋ค์ด ๋ฐํํ๊ธฐ๋ก ํ์ต๋๋ค. ํฐ ์ ์ ํค๋ฅผ ์บ์ฑํด์ ์ป๋ ์ด์ ๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฌดํํ ์ก์๋จน๋ ์ํ์ด ํจ์ฌ ํฌ๊ณ , ๋งค๋ฒ JSKey ๋ฅผ ๋ง๋๋ ์ชฝ์ด ์คํ๋ ค ์ค๋ฒํค๋๊ฐ ๋ฎ๋ค๊ณ ํ๋จํ๋ค๊ณ ํฉ๋๋ค. ์ ๊ฐ ์ดํดํ๊ธฐ๋ก๋, ์ ๊น ์ฐ๊ณ ๋ฒ๋ ค์ง๋ ์์ ๊ฐ์ฒด๋ 0์ธ๋ GC ์์ ์ธ๊ฒ ํ์๋๋ static ์ฌ์ ์ ์์ ๋๊ณ ๋ฒํท ๋ฐฐ์ด๊น์ง ํค์ฐ๋ ๊ฒ๋ณด๋ค ๊ฐ๋ณ์ต๋๋ค.
์ด ๋ณ๊ฒฝ์ด ๋ค์ด๊ฐ๋ฉด ํน์ ๋น์ฆ๋์ค ์ฝ๋ ํ ๊ณณ์ด ์๋๋ผ ์์ง ์์์ ๋๋ ๋ชจ๋ ์ฝ๋์์ ๊ฐ์ ์ข ๋ฅ์ ๋์๊ฐ ์๊ธธ ๊ธธ์ด ๋งํ๋๋ค.
5๏ธโฃ๋คํ ๋ถ์ ๋์๋ณด๋๋ฅผ ๋ง๋ค์ด ์ฌ๋ด์ ๊ณต์
์ด๋ฒ ์กฐ์ฌ๋ฅผ ํ๋ฉด์ ๊ฐ์ฅ ์์ด ๋ง์ด ๊ฐ ๊ฑด csv ๋ ๊ฐ๋ฅผ ์์
๋ก ๊ทธ๋ ค ๋ณด๊ณ , ์ฝ์์์ dumpheap, gcroot, dumpobj ๊ฒฐ๊ณผ๋ฅผ ํ ์ค์ฉ ์ฝ๊ณ , ๋คํ ๋ ๊ฐ๋ฅผ ์ฐฝ ๋ ๊ฐ์ ๋์ ์ซ์๋ฅผ ๋์ผ๋ก ๋ง์ถ๋ ์ผ์ด์์ต๋๋ค. ๋ค์์ ๋๊ฐ ๊ฐ์ ์ผ์ ๊ฒช์ด๋ ์ด ๊ณผ์ ์ ๋ฐ๋ณตํ์ง ์๋๋ก, ์์ฃผ ์ฐ๋ ๋ช
๋ น์ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ํ์ ํ, ๋
ธ๋·๊ฐ์ ๊ทธ๋ํ๋ก ๋ณด์ฌ ์ฃผ๋ ๋ก์ปฌ ๋์๋ณด๋๋ฅผ ๋ง๋ค์ด ํ์ ๊ณต์ ํ์ต๋๋ค.
์ธ๋ถ ์์กด์ฑ ์์ด Node.js ์๋ฒ ํ๋๋ก ๋๊ณ , ์๋ฒ๊ฐ ๋คํ๋ง๋ค dotnet-dump analyze ํ๋ก์ธ์ค๋ฅผ ํ๋ ๋์ ๋๊ณ ๋ช
๋ น์ ๋ณด๋ธ ๋ค ์ถ๋ ฅ์ ํ์ฑํด์ ํ๋ฉด์ ๊ทธ๋ฆฝ๋๋ค. ํ ๋ฒ ์คํํ ๋ช
๋ น ๊ฒฐ๊ณผ๋ ํ
์คํธ๋ก ์บ์ํด์, ๋ค์๋ถํฐ๋ ๋ช ๋ถ์ฉ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ๋ก ๋ณผ ์ ์๊ฒ ํ์ต๋๋ค.
| ํ๋ฉด | ๋ณด์ฌ ์ฃผ๋ ๊ฒ | ์ฐ๋ ๋ช ๋ น·ํ์ผ |
| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ํ์๋ผ์ธ | Private Bytes, Working Set, GC ํ์ ํ ์ถ์ ๊ทธ๋ฆฌ๊ณ GC ๋ฐ์ ์๊ฐ(์ธ๋๋ณ ์ ์ ), ๋คํ ์์ฑ ์๊ฐ์ ํ์. GC ๋ฉ์ถค ์๊ฐ, ํ ๋น๋, ๋จํธํ, ์ค๋ ๋ํ, ์์ธ, CPU ๋ณด์กฐ ์ฐจํธ | mem.csv, counters.csv |
| ๋คํ ํ์ผ ๋ถ์ | ์ธ๋๋ณ ํ ์์ญ ๋ง๋, ํ์ ๋ณ ๋ฉ๋ชจ๋ฆฌ ํ, ๊ฐ์ฒด ๋ชฉ๋ก, ์ฐธ์กฐ ๊ทธ๋ํ, ๊ฐ์ฒด ์์ธ, ์ค๋ ๋ ์คํ | eeheap -gc, dumpheap -stat / -mt / -min, gcroot, dumpobj, clrstack -all |
| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ๋น๊ต | ์ฌ๋ฌ ํ ์คํธ์ csv ๋ฅผ ๊ธฐ์ค ์๊ฐ(T0)์ ๋ง์ถฐ ๊ฒน์ณ ๊ทธ๋ฆผ | mem.csv, counters.csv |
| ๋คํ ํ์ผ ๋น๊ต | ๋คํ ๋ ๊ฐ ์ด์์ ํ์ ํต๊ณ๋ฅผ ๋๋ํ ๋๊ณ ์ฆ๊ฐ๊ณผ ๋ณํ์จ ์์ผ๋ก ์ ๋ ฌ | ๊ฐ ๋คํ์ dumpheap -stat |
| ๋ช ๋ น ์ฝ์ | ์ ํํ ๋คํ์ ์์์ SOS ๋ช ๋ น ์คํ | syncblk, finalizequeue ๋ฑ |
โ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ํ์๋ผ์ธ

์์ ์ ์ฌํ์ csv ๋ ๊ฐ๋ฅผ ์ฌ๋ฆฌ๋ฉด, ์ด๋ฒ ๊ธ ์๋ถ๋ถ์์ ํ๋ก ์ ๋ฆฌํ๋ ๋ด์ฉ์ด ํ ํ๋ฉด์ ๋์ต๋๋ค. ๋นจ๊ฐ ์ ์ ์ด 2์ธ๋ GC ์ด๊ณ , ์ด๋ก ์ค์ ์ด ๋คํ๋ฅผ ๋ฌ ์๊ฐ์ ๋๋ค. GC ๊ฐ ์ฌ๋ฌ ๋ฒ ๋์๋๋ฐ๋ ํ์ด ๋ด๋ ค์ค์ง ์๋ ๋ชจ์์ด ํ๋์ ๋ณด์ ๋๋ค.

โก ๋คํ ํ์ผ ๋ถ์


์ฝ์์์ ์ฃผ์๋ฅผ ๋ณต์ฌํด dumpobj ๋ฅผ ์น๊ณ , ๊ทธ ๊ฒฐ๊ณผ์์ ๋ค์ ์ฃผ์๋ฅผ ๋ณต์ฌํ๋ ์ผ์ ํด๋ฆญ ํ ๋ฒ์ผ๋ก ๋ฐ๊ฟจ์ต๋๋ค. ์์์ ๋ช
๋ น ์ธ ๋ฒ์ผ๋ก ๋ฐ๋ผ๊ฐ ์ฌ์ ๋ณธ์ฒด → Tables → _countPerLock ๊ฒฝ๋ก๋ ๊ทธ๋ํ์์ ๋
ธ๋๋ฅผ ์ฐจ๋ก๋ก ๋๋ฅด๋ฉด ๋ฉ๋๋ค.
โข ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ๋น๊ต / ๋คํ ํ์ผ ๋น๊ต


์ด๋ฒ ๊ธ์ "๊ฒฐ๊ณผ" ํ๋ฅผ ๋ง๋ค๋ ค๊ณ ๋คํ ๋ ๊ฐ๋ฅผ ๋๋ํ ๋์ ์ซ์๋ฅผ ๋ง์ถ๋ ์์ ์ด, ๋คํ ๋ ๊ฐ๋ฅผ ๊ณ ๋ฅด๊ณ ๋ฒํผ ํ ๋ฒ ๋๋ฅด๋ ์ผ์ด ๋์ต๋๋ค.
6๏ธโฃ๊ฒฐ๊ณผ ๋ฐ ๋ฐฐ์ด ์
1. "๊ทธ๋ฅ OO ์ด ์ด์ ๊ฒ ์ง" ํ๊ณ ๊ณ ์น์ง ์์ ์ ์์์ต๋๋ค.
์ฝ๋๋ฅผ ์ฝ์ด์ ์ธ์ด ๊ฐ์ค์ ์ ์ด์๊ณ , ์ฒ์ ๊ฐ์ฅ ์ ๋ ฅํ๋ LOH ์กฐ๊ฐํ๋ ํ๋ ธ์ต๋๋ค. ์ง๋ ์ง์์ผ๋ก GC ์ค์ ์ ๋ฐ๊ฟ ๋ฐฐํฌํ๋ค๋ฉด ํจ๊ณผ ์๋ ์์ ์ ์ด์์ ์ฌ๋ ธ์ ๊ฒ๋๋ค. ๋คํ๋ "๋ฌด์์ด ๋ฉ๋ชจ๋ฆฌ์ ์๊ณ ๋๊ฐ ๋ถ์ก๊ณ ์๋๊ฐ"๋ฅผ ์ซ์๋ก ๋ณด์ฌ ์คฌ์ต๋๋ค.
2. ์์ธก์ ๋จผ์ ์ ๊ณ ์ค์ธก๊ณผ ๋ง์ท์ต๋๋ค.
"๊ธ์ ์ − 1,025 ๊ฐ์ ์ ์ ํค๊ฐ ์์ผ ๊ฒ"์ด๋ผ๋ ์์ธก์ด ๋คํ์ ๋ฐ์ฑ Int32 ๊ฐ์์ ๋ค์ด๋ง์์ ๋ ์ค๋ช ์ด ๋จ๋จํด์ก์ต๋๋ค. ์์ ๋ค์๋ "๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ๋์๋ค"๊ฐ ์๋๋ผ ์์ธ์ผ๋ก ์ง๋ชฉํ ๊ฐ์ฒด์ ๊ฐ์๋ฅผ ๋ค์ ์ ์ต๋๋ค.
3. ์คํจํ ์คํ๋ ์๋ฃ์์ต๋๋ค.
์๋ฒ๋ฅผ ์ฐ๋ฌ๋จ๋ฆฐ 1์ฐจ ์ฌํ์์ "๋๋๋ฉด ๋จ์"๊ณ ๊ธฐ๋ค๋ ธ๋ค๋ฉด ์๋ฌด๊ฒ๋ ๋จ์ง ์์์ ๊ฒ๋๋ค. ์ด์ํ๋ค ์ถ์ ์๊ฐ์ ๋ ๋ ์ค๊ฐ ๋คํ๊ฐ ์์ธ ๊ฐ์ฒด์ ์คํ ์ค์ธ ํจ์๋ฅผ ํจ๊ป ์๋ ค ์คฌ์ต๋๋ค.
4. ์บ์๋ ํค์ ์ข ๋ฅ๊ฐ ์ ํํ ๋๋ง ์บ์์ ๋๋ค.
์ ๊ฑฐ ๋ก์ง์ด ์๋ static ์บ์์ ์
๋ ฅ ๋ฐ์ดํฐ์ ๋น๋กํ๋ ํค๊ฐ ๋ค์ด์ค๋ ์๊ฐ, ๊ทธ๊ฑด ์บ์๊ฐ ์๋๋ผ ๋์์
๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์์ธ์ str[i] ์ฒ๋ผ ์์ฃผ ํ๋ฒํ ์ฝ๋์์ต๋๋ค.
GC ๊ฐ ์๋ค๊ณ ๋์๊ฐ ์๋ ๊ฒ ์๋๋๋ค. GC ๋ "๋ฟ์ ์ ์๋ ๊ฒ"๋ง ์น์ ์ค ๋ฟ, "๋ฟ์ ์ ์์ง๋ง ์ธ๋ชจ์๋ ๊ฒ"์ ๋๊น์ง ์ง์ผ ์ค๋๋ค.
์ฐธ๊ณ ์๋ฃ
'Observability' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| MSA ํ๊ฒฝ์์ ๋ชจ๋ํฐ๋ง (0) | 2024.11.14 |
|---|
๋๊ธ