ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๊ด€๋ฆฌ

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜: ์›์ธ, ํƒ์ง€ ๋ฐ ์˜ˆ๋ฐฉ ์ดํ•ด

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ์—”์ง€๋‹ˆ์–ด๋ง์—์„œ ๊ฐ€์žฅ ์‹ฌ๊ฐํ•œ ๊ฒฐํ•จ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์‹คํ–‰์„ ์ฆ‰์‹œ ์ค‘๋‹จ์‹œํ‚ค๋Š” ํฌ๋ž˜์‹œ์™€ ๋‹ฌ๋ฆฌ, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ์‹œ์Šคํ…œ์„ ์ ์ง„์ ์œผ๋กœ ์ €ํ•˜์‹œ์ผœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ์‘๋‹ต ์†๋„๊ฐ€ ๋А๋ ค์ง€๊ฑฐ๋‚˜, ์„œ๋น„์Šค๊ฐ€ ์˜ˆ๊ธฐ์น˜ ์•Š๊ฒŒ ์žฌ์‹œ์ž‘๋˜๊ฑฐ๋‚˜, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์˜ค๋ฅ˜๋กœ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์ด๋Ÿฌํ•œ ํ˜„์ƒ์ด ์ง€์†๋ฉ๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ๋ชจ๋“  ์ฃผ์š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํž™ ๊ด€๋ฆฌ๊ฐ€ ์ „์ ์œผ๋กœ ์ˆ˜๋™์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋Š” C์™€ C++๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ๋Œ€๋ถ€๋ถ„์˜ ์ •๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ ๋ฏธ๋ฌ˜ํ•œ ์ฐธ์กฐ ์ฒด์ธ์œผ๋กœ ์ธํ•ด ๋ฉ”๋ชจ๋ฆฌ ํšŒ์ˆ˜๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ Java, Python, JavaScript, C#์—์„œ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Android ์•กํ‹ฐ๋น„ํ‹ฐ์˜ ๋ˆ„์ˆ˜๋œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ, Java ์„œ๋น„์Šค์˜ ๋ฌดํ•œ ์บ์‹œ, ์Šค๋ ˆ๋“œ ํ’€์—์„œ ์ œ๊ฑฐ๋˜์ง€ ์•Š์€ ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜ ๋“ฑ์€ ๋ชจ๋‘ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์— ํ•ด๋‹นํ•˜๋ฉฐ, ์‹œ์Šคํ…œ์—์„œ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์ „๊นŒ์ง€ ์กฐ์šฉํžˆ ๋ˆ„์ ๋ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋‚˜์š”?

SMART TS XL ์ˆ˜๋ฐฑ๋งŒ ๊ฐœ์˜ ์ฝ”๋“œ ์ค„์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ์ด์ƒ์ ์ธ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค.

์ง€๊ธˆ ํƒ์ƒ‰

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฐ€์žฅ ํฐ ์ด์œ ๋Š” ๊ฐœ๋ฐœ ๋‹จ๊ณ„์—์„œ๋Š” ๊ฑฐ์˜ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 30์ดˆ ๋™์•ˆ ์ง„ํ–‰๋˜๋Š” ํ…Œ์ŠคํŠธ ์‹คํ–‰์—์„œ๋„ ์ˆ˜์‹ญ๋งŒ ๋ฒˆ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ฐ ํ•ด์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ, ์ธก์ • ๊ฐ€๋Šฅํ•œ ๋ˆ„์ˆ˜๋Š” ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋™์ผํ•œ ์ฝ”๋“œ๊ฐ€ ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ 12์‹œ๊ฐ„ ๋™์•ˆ ์‹คํ–‰๋˜๋ฉด ์„œ๋ฒ„์— ์‹ฌ๊ฐํ•œ ๋ถ€ํ•˜๊ฐ€ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์‹œ์ ๊ณผ ์ฒ˜์Œ ๋ฐœ๊ฒฌ๋˜๋Š” ์‹œ์  ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ์€ ๋ณดํ†ต ๋ช‡ ์ฃผ์— ๋‹ฌํ•˜๋ฉฐ, ๊ทธ ์‹œ์ ์—๋Š” ๋ˆ„์ˆ˜๋ฅผ ์œ ๋ฐœํ•œ ์ปค๋ฐ‹์ด ์ด๋ฏธ ๋ณ‘ํ•ฉ๋œ ํ›„์ด๊ณ , ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ ๊ฐœ๋ฐœ์ž๋Š” ๋ˆ„๋ฝ๋œ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๊ธฐ์–ตํ•˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ์ฐพ๊ณ , ์ˆ˜์ •ํ•˜๊ณ , ์˜ˆ๋ฐฉํ•˜๋ ค๋ฉด ๊ตฌ์กฐ์  ์ง€์‹, ์ ์ ˆํ•œ ์‹œ๊ธฐ์— ์ ์šฉ๋˜๋Š” ์ ์ ˆํ•œ ํƒ์ง€ ๋„๊ตฌ, ๊ทธ๋ฆฌ๊ณ  ์•ˆ์ „ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์‚ฌํ›„ ๊ณ ๋ ค ์‚ฌํ•ญ์ด ์•„๋‹Œ ๊ฐ€์žฅ ์‰ฌ์šด ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ๋งŒ๋“œ๋Š” ์„ค๊ณ„ ์Šต๊ด€์ด ๋ชจ๋‘ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ฐจ๋ก€

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

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

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

C๋‚˜ C++์ฒ˜๋Ÿผ ์ˆ˜๋™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์–ธ์–ด์—์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. malloc, calloc๋ฐ new ๋Œ€์‘๋˜๋Š” ํ˜ธ์ถœ ์—†์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. free or delete์ž๋ฐ”, ํŒŒ์ด์ฌ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ, C#๊ณผ ๊ฐ™์ด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด์—์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ํ˜•ํƒœ๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์˜๋„์น˜ ์•Š๊ฒŒ ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„ ์žˆ๋”๋ผ๋„ ํ•˜๋‚˜ ์ด์ƒ์˜ ํ™œ์„ฑ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋Š” ํšŒ์ˆ˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฉ”๋ชจ๋ฆฌ๋Š” ๊ณ ์•„ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ, ํ”„๋กœ๊ทธ๋žจ์ด ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆฐ ์ฐธ์กฐ ์ฒด์ธ์— ์˜ํ•ด ์œ ์ง€๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ๊ฒฐ๊ณผ๋Š” ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ฒฝ๋ฏธํ•œ ๊ฒƒ๋ถ€ํ„ฐ ์น˜๋ช…์ ์ธ ๊ฒƒ๊นŒ์ง€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜๋ช…์ด ์งง์€ ๋ช…๋ น์ค„ ๋„๊ตฌ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ž‘์€ ๋ˆ„์ˆ˜๋Š” ์ „ํ˜€ ๊ฐ์ง€๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜๊ณ  ์šด์˜ ์ฒด์ œ๊ฐ€ ๋ชจ๋“  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšŒ์ˆ˜ํ•˜๋ฏ€๋กœ ๋ˆ„์ˆ˜๋กœ ์ธํ•œ ์˜ํ–ฅ์€ ๊ด€์ฐฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ช‡ ์ฃผ ๋™์•ˆ ์ง€์†์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ์„œ๋ฒ„ ํ”„๋กœ์„ธ์Šค์—์„œ ๋™์ผํ•œ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ๊พธ์ค€ํžˆ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„์ˆ˜๋กœ ์ธํ•ด RAM ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ์šด์˜ ์ฒด์ œ๋Š” ํŽ˜์ด์ง•์„ ์‹œ์ž‘ํ•˜๊ณ  ์‘๋‹ต ์‹œ๊ฐ„์ด ์ฆ๊ฐ€ํ•˜๋ฉฐ ๊ฒฐ๊ตญ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ถฉ๋Œํ•˜๊ฑฐ๋‚˜ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์œผ๋กœ ์ธํ•ด ๊ฐ•์ œ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๊ฐ€๋ฐ”์ดํŠธ๊ฐ€ ์•„๋‹Œ ํ‚ฌ๋กœ๋ฐ”์ดํŠธ ๋‹จ์œ„์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ž„๋ฒ ๋””๋“œ ์‹œ์Šคํ…œ์—์„œ๋Š” ์‹œ๊ฐ„๋‹น ๋ช‡ ๋ฐ”์ดํŠธ์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ์ž‘์€ ๋ˆ„์ˆ˜์กฐ์ฐจ๋„ ๋ฉฐ์น  ๋‚ด์— ์žฅ์น˜ ๊ณ ์žฅ์„ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ์›์ธ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ์›์ธ์€ ์–ธ์–ด ๋ฐ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ๊ทผ๋ณธ์ ์ธ ํŒจํ„ด์ด ๋ชจ๋“  ๊ฒฝ์šฐ์— ๊ณตํ†ต์ ์œผ๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

C ๋ฐ C++์—์„œ์˜ ์ˆ˜๋™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์˜ค๋ฅ˜

C์™€ C++์—์„œ๋Š” ๋ชจ๋“  ๋™์  ํ• ๋‹น์—๋Š” ๋ช…์‹œ์ ์ธ ํ• ๋‹น ํ•ด์ œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ ํ•˜๋‚˜์˜ ํ• ๋‹น ํ•ด์ œ๊ฐ€ ๋ˆ„๋ฝ๋˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. free or delete ์ˆ˜๋ฐฑ๋งŒ ๋ฒˆ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ ๊ฒฝ๋กœ์—์„œ ์‹ฌ๊ฐํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์›์ธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์˜ค๋ฅ˜ ๊ฒฝ๋กœ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ํ•ด์ œ๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ผ์ฐ ํ• ๋‹นํ•œ ํ›„ ์ผ๋ จ์˜ ์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ, ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ํ•จ์ˆ˜๊ฐ€ ์ผ์ฐ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ๋นˆ๋„๊ฐ€ ๋‚ฎ๋‹ค๋ฉด ํ…Œ์ŠคํŠธ ๊ณผ์ •์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํฌ์ธํ„ฐ๋ฅผ ์žƒ์–ด๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค. ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๊ฐ€ ์›๋ž˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋˜๊ธฐ ์ „์— ์ƒˆ ๊ฐ’์œผ๋กœ ๋ฎ์–ด์“ฐ์—ฌ์ง‘๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์›๋ž˜ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ์›๋ณธ์„ ํ•ด์ œํ•˜์ง€ ์•Š๊ณ  ์žฌํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœ realloc ๋งŒ์•ฝ ์ž˜๋ชป๋œ ๊ฒฝ์šฐ ์›๋ž˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. realloc null์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์›๋ž˜ ํ• ๋‹น๋œ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

c

// Bug: early return on error loses the allocation
char *process_data(int size) {
    char *buf = malloc(size);
    if (!buf) return NULL;

    if (validate(buf) < 0) {
        return NULL;   // BUG: buf is never freed
    }
    return buf;
}

// Fix: free before returning on every error path
char *process_data_fixed(int size) {
    char *buf = malloc(size);
    if (!buf) return NULL;

    if (validate(buf) < 0) {
        free(buf);     // release before returning
        return NULL;
    }
    return buf;
}

๊ฐ€๋น„์ง€ ์ˆ˜์ง‘ ์–ธ์–ด์˜ ์ˆœํ™˜ ์ฐธ์กฐ

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

"๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ์žˆ๋Š” ์–ธ์–ด์—์„œ ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ์ผ์œผํ‚ค๋Š”๊ฐ€?"๋ผ๋Š” ์งˆ๋ฌธ์€ ์ด ๋ถ„์•ผ์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ๊ฒ€์ƒ‰๋˜๋Š” ์งˆ๋ฌธ ์ค‘ ํ•˜๋‚˜์ด๋ฉฐ ๋ช…ํ™•ํ•œ ๋‹ต๋ณ€์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. CPython์—์„œ๋Š” ๊ด€๋ จ๋œ ๊ฐ์ฒด์— ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. __del__ ๋ฉ”์„œ๋“œ. CPython์˜ ์ˆœํ™˜ ์ฐธ์กฐ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ, ๊ณผ๊ฑฐ์—๋Š” ํŒŒ์ด๋„๋ผ์ด์ €๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด์™€ ๊ด€๋ จ๋œ ์ˆœํ™˜ ์ฐธ์กฐ๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ํšŒ์ˆ˜ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. Java์™€ ์ตœ์‹  .NET์—์„œ๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. JavaScript์˜ ๊ฒฝ์šฐ, ์ด์ „ ๋ฒ„์ „์˜ Internet Explorer DOM์—์„œ ์ˆœํ™˜ ์ฐธ์กฐ๋กœ ์ธํ•ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”๋ฐ, ์ด๋Š” JavaScript ์—”์ง„์˜ DOM ๋…ธ๋“œ ์ฐธ์กฐ ์นด์šดํŒ… ๋ฐฉ์‹์ด ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

ํŒŒ์ด์ฌ

# Python circular reference example
class Node:
    def __init__(self, value):
        self.value = value
        self.parent = None
        self.child = None

a = Node(1)
b = Node(2)
a.child = b    # a references b
b.parent = a   # b references a -- cycle formed

del a          # neither a nor b collected immediately
del b          # Python's cyclic GC will eventually collect them
               # but __del__ on either object would block collection
               # in older Python versions

๋‹ซํžˆ์ง€ ์•Š์€ ๋ฆฌ์†Œ์Šค: ํŒŒ์ผ ํ•ธ๋“ค, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ, ์†Œ์ผ“

ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ, ๋„คํŠธ์›Œํฌ ์†Œ์ผ“, GUI ํ•ธ๋“ค๊ณผ ๊ฐ™์€ ์šด์˜ ์ฒด์ œ ๋ฆฌ์†Œ์Šค๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์—์„œ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฆฌ์†Œ์Šค๋Š” ๋ช…์‹œ์ ์œผ๋กœ ๋‹ซ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ซ์ง€ ์•Š์œผ๋ฉด ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๊ณ ๊ฐˆ(Linux์—์„œ๋Š” "์—ด๋ฆฐ ํŒŒ์ผ์ด ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค" ์˜ค๋ฅ˜), ์—ฐ๊ฒฐ ํ’€ ๊ณ ๊ฐˆ ๋˜๋Š” ๊ณ ์ฒ˜๋ฆฌ๋Ÿ‰ ์„œ๋ฒ„์—์„œ ์†Œ์ผ“ ๊ณ ๊ฐˆ๊ณผ ๊ฐ™์€ ๋ฆฌ์†Œ์Šค ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ด์ฌ

# Bug: file handle leaked if exception occurs between open and close
def read_config(path):
    f = open(path)
    data = f.read()
    # if processing raises an exception, f is never closed
    process(data)
    f.close()

# Fix: context manager guarantees closure regardless of exceptions
def read_config_fixed(path):
    with open(path) as f:
        data = f.read()
    process(data)

์ž๋ฐ”

// Java: try-with-resources guarantees closure
try (Connection conn = dataSource.getConnection();
     PreparedStatement stmt = conn.prepareStatement(sql)) {
    ResultSet rs = stmt.executeQuery();
    while (rs.next()) {
        // process results
    }
}  // conn and stmt closed automatically, even on exception

๋ฌดํ•œ ๋˜๋Š” ์„ฑ์žฅํ•˜๋Š” ์ปฌ๋ ‰์…˜

ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋˜์ง€๋งŒ ์‚ญ์ œ๋˜์ง€ ์•Š๊ณ  ๋ฌดํ•œํžˆ ์ปค์ง€๋Š” ์ปฌ๋ ‰์…˜์€ ๋ชจ๋“  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ๋ณด์•ˆ ์ทจ์•ฝ์ (๋ˆ„์ˆ˜)์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์˜ˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์‚ญ์ œ ์ •์ฑ… ์—†์ด ๊ฒฐ๊ณผ๋ฅผ ๋ฌด๊ธฐํ•œ ์ €์žฅํ•˜๋Š” ์บ์‹œ
  • ์ด์ „ ํ•ญ๋ชฉ์„ ์‚ญ์ œํ•˜์ง€ ์•Š๊ณ  ๋ชจ๋“  ๋ฉ”์‹œ์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ด๋ฒคํŠธ ๋กœ๊ทธ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.
  • ์ƒˆ๋กœ์šด ์—ฐ๊ฒฐ์„ ์ถ”๊ฐ€ํ•˜์ง€๋งŒ ๋‹ซํžŒ ์—ฐ๊ฒฐ์€ ์‚ญ์ œํ•˜์ง€ ์•Š๋Š” ์—ฐ๊ฒฐ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์ž…๋‹ˆ๋‹ค.

์ž๋ฐ”

// Bug: cache grows indefinitely -- classic Java memory leak pattern
private static final Map<String, Object> cache = new HashMap<>();

public void process(String key) {
    cache.put(key, expensiveOperation(key));
    // key is never removed from cache
}

// Fix: use a cache with eviction policy
private static final Map<String, Object> cache =
    Collections.synchronizedMap(
        new LinkedHashMap<String, Object>(1000, 0.75f, true) {
            protected boolean removeEldestEntry(Map.Entry e) {
                return size() > 1000;  // LRU eviction at 1000 entries
            }
        }
    );

์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ๋ฐ ์ฝœ๋ฐฑ ๋ˆ„์ถœ

์ด๋ฒคํŠธ ์†Œ์Šค์— ๋ฆฌ์Šค๋„ˆ ๋˜๋Š” ์ฝœ๋ฐฑ์ด ๋“ฑ๋ก๋˜์—ˆ์ง€๋งŒ ๋“ฑ๋ก ํ•ด์ œ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ์ด๋ฒคํŠธ ์†Œ์Šค๋Š” ํ•ด๋‹น ๋ฆฌ์Šค๋„ˆ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๊ณ„์† ๋ณด์œ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ์ฐธ์กฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๋ชจ๋“  ์ฐธ์กฐ๊ฐ€ ํ•ด์ œ๋˜์—ˆ๋”๋ผ๋„ ๋ฆฌ์Šค๋„ˆ๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด JavaScript, Android ๋ฐ Java Swing ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฐ€์žฅ ํ”ํ•œ ์›์ธ์ž…๋‹ˆ๋‹ค.

์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ

// JavaScript: event listener leak
function setup() {
    const handler = () => doWork();
    document.addEventListener('click', handler);
    // handler is never removed -- listener holds a reference forever
}

// Fix: remove listener when no longer needed
function setup() {
    const handler = () => doWork();
    document.addEventListener('click', handler);
    return () => document.removeEventListener('click', handler);  // cleanup function
}

์ž๋ฐ”

// Android: Activity leaked via static listener
class MainActivity extends Activity {
    private static OnDataListener listener;  // static holds Activity reference

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        listener = data -> updateUI(data);   // BUG: Activity can't be GC'd
        dataService.register(listener);
    }

    @Override
    protected void onDestroy() {
        dataService.unregister(listener);    // Fix: deregister on destroy
        listener = null;
    }
}

์Šค๋ ˆ๋“œ ๋กœ์ปฌ ์ €์žฅ์†Œ ๋ˆ„์ถœ

์ž๋ฐ”์—์„œ๋Š” ThreadLocal ๋ณ€์ˆ˜๋Š” ๊ฐ’์„ ์Šค๋ ˆ๋“œ์— ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ ํ’€์ด ์žˆ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์š”์ฒญ ๊ฐ„์— ์žฌ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ThreadLocal ํ•ด๋‹น ๊ฐ’์€ ๊ฐ ์š”์ฒญ ํ›„์— ์ œ๊ฑฐ๋˜์ง€ ์•Š๊ณ  ์Šค๋ ˆ๋“œ์— ๋ฐ”์ธ๋”ฉ๋œ ์ƒํƒœ๋กœ ์œ ์ง€๋˜๋ฉฐ ์š”์ฒญ ์ „๋ฐ˜์— ๊ฑธ์ณ ๋ˆ„์ ๋ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”

// Bug: ThreadLocal not cleared -- leaks across pooled threads
private static final ThreadLocal<UserContext> context = new ThreadLocal<>();

public void handleRequest(Request req) {
    context.set(new UserContext(req.getUser()));
    processRequest();
    // BUG: context.remove() never called
    // Next request on this thread inherits previous request's context
}

// Fix: always remove in a finally block
public void handleRequest(Request req) {
    try {
        context.set(new UserContext(req.getUser()));
        processRequest();
    } finally {
        context.remove();  // guarantees cleanup even on exception
    }
}

C++ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ์˜ค์šฉ

std::shared_ptr ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐ์ฒด๊ฐ€ ๋‹ค์Œ์„ ๊ฐ€์งˆ ๋•Œ. shared_ptr ์„œ๋กœ์— ๋Œ€ํ•œ ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” ์ ˆ๋Œ€ 0์— ๋„๋‹ฌํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์–ด๋А ์ชฝ๋„ ํŒŒ๊ดด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

CPP

#include <memory>

struct Node {
    std::shared_ptr<Node> next;  // strong reference
};

// Cycle: neither node destroyed
auto a = std::make_shared<Node>();
auto b = std::make_shared<Node>();
a->next = b;
b->next = a;  // cycle -- both a and b leaked

// Fix: use weak_ptr to break the cycle
struct Node {
    std::weak_ptr<Node> next;   // weak reference does not affect refcount
};

์ •์  ๋ฐ ์ „์—ญ ๋ณ€์ˆ˜ ๋ˆ„์ 

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

์–ธ์–ด๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

C ์–ธ์–ด์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

C ์–ธ์–ด์—๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ์—†๊ณ , ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ์ถ”์ ํ•˜๋Š” ํ‘œ์ค€ ๋ฉ”์ปค๋‹ˆ์ฆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. malloc, calloc๋ฐ realloc ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœ๊ณผ ํ•จ๊ป˜ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. free์ฃผ์š” ํƒ์ง€ ๋„๊ตฌ๋Š” Valgrind์ž…๋‹ˆ๋‹ค.valgrind --leak-check=full ./program) ๋Ÿฐํƒ€์ž„ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ์ž‘์—…์„ ๊ณ„์ธกํ•˜๊ณ  ํ•ด์ œ๋˜์ง€ ์•Š์€ ๋ชจ๋“  ํ• ๋‹น์„ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค. AddressSanitizer(-fsanitize=address์ปดํŒŒ์ผ ์‹œ์ ์— ์ตœ์†Œํ•œ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๊ฐ์ง€ํ•˜๋ฉฐ, ์ง€์†์  ํ†ตํ•ฉ ํŒŒ์ดํ”„๋ผ์ธ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

C ์–ธ์–ด์—์„œ ๊ฐ€์žฅ ํšจ๊ณผ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ๋ฐฉ์ง€ ์ „๋žต์€ ์†Œ์œ ๊ถŒ์„ ๋ช…ํ™•ํžˆ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ํ• ๋‹น์—๋Š” ํ•ด๋‹น ํ• ๋‹น์„ ํ•ด์ œํ•  ์ฑ…์ž„์ด ์žˆ๋Š” ์†Œ์œ ์ž๊ฐ€ ์ •ํ™•ํžˆ ํ•œ ๋ช… ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ๊ทธ ์†Œ์œ ๊ถŒ์€ ์ฃผ์„๊ณผ ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์— ๋ฌธ์„œํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

C++์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

C++๋Š” C์˜ ์ž์› ํ• ๋‹น ๋ชจ๋ธ์— ์ƒ์„ฑ์ž, ์†Œ๋ฉธ์ž ๋ฐ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. RAII(Resource Acquisition Is Initialization, ์ž์› ํš๋“์€ ์ดˆ๊ธฐํ™”) ์›์น™, ์ฆ‰ ์ƒ์„ฑ์ž์—์„œ ์ž์›์„ ํš๋“ํ•˜๊ณ  ์†Œ๋ฉธ์ž์—์„œ ์ž์›์„ ํ•ด์ œํ•˜๋Š” ์›์น™์ด ์ฃผ์š” ์ž์› ํ• ๋‹น ๋ฐฉ์ง€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. std::unique_ptr std::shared_ptr ์›์‹œ ํฌ์ธํ„ฐ ๋Œ€์‹  ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„์˜ ์ˆ˜๋™ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ์ž‘์—…์ด ํ•„์š” ์—†์–ด์ง‘๋‹ˆ๋‹ค. ๊ฐ์ง€ ๋„๊ตฌ๋กœ๋Š” Valgrind, AddressSanitizer, ๊ทธ๋ฆฌ๊ณ  Windows์šฉ Visual Studio์˜ CRT ๋””๋ฒ„๊ทธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

C++์—์„œ ํ”ํžˆ ๋ฐœ์ƒํ•˜๋Š” ์›์ธ์œผ๋กœ๋Š” ๊ธฐ๋ณธ ํด๋ž˜์Šค์—์„œ ์†Œ๋ฉธ์ž๋ฅผ ๊ฐ€์ƒ์œผ๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์„ ์žŠ๋Š” ๊ฒฝ์šฐ(ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๊ฐ€ ๊ธฐ๋ณธ ํด๋ž˜์Šค ํฌ์ธํ„ฐ๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœ๋˜์ง€ ์•Š์Œ), ์›์‹œ ํฌ์ธํ„ฐ์™€ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋ฅผ ํ˜ผ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. shared_ptr ์œ„์—์„œ ์„ค๋ช…ํ•œ ์›ํ˜• ์ฐธ์กฐ ํŒจํ„ด.

์ž๋ฐ”์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

Java์˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ํž™ ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜์ง€๋งŒ ์šด์˜์ฒด์ œ ๋ฆฌ์†Œ์Šค๋Š” ๊ด€๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ Java ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํŒจํ„ด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•˜๋Š” ์ •์  ํ•„๋“œ
  • ๋ฌด์ œํ•œ ์บ์‹œ ๋ฐ ์ปฌ๋ ‰์…˜
  • ๋‹ซํžˆ์ง€ ์•Š์€ ์ŠคํŠธ๋ฆผ, ์—ฐ๊ฒฐ ๋ฐ ๋…์ž
  • finally ๋ธ”๋ก์—์„œ ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜๊ฐ€ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ฒญ์ทจ์ž ๋“ฑ๋ก์€ ์‚ญ์ œ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

ํƒ์ง€ ๋„๊ตฌ: VisualVM(๋ฌด๋ฃŒ, JDK์— ํฌํ•จ), ํž™ ๋คํ”„ ๋ถ„์„์„ ์œ„ํ•œ Eclipse Memory Analyzer(MAT), YourKit, JProfiler ๋ฐ JVM ํ”Œ๋ž˜๊ทธ -XX:+HeapDumpOnOutOfMemoryError OOM(๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ)์ด ๋ฐœ์ƒํ•˜๋ฉด ํž™ ๋คํ”„๋ฅผ ์ž๋™์œผ๋กœ ์บก์ฒ˜ํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ด์ฌ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

Python์€ ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ฐธ์กฐ ์นด์šดํŒ…๊ณผ ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Python์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฌดํ•œํžˆ ํ™•์žฅ๋˜๋Š” ์žฅ๊ธฐ๊ฐ„ ์œ ์ง€๋˜๋Š” ์บ์‹œ ๋˜๋Š” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ
  • ๊ฐ์ฒด์™€ ๊ด€๋ จ๋œ ์ˆœํ™˜ ์ฐธ์กฐ __del__ ์ด์ „ Python ๋ฒ„์ „์˜ ๋ฉ”์„œ๋“œ
  • ๋ชจ๋“ˆ ์ˆ˜์ค€์˜ ์ „์—ญ ๋ณ€์ˆ˜์— ์ €์žฅ๋œ ๋Œ€ํ˜• ๊ฐ์ฒด
  • ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ž˜๋ชป ๊ด€๋ฆฌํ•˜๋Š” C ํ™•์žฅ ๊ธฐ๋Šฅ

ํƒ์ง€ ๋„๊ตฌ: tracemalloc (ํŒŒ์ด์ฌ 3.4๋ถ€ํ„ฐ ๋‚ด์žฅ๋จ) objgraph ๊ฐ์ฒด ์ฐธ์กฐ ๊ทธ๋ž˜ํ”„๋ฅผ ์‹œ๊ฐํ™”ํ•˜๊ธฐ ์œ„ํ•ด, memory_profiler ๋ผ์ธ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ์ธก์ •์„ ์œ„ํ•ด.

ํŒŒ์ด์ฌ

import tracemalloc

tracemalloc.start()

# ... run the code under test ...

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

for stat in top_stats[:10]:
    print(stat)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜๋„์น˜ ์•Š์€ ์ฐธ์กฐ๋กœ ์ธํ•ด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ๋ถˆ๊ฐ€๋Šฅํ•ด์ง€๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • DOM ๋…ธ๋“œ๊ฐ€ ๋ฌธ์„œ์—์„œ ์ œ๊ฑฐ๋˜์—ˆ์ง€๋งŒ JavaScript ํด๋กœ์ €์—์„œ๋Š” ์—ฌ์ „ํžˆ ์ฐธ์กฐ๋ฉ๋‹ˆ๋‹ค.
  • ์‹œ๊ฐ„์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ•์ ๋˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜
  • ํƒ€์ด๋จธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. setInterval ์ ˆ๋Œ€ ์‚ญ์ œ๋˜์ง€ ์•Š๋Š” ๊ฒƒ๋“ค
  • ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ˆ˜๋ช…์ด ๊ธด ๊ฐ์ฒด์—์„œ ์ œ๊ฑฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

ํƒ์ง€ ๋ฐฉ๋ฒ•: Chrome ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ ๋ฉ”๋ชจ๋ฆฌ ํƒญ(ํž™ ์Šค๋ƒ…์ƒท, ํ• ๋‹น ํƒ€์ž„๋ผ์ธ), Firefox ๋ฉ”๋ชจ๋ฆฌ ํ”„๋กœํŒŒ์ผ๋Ÿฌ.

์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ

// Bug: interval holds reference to elements indefinitely
const elements = [];
const interval = setInterval(() => {
    elements.push(document.createElement('div'));  // grows forever
}, 100);

// Fix: clear interval when done
clearInterval(interval);
elements.length = 0;  // release array contents

C#์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

C#๊ณผ .NET์€ ์„ธ๋Œ€๋ณ„ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ์ˆ˜๋ช…์ด ๊ธด ๊ฐ์ฒด์— ๋“ฑ๋ก๋œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ๋“ฑ๋ก ํ•ด์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฌดํ•œํžˆ ์ปค์ง€๋Š” ์ •์  ์ปฌ๋ ‰์…˜
  • ๊ด€๋ฆฌ๋˜์ง€ ์•Š์€ ์ž์›์€ ์ฒ˜๋ถ„๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. IDisposable
  • ๋นˆ๋ฒˆํ•œ ๋Œ€๊ทœ๋ชจ ํ• ๋‹น์œผ๋กœ ์ธํ•œ ๋Œ€ํ˜• ๊ฐ์ฒด ํž™(LOH) ์กฐ๊ฐํ™”

ํƒ์ง€: dotMemory, Visual Studio ์ง„๋‹จ ๋„๊ตฌ, PerfView๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์„ธํ•œ GC ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋‚ ์นด๋กœ์šด

// Fix: implement IDisposable for explicit resource cleanup
public class DatabaseConnection : IDisposable {
    private SqlConnection _connection;
    private bool _disposed = false;

    public DatabaseConnection(string connectionString) {
        _connection = new SqlConnection(connectionString);
    }

    public void Dispose() {
        if (!_disposed) {
            _connection?.Dispose();
            _disposed = true;
        }
    }
}

// Use with 'using' to guarantee Dispose is called
using (var conn = new DatabaseConnection(connectionString)) {
    // use connection
}  // Dispose called here automatically

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํƒ์ง€: ๋„๊ตฌ ๋ฐ ๊ธฐ๋ฒ•

์–ธ์–ด๋ณ„ ํƒ์ง€ ๋„๊ตฌ

Language์ˆ˜๋‹จ๋ฌด์—‡์„ ๊ฐ์ง€ํ•˜๋Š”๊ฐ€
C/C++๋ฐœ๊ทธ๋ผ์ธ๋“œ(๋ฉค์ฒดํฌ)ํž™ ๋ˆ„์ˆ˜, ์ž˜๋ชป๋œ ์ฝ๊ธฐ/์“ฐ๊ธฐ, ํ•ด์ œ ํ›„ ์‚ฌ์šฉ
C/C++์ฃผ์†Œ์„ธ๋‹ˆํƒ€์ด์ €๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜, ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ, ํ•ด์ œ ํ›„ ์‚ฌ์šฉ, ๋น ๋ฅธ ์‹คํ–‰ ์‹œ๊ฐ„
C + +๋ฉ”๋ชจ๋ฆฌ ๋ฐ•์‚ฌWindows/Linux ํž™ ๋ฐ ํ•ธ๋“ค ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜
์ž๋ฐ”์ดํด๋ฆฝ์Šค MATํž™ ๋คํ”„ ๋ถ„์„, ๋„๋ฏธ๋„ค์ดํ„ฐ ํŠธ๋ฆฌ, ๋ˆ„์ถœ ์˜์‹ฌ ์š”์†Œ
์ž๋ฐ”๋น„์ฃผ์–ผ VM์‹ค์‹œ๊ฐ„ ํž™ ๋ชจ๋‹ˆํ„ฐ๋ง, GC ๋™์ž‘ ๋ถ„์„, ์Šค๋ ˆ๋“œ ๋ถ„์„
์ž๋ฐ”JProfiler / YourKit์‹ฌ์ธต์ ์ธ ํ• ๋‹น ์ถ”์  ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ˜ ์ƒ์—… ํ”„๋กœํŒŒ์ผ๋Ÿฌ
PythonํŠธ๋ ˆ์ด์Šค๋ง๋กPython 3.4๋ถ€ํ„ฐ ๋‚ด์žฅ๋œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์ถ”์  ๊ธฐ๋Šฅ
Python๊ฐ์ฒด ๊ทธ๋ž˜ํ”„๊ฐ์ฒด ์ฐธ์กฐ ๊ทธ๋ž˜ํ”„ ์‹œ๊ฐํ™”
Python๋ฉ”๋ชจ๋ฆฌ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๋ผ์ธ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ์ธก์ •
JavaScriptChrome DevToolsํž™ ์Šค๋ƒ…์ƒท, ํ• ๋‹น ํƒ€์ž„๋ผ์ธ, ์œ ์ง€ ํฌ๊ธฐ
C # / .NET๋„ํŠธ๋ฉ”๋ชจ๋ฆฌ๊ฐ์ฒด ์œ ์ง€, ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๋ถ„์„
C # / .NET์„ฑ๋Šฅ ๋ณด๊ธฐGC ์ด๋ฒคํŠธ, ํ• ๋‹น ์Šคํƒ, ๋ฉ”๋ชจ๋ฆฌ ์••๋ ฅ
์ „์ฒด / ์ œ์ž‘๋‰ด๋ ๋ฆญ, ๋ฐ์ดํ„ฐ๋…, ๋‹ค์ด๋‚˜ํŠธ๋ ˆ์ด์Šค์ง€์†์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋‹ˆํ„ฐ๋ง, ์ด์ƒ ํƒ์ง€

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์ฐพ๋Š” ๋ฐฉ๋ฒ•: ๋‹จ๊ณ„๋ณ„ ์ ‘๊ทผ ๋ฐฉ์‹

1๋‹จ๊ณ„: ๋ˆ„์ถœ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ๋ถ€ํ•˜ ์กฐ๊ฑด์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๊ณ  ์‹œ์Šคํ…œ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๊ฐ„ ๊ฒฝ๊ณผ์— ๋”ฐ๋ฅธ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์‹ญ์‹œ์˜ค.top, htop(์ž‘์—… ๊ด€๋ฆฌ์ž ๋˜๋Š” ๋ชจ๋‹ˆํ„ฐ๋ง ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.) ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์•ˆ์ •ํ™”๋˜์ง€ ์•Š๊ณ  ์ง€์†์ ์œผ๋กœ ์ฆ๊ฐ€ํ•œ๋‹ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

2๋‹จ๊ณ„: ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ฝ”๋“œ ๊ฒฝ๋กœ๋ฅผ ๊ฒฉ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€์™€ ๊ด€๋ จ๋œ ์ž‘์—…์„ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ์›Œํฌํ”Œ๋กœ(๋กœ๊ทธ์ธ, ํŒŒ์ผ ์—…๋กœ๋“œ, ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ ๋“ฑ)๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰ํ•˜๊ณ  ๊ฐ ์‹คํ–‰๋งˆ๋‹ค ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š”์ง€ ๊ด€์ฐฐํ•˜๋ฉด ํ•ด๋‹น ์›Œํฌํ”Œ๋กœ๊ฐ€ ๋ฌธ์ œ์˜ ์›์ธ์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3๋‹จ๊ณ„: ์˜์‹ฌ์Šค๋Ÿฌ์šด ์›Œํฌํ”Œ๋กœ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณต ์‹คํ–‰ํ•œ ํ›„ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํž™ ์Šค๋ƒ…์ƒท์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ ์Šค๋ƒ…์ƒท๋“ค์„ ๋น„๊ตํ•˜์—ฌ ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ๋ˆ„์ ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

4๋‹จ๊ณ„: ์ฐธ์กฐ ์ฒด์ธ์„ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœํŒŒ์ผ๋ง ๋„๊ตฌ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ๋‚จ์•„ ์žˆ๋Š” ์ด์œ ์™€ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ฃจํŠธ ์ฐธ์กฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์œ ์ง€ ํŠธ๋ฆฌ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฒด์ธ์„ ๋”ฐ๋ผ๊ฐ€๋ฉด ์œ ์ง€ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5๋‹จ๊ณ„: ์ˆ˜์ • ๋ฐ ๊ฒ€์ฆ. ์˜์‹ฌ๋˜๋Š” ์›์ธ์„ ์ˆ˜์ •ํ•œ ํ›„ ์Šค๋ƒ…์ƒท ๋น„๊ต๋ฅผ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์›Œํฌํ”Œ๋กœ ๋ฐ˜๋ณต ํ›„ ๊ฐ์ฒด ์ˆ˜๊ฐ€ ๋” ์ด์ƒ ์ฆ๊ฐ€ํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์‹œ๊ฐ„ ๊ฒฝ๊ณผ์— ๋”ฐ๋ฅธ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ชจ๋‹ˆํ„ฐ๋ง: ๋А๋ฆฐ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๊ฐ์ง€

์‹œ๊ฐ„๋‹น ๋ช‡ ํ‚ฌ๋กœ๋ฐ”์ดํŠธ ์ •๋„์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ˆ„์ถœ๋˜๋Š” ๋А๋ฆฐ ๋ˆ„์ˆ˜๋Š” ์งง์€ ํ…Œ์ŠคํŠธ ์‹คํ–‰์—์„œ๋Š” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ˆ„์ˆ˜๋ฅผ ๊ฐ์ง€ํ•˜๋ ค๋ฉด ์žฅ๊ธฐ๊ฐ„ ๊ด€์ฐฐ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ •๊ธฐ์ ์œผ๋กœ ์ถ”์ ํ•˜๊ณ  ์‚ฌ์šฉ๋Ÿ‰์ด ๊ธฐ์ค€์น˜๋ฅผ ์ดˆ๊ณผํ•˜๊ฑฐ๋‚˜ ์ •์˜๋œ ์ฆ๊ฐ€์œจ์„ ๋„˜์–ด์„œ๋ฉด ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋„๋ก ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•˜์‹ญ์‹œ์˜ค. ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” Datadog, New Relic, Dynatrace์™€ ๊ฐ™์€ APM ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์†์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋‹ˆํ„ฐ๋ง, ์•Œ๋ฆผ ๋ฐ ์ด๋ ฅ ๋น„๊ต ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•

๊ตฌ์กฐํ™”๋œ ์ž์› ๊ด€๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜์„ธ์š”

๋ชจ๋“  ์–ธ์–ด๋Š” ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ๋ฅผ ๋ณด์žฅํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ์‚ฌ์šฉํ•˜์„ธ์š”.

  • C ++ : RAII๋Š” ์ƒ์„ฑ์ž์—์„œ ํš๋“ํ•˜๊ณ  ์†Œ๋ฉธ์ž์—์„œ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ std::unique_ptr std::shared_ptr ํž™ ๋ฉ”๋ชจ๋ฆฌ์šฉ๊ณผ ํŒŒ์ผ ํ•ธ๋“ค ๋ฐ ์†Œ์ผ“์šฉ ์‚ฌ์šฉ์ž ์ง€์ • RAII ๋ž˜ํผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ž๋ฐ” : try-with-resources ์„ ํ†ตํ•œ AutoCloseable ์ž์›.
  • ํŒŒ์ด์ฌ : with ํŒŒ์ผ, ์ž ๊ธˆ ๋ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž(๋ฌธ์„œ)์ž…๋‹ˆ๋‹ค.
  • ์”จ#: using ์— ๋Œ€ํ•œ ์ง„์ˆ  IDisposable ์‚ฌ๋ฌผ.
  • ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ : ๋ช…์‹œ์  ์ •๋ฆฌ ํ•จ์ˆ˜, WeakRef FinalizationRegistry ์บ์‹œ์šฉ์ž…๋‹ˆ๋‹ค.

๋ฆฌ์Šค๋„ˆ ๋ฐ ์ฝœ๋ฐฑ ๋“ฑ๋ก ํ•ด์ œ

๋ชจ๋“  ๋“ฑ๋ก์—๋Š” ๋“ฑ๋ก ํ•ด์ œ๊ฐ€ ์ˆ˜๋ฐ˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ(React, Android, Angular, Qt)์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ teardown ๋ผ์ดํ”„์‚ฌ์ดํด ๋ฉ”์„œ๋“œ์—์„œ ๋“ฑ๋ก ํ•ด์ œ๋ฅผ ์ˆ˜ํ–‰ํ•˜์„ธ์š”. useEffect React์—์„œ์˜ ์ •๋ฆฌ ์ž‘์—… onDestroy ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ, ngOnDestroy Angular์—์„œ ์†Œ๋ฉธ์ž ๋˜๋Š” disconnectedCallback ์›น ๊ตฌ์„ฑ ์š”์†Œ์—์„œ.

์ˆœํ™˜ ์ฐธ์กฐ ๋Š๊ธฐ

๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•  ๋•Œ๋Š” ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ ์•ฝํ•œ ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋Š” ์ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

  • ํŒŒ์ด์ฌ : weakref.ref() or weakref.WeakValueDictionary
  • C ++ : std::weak_ptr
  • ์ž๋ฐ” : java.lang.ref.WeakReference
  • ์”จ#: WeakReference<T>
  • ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ : WeakMap, WeakSet, WeakRef

์บ์‹œ์— ์ œ๊ฑฐ ์ •์ฑ… ๊ตฌํ˜„

์ตœ๋Œ€ ํฌ๊ธฐ๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ์บ์‹œ๋Š” ์ž ์žฌ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์ž…๋‹ˆ๋‹ค. ํฌ๊ธฐ ์ œํ•œ์„ ๋‘๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. Java์—์„œ๋Š” LRU ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.LinkedHashMap ๊ณผ removeEldestEntry), functools.lru_cache ํŒŒ์ด์ฌ์—์„œ, WeakHashMap ๊ฐ์ฒด์˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ์ถ”์ ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๊ฐ์ฒด๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ ๋˜๋Š” Caffeine(Java), cachetools(Python)๊ณผ ๊ฐ™์€ ์ „์šฉ ์บ์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. node-lru-cache (์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ)

CI/CD์— ๋ฉ”๋ชจ๋ฆฌ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ฉํ•˜์„ธ์š”

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๊ฐ์ง€๋Š” ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • C/C++ ๋นŒ๋“œ ๋ฐ ํ…Œ์ŠคํŠธ ํŒŒ์ดํ”„๋ผ์ธ์— Valgrind ๋˜๋Š” AddressSanitizer๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”.
  • ํž™ ์Šค๋ƒ…์ƒท ๋น„๊ต์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฐ์ฒด ์ฆ๊ฐ€๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฉด ๋นŒ๋“œ๋ฅผ ์‹คํŒจ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • pytest-memray or pytest-leaks ํŒŒ์ด์ฌ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์šฉ
  • ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ํ™œ์„ฑํ™”ํ•œ ์ƒํƒœ๋กœ ์Šคํ…Œ์ด์ง• ํ™˜๊ฒฝ์—์„œ ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์ž„๊ณ„๊ฐ’ ์œ„๋ฐ˜ ์‹œ ์‹คํŒจ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

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

ํŠน์ • ์ƒํ™ฉ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

๊ฒŒ์ž„์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

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

์ผ๋ฐ˜์ ์ธ ๊ฒŒ์ž„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํŒจํ„ด:

  • ์‹œ๊ฐ์ ์œผ๋กœ๋Š” ํŒŒ๊ดด๋˜์—ˆ์ง€๋งŒ ๋‚ด๋ถ€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋‚˜ ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ์—์„œ๋Š” ์ œ๊ฑฐ๋˜์ง€ ์•Š์€ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ
  • ์žฅ๋ฉด ์ „ํ™˜ ํ›„ ํ…์Šค์ฒ˜ ๋˜๋Š” ๋ฉ”์‹œ๊ฐ€ ์–ธ๋กœ๋“œ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ์—์…‹ ์ฐธ์กฐ
  • ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์†Œ๋ฉธ๋  ๋•Œ ๋ฌผ๋ฆฌ ์—”์ง„ ๊ฐ์ฒด๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํ•ด์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ทธ๋ž˜ํ”ฝ API ํ˜ธ์ถœ ์‹œ ์…ฐ์ด๋” ๋˜๋Š” GPU ๋ฆฌ์†Œ์Šค ํ•ธ๋“ค์ด ์œ ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฒŒ์ž„์—์„œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ๊ฐ์ง€ํ•˜๋Š” ๋ฐ์—๋Š” ์—”์ง„๋ณ„ ๋„๊ตฌ(Unity Profiler, Unreal Insights)์™€ ํ‘œ์ค€ ํž™ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ชจ๋‘ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ์”ฌ ๋กœ๋“œ ์‹œ ์Šค๋ƒ…์ƒท์„ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. ๋ ˆ๋ฒจ์„ ๋กœ๋“œํ•˜๊ณ  ์–ธ๋กœ๋“œํ•œ ํ›„ ํž™ ํฌ๊ธฐ๋Š” ๋กœ๋“œ ์ „๊ณผ ๊ฑฐ์˜ ๋™์ผํ•œ ํฌ๊ธฐ๋กœ ๋Œ์•„์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ž„๋ฒ ๋””๋“œ C ๋ฐ ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

์ž„๋ฒ ๋””๋“œ ์‹œ์Šคํ…œ์€ ๋ฉ”๋ชจ๋ฆฌ ์šฉ๋Ÿ‰์ด ๊ณ ์ •๋˜์–ด ์žˆ๊ฑฐ๋‚˜ ๋งค์šฐ ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค. ๋งˆ์ดํฌ๋กœ์ปจํŠธ๋กค๋Ÿฌ๋Š” 2KB์—์„œ 256KB ์‚ฌ์ด์˜ RAM์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์Šคํฌํ†ฑ ์‹œ์Šคํ…œ์—์„œ ์—ฐ์‚ฐ๋‹น 10๋ฐ”์ดํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์ž„๋ฒ ๋””๋“œ ํ•˜๋“œ์›จ์–ด์—์„œ๋Š” ์น˜๋ช…์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž„๋ฒ ๋””๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์˜ˆ๋ฐฉํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„์ˆ˜๊ฐ€ ๊ฐ์ง€๋  ๋•Œ์ฏค์ด๋ฉด ์‹œ์Šคํ…œ์ด ์ด๋ฏธ ๊ณ ์žฅ ๋‚˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ž„๋ฒ ๋””๋“œ C์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€:

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

๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฆฌ์†Œ์Šค ๋ˆ„์ˆ˜ ๋ฐฉ์ง€์—๋Š” ์†Œ์ผ“ ํ•ธ๋“ค, ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ, ๋ฒ„ํผ ํ• ๋‹น์— ์ ์šฉ๋˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ๊ทœ์œจ์ด โ€‹โ€‹ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์—ด๋ฆฐ ๋ชจ๋“  ์†Œ์ผ“์€ ๋‹ซ์•„์•ผ ํ•˜๊ณ , ๋„คํŠธ์›Œํฌ I/O๋ฅผ ์œ„ํ•ด ํ• ๋‹น๋œ ๋ชจ๋“  ๋ฒ„ํผ๋Š” ํ•ด์ œํ•ด์•ผ ํ•˜๋ฉฐ, ๋„คํŠธ์›Œํฌ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ๋ฅผ ์œ„ํ•ด ํš๋“ํ•œ ๋ชจ๋“  ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋Š” ํ•ด์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. SO_REUSEADDR SO_REUSEPORT ์†Œ์ผ“์ด ์ œ๋Œ€๋กœ ๋‹ซํžˆ๋Š” ๊ฒƒ์„ ๋Œ€์ฒดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ vs. ๋งค๋‹ฌ๋ฆฐ ํฌ์ธํ„ฐ vs. ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ

์ด ์„ธ ๊ฐ€์ง€๋Š” ๋ชจ๋‘ ์ž˜๋ชป๋œ ๊ธฐ์–ต ๊ด€๋ฆฌ์™€ ๊ด€๋ จ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”ํžˆ ํ˜ผ๋™๋˜์ง€๋งŒ, ์„œ๋กœ ๋‹ค๋ฅธ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

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

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

์ด ์„ธ ๊ฐ€์ง€ ๋ชจ๋‘ C/C++์˜ AddressSanitizer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. AddressSanitizer๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ž‘์—…์„ ๊ณ„์ธกํ•˜๊ณ  ๋Ÿฐํƒ€์ž„์— ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์ฝ”๋“œ ์˜ˆ์ œ

C: ๋ˆ„์ˆ˜ ์™„์ „ ์ œ๊ฑฐ ๋ฐ ์ˆ˜๋ฆฌ

c

#include <stdlib.h>
#include <string.h>

// Bug: user->name is never freed before user itself
typedef struct {
    char *name;
    int age;
} User;

User *create_user_buggy(const char *name, int age) {
    User *user = malloc(sizeof(User));
    user->name = strdup(name);  // allocates a copy of name
    user->age = age;
    return user;
}

void free_user_buggy(User *user) {
    free(user);           // BUG: user->name leaked
}

// Fix: free nested allocations before the container
void free_user_fixed(User *user) {
    if (user) {
        free(user->name); // free nested allocation first
        free(user);       // then free the container
    }
}

Java: ๋ฆฌ์Šค๋„ˆ ๋ˆ„์ˆ˜ ๋ฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์ž๋ฐ”

import java.util.ArrayList;
import java.util.List;

// Bug: listeners registered but never removed
public class EventBus {
    private static final List<Runnable> listeners = new ArrayList<>();

    public static void register(Runnable listener) {
        listeners.add(listener);
    }

    // Fix: provide a deregistration method
    public static void unregister(Runnable listener) {
        listeners.remove(listener);
    }
}

// Usage -- always pair register with unregister
public class MyComponent {
    private final Runnable listener = this::onEvent;

    public void attach() {
        EventBus.register(listener);
    }

    public void detach() {
        EventBus.unregister(listener);  // ensures no retained reference
    }

    private void onEvent() {
        // handle event
    }
}

C++: RAII ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ์ž

CPP

#include <cstdio>
#include <stdexcept>

// RAII wrapper: file is closed when FileHandle goes out of scope
class FileHandle {
    FILE *file_;
public:
    explicit FileHandle(const char *path, const char *mode)
        : file_(std::fopen(path, mode)) {
        if (!file_) throw std::runtime_error("Cannot open file");
    }
    ~FileHandle() { std::fclose(file_); }  // destructor guarantees close

    // Disable copy to prevent double-close
    FileHandle(const FileHandle&) = delete;
    FileHandle &operator=(const FileHandle&) = delete;

    FILE *get() const { return file_; }
};

void process_file(const char *path) {
    FileHandle fh(path, "r");  // opened here
    // use fh.get() ...
}   // ~FileHandle() called here automatically -- file closed even on exception

Python: tracemalloc ๋ˆ„์ถœ ๊ฐ์ง€

ํŒŒ์ด์ฌ

import tracemalloc

def leaking_function():
    data = []
    for _ in range(10000):
        data.append("x" * 1000)  # 10MB allocated, never freed
    return None  # data goes out of scope here but items may be cached

tracemalloc.start()
leaking_function()
snapshot = tracemalloc.take_snapshot()

top_stats = snapshot.statistics("lineno")
print("Top memory consumers:")
for stat in top_stats[:5]:
    print(stat)

๋ฐฉ๋ฒ• SMART TS XL ๋Œ€๊ทœ๋ชจ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.

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

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

  • ํ• ๋‹น ์‚ฌ์ดํŠธ(ํ˜ธ์ถœ ๋Œ€์ƒ) malloc, new, open, connect๋ชจ๋“  ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ ๊ฒฝ๋กœ์—์„œ ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” (๋ฐ ๊ฐ ์–ธ์–ด์—์„œ์˜ ๋™๋“ฑํ•œ ๋™์ž‘)
  • ๋ฆฌ์†Œ์Šค๊ฐ€ ํ• ๋‹น๋˜๊ธฐ ์ „์— ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ฒฝ๋กœ throw ํ•˜์ง€๋งŒ ํฌํš ๊ณผ์ •์—์„œ ๋˜๋Š” ์ตœ์ข…์ ์œผ๋กœ๋Š” ๋ฐฉ์ถœ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ˆ„์ ๋˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•˜๋Š” ์ •์  ๋ฐ ์ „์—ญ ํ•„๋“œ
  • ์ปดํฌ๋„ŒํŠธ ์ˆ˜๋ช… ์ฃผ๊ธฐ์—์„œ ํ•ด๋‹น ๋“ฑ๋ก ํ•ด์ œ๊ฐ€ ์—†๋Š” ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก ํ˜ธ์ถœ
  • ThreadLocal.set ๋Œ€์‘ํ•˜๋Š” ํ•ญ๋ชฉ์ด ์—†๋Š” ํ˜ธ์ถœ remove ๋งˆ์ง€๋ง‰ ๋ธ”๋ก์—์„œ

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

COBOL, JCL ๋ฐ ์ตœ์‹  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ๋ชจ๋‘ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ์˜ ๊ฒฝ์šฐ, SMART TS XL์˜ ๋ ˆ๊ฑฐ์‹œ ํ˜„๋Œ€ํ™” ์ด ๋ถ„์„์€ ์–ธ์–ด ๊ฐ„ ๋ฆฌ์†Œ์Šค ํ๋ฆ„์œผ๋กœ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฉ”์ธํ”„๋ ˆ์ž„ ํ”„๋กœ๊ทธ๋žจ์—์„œ ํš๋“ํ•œ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ณด์žฅ๋œ ํ•ด์ œ ๊ฒฝ๋กœ ์—†์ด Java ์„œ๋น„์Šค์—์„œ ์†Œ๋น„๋˜๋Š” ๊ฒฝ์šฐ๋‚˜ COBOL ํ”„๋กœ๊ทธ๋žจ์—์„œ ์—ด๋ฆฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์ด JCL ์ž‘์—… ์ŠคํŠธ๋ฆผ์ด ์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ๋‹ซํžˆ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ์–ต ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์Šต๊ด€

๋ชจ๋“  ์–ธ์–ด, ํ”„๋ ˆ์ž„์›Œํฌ, ๋Ÿฐํƒ€์ž„์€ ์ €๋งˆ๋‹ค ๊ณ ์œ ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ๋ชจ๋“  ํ™˜๊ฒฝ์—์„œ ๊ฐ€์žฅ ํšจ๊ณผ์ ์ธ ์Šต๊ด€์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ˆœ๊ฐ„ ๊ทธ ๋ฆฌ์†Œ์Šค์˜ ์†Œ์œ ์ž๋ฅผ ๋ช…ํ™•ํžˆ ํ•˜๊ณ , ์ฝ”๋“œ์— ์†Œ์œ ๊ถŒ์„ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์†Œ์œ ๊ถŒ์€ ๊ณง ์ฑ…์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํž™ ํ• ๋‹น์˜ ์†Œ์œ ์ž๋Š” ํ•ด๋‹น ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์˜ ์†Œ์œ ์ž๋Š” ์—ฐ๊ฒฐ์„ ๋‹ซ์œผ๋ฉฐ, ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์˜ ์†Œ์œ ์ž๋Š” ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์†Œ์œ ๊ถŒ์ด ๋ช…ํ™•ํ•˜๋ฉด ์ •๋ฆฌ ์ž‘์—…๋„ ๊ฐ„๋‹จํ•ด์ง‘๋‹ˆ๋‹ค. ์†Œ์œ ๊ถŒ์ด ๋ชจํ˜ธํ•˜๋ฉด ์ •๋ฆฌ ์ž‘์—…์ด ์ง€์—ฐ๋˜๊ณ , ์ด๋Ÿฌํ•œ ์ง€์—ฐ๋œ ์ •๋ฆฌ ์ž‘์—…์ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ์›์ธ์ด ๋ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ์ฝ”๋“œ ํŒจํ„ด์€ ์ด๋Ÿฌํ•œ ์›์น™์—์„œ ์ง์ ‘์ ์œผ๋กœ ํŒŒ์ƒ๋ฉ๋‹ˆ๋‹ค. C++์˜ RAII๋Š” ์Šคํƒ ๊ฐ์ฒด๋กœ ์†Œ์œ ๊ถŒ์„ ์ด์ „ํ•˜๊ณ , ํ•ด๋‹น ์Šคํƒ ๊ฐ์ฒด์˜ ์†Œ๋ฉธ์ž๊ฐ€ ์ž๋™์œผ๋กœ ์ •๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. try-with-resources ์ž๋ฐ”์—์„œ ๊ทธ๋ฆฌ๊ณ  with ํŒŒ์ด์ฌ์˜ `--` ๊ตฌ๋ฌธ์€ ๋ฆฌ์†Œ์Šค ์†Œ์œ ๊ถŒ์˜ ๋ฒ”์œ„๋ฅผ ๊ตฌ๋ฌธ์ ์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. C++์˜ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋Š” ์†Œ์œ ๊ถŒ์„ ์–‘๋„ ๋ฐ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉฐ, ๋งˆ์ง€๋ง‰ ์†Œ์œ ์ž๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ์ •๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ์—์„œ์˜ ๋“ฑ๋ก ํ•ด์ œ๋Š” ๋ฆฌ์Šค๋„ˆ์™€ ํผ๋ธ”๋ฆฌ์…” ๊ฐ„์˜ ๊ด€๊ณ„ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๋ช…์‹œ์ ์ด๊ณ  ์ œํ•œ์ ์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŒจํ„ด๋“ค์€ ๋ชจ๋‘ ๋ณธ์งˆ์ ์œผ๋กœ ์†Œ์œ ๊ถŒ์„ ๊ฐ€์‹œํ™”ํ•˜๊ณ  ์ž๋™ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ์‹œํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋ช…ํ™•ํ•œ ์†Œ์œ ๊ถŒ์˜ ํšจ์šฉ์€ ๋ช…ํ™•ํ•œ ํ…Œ์ŠคํŠธ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ๋ฐ˜ํ™˜ ๊ฐ’๋งŒ ํ™•์ธํ•˜๋Š” ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ์—์„œ๋Š” ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ๋ฆฌ์†Œ์Šค ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์—ฐ๊ฒฐ์ด ๋‹ซํ˜”๋Š”์ง€, ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ œ๊ฑฐ๋˜์—ˆ๋Š”์ง€, ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜๊ฐ€ ์ดˆ๊ธฐํ™”๋˜์—ˆ๋Š”์ง€, ๋ฒ„ํผ๊ฐ€ ํ•ด์ œ๋˜์—ˆ๋Š”์ง€ ๋“ฑ์„ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์–ด์„ค์…˜์„ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์— ์ถ”๊ฐ€ํ•˜๊ณ , CI(์ง€์†์  ํ†ตํ•ฉ)์˜ ์ผํ™˜์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ, ์Šคํ…Œ์ด์ง• ํ™˜๊ฒฝ์—์„œ ํž™ ํฌ๊ธฐ๊ฐ€ ์ง€์†์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๊ฐ€ ์•„๋‹Œ ๋นŒ๋“œ ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ๋ฌธ์ œ๋กœ ์ด์–ด์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ์šด์˜ ์Šต๊ด€์ž…๋‹ˆ๋‹ค.

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