๋ฉ๋ชจ๋ฆฌ ๋์๋ ์ํํธ์จ์ด ์์ง๋์ด๋ง์์ ๊ฐ์ฅ ์ฌ๊ฐํ ๊ฒฐํจ ์ค ํ๋์ ๋๋ค. ์คํ์ ์ฆ์ ์ค๋จ์ํค๋ ํฌ๋์์ ๋ฌ๋ฆฌ, ๋ฉ๋ชจ๋ฆฌ ๋์๋ ์์คํ ์ ์ ์ง์ ์ผ๋ก ์ ํ์์ผ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ชจํฉ๋๋ค. ๊ฒฐ๊ตญ ์๋ต ์๋๊ฐ ๋๋ ค์ง๊ฑฐ๋, ์๋น์ค๊ฐ ์๊ธฐ์น ์๊ฒ ์ฌ์์๋๊ฑฐ๋, ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ์ค๋ฅ๋ก ์ข ๋ฃ๋ ๋๊น์ง ์ด๋ฌํ ํ์์ด ์ง์๋ฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋์๋ ๋ชจ๋ ์ฃผ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ๋ฐ์ํฉ๋๋ค. ํ ๊ด๋ฆฌ๊ฐ ์ ์ ์ผ๋ก ์๋์ผ๋ก ์ด๋ฃจ์ด์ง๋ 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๋ง์ฝ ์๋ชป๋ ๊ฒฝ์ฐ ์๋ ํฌ์ธํฐ๋ฅผ ๋ฒ๋ฆฝ๋๋ค.reallocnull์ ๋ฐํํ๋ฉด ์๋ ํ ๋น๋ ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์๊ฒ ๋ฉ๋๋ค.
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 | ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ฌ | ๋ผ์ธ๋ณ ๋ฉ๋ชจ๋ฆฌ ์ธก์ |
| JavaScript | Chrome DevTools | ํ ์ค๋ ์ท, ํ ๋น ํ์๋ผ์ธ, ์ ์ง ํฌ๊ธฐ |
| C # / .NET | ๋ํธ๋ฉ๋ชจ๋ฆฌ | ๊ฐ์ฒด ์ ์ง, ๊ฐ๋น์ง ์ปฌ๋ ์ ๋ถ์ |
| C # / .NET | ์ฑ๋ฅ ๋ณด๊ธฐ | GC ์ด๋ฒคํธ, ํ ๋น ์คํ, ๋ฉ๋ชจ๋ฆฌ ์๋ ฅ |
| ์ ์ฒด / ์ ์ | ๋ด๋ ๋ฆญ, ๋ฐ์ดํฐ๋ , ๋ค์ด๋ํธ๋ ์ด์ค | ์ง์์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง, ์ด์ ํ์ง |
๋ฉ๋ชจ๋ฆฌ ๋์ ์ฐพ๋ ๋ฐฉ๋ฒ: ๋จ๊ณ๋ณ ์ ๊ทผ ๋ฐฉ์
1๋จ๊ณ: ๋์ถ ์ฌ๋ถ๋ฅผ ํ์ธํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ๋ถํ ์กฐ๊ฑด์์ ์ ํ๋ฆฌ์ผ์ด์
์ ์คํํ๊ณ ์์คํ
๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ๋ชจ๋ํฐ๋งํ์ญ์์ค.top, htop(์์
๊ด๋ฆฌ์ ๋๋ ๋ชจ๋ํฐ๋ง ๋์๋ณด๋๋ฅผ ํตํด ํ์ธํ ์ ์์ต๋๋ค.) ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์์ ํ๋์ง ์๊ณ ์ง์์ ์ผ๋ก ์ฆ๊ฐํ๋ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
2๋จ๊ณ: ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๋ ์ฝ๋ ๊ฒฝ๋ก๋ฅผ ๊ฒฉ๋ฆฌํฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฆ๊ฐ์ ๊ด๋ จ๋ ์์ ์ ์๋ณํฉ๋๋ค. ํน์ ์ํฌํ๋ก(๋ก๊ทธ์ธ, ํ์ผ ์ ๋ก๋, ๊ฒ์ ์ฟผ๋ฆฌ ๋ฑ)๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ์คํํ๊ณ ๊ฐ ์คํ๋ง๋ค ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฆ๊ฐํ๋์ง ๊ด์ฐฐํ๋ฉด ํด๋น ์ํฌํ๋ก๊ฐ ๋ฌธ์ ์ ์์ธ์์ ์ ์ ์์ต๋๋ค.
3๋จ๊ณ: ์์ฌ์ค๋ฌ์ด ์ํฌํ๋ก๋ฅผ ์ฌ๋ฌ ๋ฒ ๋ฐ๋ณต ์คํํ ํ ํ๋กํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ค๋ ์ท์ ์์ฑํฉ๋๋ค. ์์ฑ๋ ์ค๋ ์ท๋ค์ ๋น๊ตํ์ฌ ์ด๋ค ๊ฐ์ฒด๊ฐ ๋์ ๋๋์ง ํ์ธํฉ๋๋ค.
4๋จ๊ณ: ์ฐธ์กฐ ์ฒด์ธ์ ์ถ์ ํฉ๋๋ค. ๋๋ถ๋ถ์ ํ๋กํ์ผ๋ง ๋๊ตฌ๋ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ์๋ ์ด์ ์ ํด๋น ๊ฐ์ฒด๋ฅผ ์ ์งํ๋ ๋ฃจํธ ์ฐธ์กฐ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ ์ง ํธ๋ฆฌ๋ฅผ ํ์ํฉ๋๋ค. ์ด ์ฒด์ธ์ ๋ฐ๋ผ๊ฐ๋ฉด ์ ์ง ์ฐธ์กฐ๋ฅผ ์์ฑํ ์ฝ๋๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
5๋จ๊ณ: ์์ ๋ฐ ๊ฒ์ฆ. ์์ฌ๋๋ ์์ธ์ ์์ ํ ํ ์ค๋ ์ท ๋น๊ต๋ฅผ ๋ค์ ์ํํฉ๋๋ค. ๊ฐ ์ํฌํ๋ก ๋ฐ๋ณต ํ ๊ฐ์ฒด ์๊ฐ ๋ ์ด์ ์ฆ๊ฐํ์ง ์๋์ง ํ์ธํฉ๋๋ค.
์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๋ชจ๋ํฐ๋ง: ๋๋ฆฐ ๋ฉ๋ชจ๋ฆฌ ๋์ ๊ฐ์ง
์๊ฐ๋น ๋ช ํฌ๋ก๋ฐ์ดํธ ์ ๋์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋์ถ๋๋ ๋๋ฆฐ ๋์๋ ์งง์ ํ ์คํธ ์คํ์์๋ ๋ํ๋์ง ์์ต๋๋ค. ์ด๋ฌํ ๋์๋ฅผ ๊ฐ์งํ๋ ค๋ฉด ์ฅ๊ธฐ๊ฐ ๊ด์ฐฐ์ด ํ์ํฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ ๊ธฐ์ ์ผ๋ก ์ถ์ ํ๊ณ ์ฌ์ฉ๋์ด ๊ธฐ์ค์น๋ฅผ ์ด๊ณผํ๊ฑฐ๋ ์ ์๋ ์ฆ๊ฐ์จ์ ๋์ด์๋ฉด ์๋ฆผ์ ๋ณด๋ด๋๋ก ๋ชจ๋ํฐ๋ง ์์คํ ์ ๊ตฌ์ฑํ์ญ์์ค. ์ค์ ์ด์ ํ๊ฒฝ์์๋ Datadog, New Relic, Dynatrace์ ๊ฐ์ APM ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ง์์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง, ์๋ฆผ ๋ฐ ์ด๋ ฅ ๋น๊ต ๊ธฐ๋ฅ์ ํ์ฉํ ์ ์์ต๋๋ค.
๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ
๊ตฌ์กฐํ๋ ์์ ๊ด๋ฆฌ๋ฅผ ํ์ฉํ์ธ์
๋ชจ๋ ์ธ์ด๋ ๋ฆฌ์์ค ์ ๋ฆฌ๋ฅผ ๋ณด์ฅํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ์ผ๊ด๋๊ฒ ์ฌ์ฉํ์ธ์.
- C ++ : RAII๋ ์์ฑ์์์ ํ๋ํ๊ณ ์๋ฉธ์์์ ํด์ ํฉ๋๋ค. ์ฌ์ฉ
std::unique_ptrstd::shared_ptrํ ๋ฉ๋ชจ๋ฆฌ์ฉ๊ณผ ํ์ผ ํธ๋ค ๋ฐ ์์ผ์ฉ ์ฌ์ฉ์ ์ง์ RAII ๋ํผ๊ฐ ์์ต๋๋ค. - ์๋ฐ :
try-with-resources์ ํตํAutoCloseable์์. - ํ์ด์ฌ :
withํ์ผ, ์ ๊ธ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๋ํ ์ปจํ ์คํธ ๊ด๋ฆฌ์(๋ฌธ์)์ ๋๋ค. - ์จ#:
using์ ๋ํ ์ง์IDisposable์ฌ๋ฌผ. - ์๋ฐ ์คํฌ๋ฆฝํธ : ๋ช
์์ ์ ๋ฆฌ ํจ์,
WeakRefFinalizationRegistry์บ์์ฉ์ ๋๋ค.
๋ฆฌ์ค๋ ๋ฐ ์ฝ๋ฐฑ ๋ฑ๋ก ํด์
๋ชจ๋ ๋ฑ๋ก์๋ ๋ฑ๋ก ํด์ ๊ฐ ์๋ฐ๋์ด์ผ ํฉ๋๋ค. ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ํ๋ ์์ํฌ(React, Android, Angular, Qt)์์๋ ์ปดํฌ๋ํธ์ teardown ๋ผ์ดํ์ฌ์ดํด ๋ฉ์๋์์ ๋ฑ๋ก ํด์ ๋ฅผ ์ํํ์ธ์. useEffect React์์์ ์ ๋ฆฌ ์์
onDestroy ์๋๋ก์ด๋์์, ngOnDestroy Angular์์ ์๋ฉธ์ ๋๋ disconnectedCallback ์น ๊ตฌ์ฑ ์์์์.
์ํ ์ฐธ์กฐ ๋๊ธฐ
๋ ๊ฐ์ฒด๊ฐ ์๋ก๋ฅผ ์ฐธ์กฐํด์ผ ํ ๋๋ ๋จ๋ฐฉํฅ์ผ๋ก ์ฝํ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ์ธ์. ๋๋ถ๋ถ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ์ด๋ฅผ ์ง์ํฉ๋๋ค.
- ํ์ด์ฌ :
weakref.ref()orweakref.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-memrayorpytest-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(์ง์์ ํตํฉ)์ ์ผํ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ฌ๋ฅผ ์คํํ๋ฉฐ, ์คํ ์ด์ง ํ๊ฒฝ์์ ํ ํฌ๊ธฐ๊ฐ ์ง์์ ์ผ๋ก ์ฆ๊ฐํ๋ ๊ฒ์ ์๋ ค์ง ๋ฌธ์ ๊ฐ ์๋ ๋น๋ ์คํจ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ํ๋ก๋์ ํ๊ฒฝ์์ ๋ฌธ์ ๋ก ์ด์ด์ง๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋๋ ์ด์ ์ต๊ด์ ๋๋ค.
๋ฉ๋ชจ๋ฆฌ๋ ์ ํํฉ๋๋ค. ํ ๋น๋์์ง๋ง ํด์ ๋์ง ์์ ๋ชจ๋ ๋ฐ์ดํธ๋ ์์คํ ์ ๋๋จธ์ง ๋ถ๋ถ์์ ์ฌ์ฉํ ์ ์๋ ๋ฐ์ดํธ์ ๋๋ค. ์๋ฐฑ๋ง ๊ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์๋ฒ, ๋ช ์๊ฐ ๋์ ์คํ๋๋ ๊ฒ์, ์ฌ์์ ๋ฉ์ปค๋์ฆ์ด ์๋ ์๋ฒ ๋๋ ์ฅ์น์์๋ ์ด๋ฌํ ์ ์ฝ ์กฐ๊ฑด์ด ์ด๋ก ์ ์ธ ๊ฒ์ด ์๋๋๋ค. ์ ํ์ฑ๊ณผ ๋ณด์์ ์ ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํ ์์ค์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์์ ๊ถ์ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์์คํ ์ ์ด๊ธฐ ๋ฐฐํฌ ํ ์ค๋ ์๊ฐ ๋์, ๊ทธ๋ฆฌ๊ณ ์ต์ด ํ ๋น ์ฝ๋๋ฅผ ์์ฑํ ๊ฐ๋ฐ์๊ฐ ๋ค๋ฅธ ์ ๋ฌด๋ก ์ด๋ํ ํ์๋ ์์ ์ ์ผ๋ก ์ ์งํ๋ ๋น๊ฒฐ์ ๋๋ค.


