** ๐ 2-1๋จ๊ณ: Ajax ๊ด๋ จ ๋ฉ๋ชจ๋ฆฌ ๋์ ์์ธ ์์ ์ ๋ณต **
๐ฃ ์ค๋ฌด์์ ์์คํ ์ ์ ์ ๋๋ฆฌ๊ฒ ๋ง๋๋ ์จ๊ฒจ์ง ๋ฌด์์ด ๋ฌธ์ : ๋ฉ๋ชจ๋ฆฌ ๋์
๐ง ๋ฉ๋ชจ๋ฆฌ ๋์๋? ์ฝ๊ฒ ๋งํด์โฆ
โ๋ ์ด์ ํ์ํ์ง ์์ ๋ฐ์ดํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์์ ๊ณ์ ๊ณต๊ฐ๋ง ์ฐจ์งํ๋ ๊ฒโ
๐ฆ ๋น์ ํ์๋ฉด:
๋์ฅ๊ณ ์์ ๋ค ๋จน์ ์์์ธ๋ฐ ์น์ฐ์ง ์๊ณ ๊ณ์ ์์๋๋ ๊ฒ์ด์์.
โ ๊ฒฐ๊ณผ์ ์ผ๋ก ๋์ฅ๊ณ ๊ฐ ๊ฝ ์ฐจ์ ์๋ก์ด ๊ฑธ ๋ฃ์ ์ ์๊ฒ ๋จ
โ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ฉ๋ชจ๋ฆฌ๋ ๋๊ฐ ์น์ธ๊น?
- ๋ธ๋ผ์ฐ์ ๊ฐ ์๋์ผ๋ก ์ ๋ฆฌํด์ค์ โ ์ด๊ฑธ GC(Garbage Collector)๋ผ๊ณ ํด์
- GC๋ ์ฌ์ฉํ์ง ์๋ ๊ฐ์ ์ง์ฐ๋๋ฐ, ๋์๊ฐ ์๊ธฐ๋ฉด GC๊ฐ ์ง์ฐ์ง ๋ชปํจ
โ
1. append()
, innerHTML
๋จ๋ฐ ์ DOM ๋์
โ ์๋ชป๋ ์์
setInterval(() => {
document.body.innerHTML += "<p>์ถ๊ฐ๋จ</p>";
}, 1000);
๐ด ๊ฒฐ๊ณผ:
<p>
๊ฐ 1์ด๋ง๋ค ๊ณ์ ์ถ๊ฐ๋จ โ DOM Tree๊ฐ ๊ณ์ ์ปค์ง- ๋ธ๋ผ์ฐ์ ๋ ํ๋ฉด๋ ๊ทธ๋ ค์ผ ํ๊ณ , ๋ฉ๋ชจ๋ฆฌ์๋ ๊ณ์ ๋จ๊ฒจ๋ฌ์ผ ํด์ ์ ์ ๋๋ ค์ง
๐ ์์ธ
- innerHTML์ ๊ธฐ์กด DOM์ ์ญ์ ํ ์๋ก ๋ง๋๋๋ฐ,
- ๊ธฐ์กด DOM์ด ์ด๋ฒคํธ๋ ํด๋ก์ ๋ฑ์ผ๋ก ์ด๋๊ฐ์์ ์ฐธ์กฐ ์ค์ด๋ฉด GC๊ฐ ์ง์ฐ์ง ๋ชปํจ
โ ํด๊ฒฐ ๋ฐฉ๋ฒ
let div = document.createElement("div");
div.textContent = "์ถ๊ฐ๋จ";
document.body.appendChild(div);
- DOM ์กฐ์์ ์ง์ node ๋จ์๋ก, ๋ฐ๋ณต ์์๋
DocumentFragment
๋ฅผ ์จ์ผ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ์ ์ต๋๋ค.
โ 2. ์ฝ๋ฐฑ / ํด๋ก์ ์ ์ํ ๋ฉ๋ชจ๋ฆฌ ๋์
๐ ์ฝ๋ฐฑ/ํด๋ก์ ๋?
function outer() {
let bigData = new Array(1000000).fill("๐ฃ"); // ์์ฒญ ํฐ ๋ฐฐ์ด
return function inner() {
console.log(bigData[0]);
};
}
bigData
๋ ํจ์ ์์ ์์ด์ ๋ฐ์์ ์ ๋ณด์ด์ง๋ง,inner
ํจ์๊ฐ ๊ณ์bigData
๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ GC๊ฐ ๋ชป ์ง์
๐ ํด๋ก์ (Closure)๋ โ๋ด๋ถ ํจ์๊ฐ ์ธ๋ถ ๋ณ์๋ฅผ ๊ธฐ์ตํ๋ ๊ฒโ์ด์์
โ ์ค๋ฌด์์ ์ด๋ฐ ์์ผ๋ก ๋ฐ์ํจ
$("#btn").click(function() {
let bigArray = [...]; // ์์ฃผ ํฐ ๋ฐ์ดํฐ
$.ajax({
url: "...",
success: function() {
console.log(bigArray[0]); // ๋ถํ์ํ ์ฐธ์กฐ
}
});
});
โ Ajax ์ฝ๋ฐฑ ํจ์์์ ํฐ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ๊ณ ์์ด์ GC๊ฐ ์ ๊ฑฐ ๋ชปํจ
โ ํด๊ฒฐ๋ฒ
- ์ฝ๋ฐฑ ๋ด๋ถ์์ ๋ถํ์ํ ์ธ๋ถ ๋ณ์ ์ฐธ์กฐ๋ฅผ ํผํ๊ธฐ
- ์ฝ๋ฐฑ ์ข ๋ฃ ํ์๋ null ์ฒ๋ฆฌ ๋๋ ์ญ์
WeakMap
,WeakRef
๋ฑ์ผ๋ก GC ๋์ ์ง์ ๊ฐ๋ฅ
โ 3. ํ์ด๋จธ(setInterval, setTimeout) ๋ฏธ์ ๋ฆฌ
โ ๋์ ์์
setInterval(() => {
console.log("๊ณ์ ์คํ");
}, 1000);
// ์ด๊ฑธ clearInterval ํ์ง ์์ผ๋ฉด โ ๊ณ์ ์ด์ ์์
- ํ์ด์ง ์ ํํด๋ ๊ณ์ ์คํ๋จ
- ํนํ DOM์ ์ฐธ์กฐํ๊ณ ์์ผ๋ฉด โ GC๊ฐ DOM๋ ๋ชป ์ง์!
โ ํด๊ฒฐ๋ฒ
let timer = setInterval(...);
clearInterval(timer); // โ
๊ผญ ์ ๋ฆฌํ๊ธฐ
- Ajax๋ก ๋ง๋ DOM์ด ์์ด์ง ๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ, ํ์ด๋จธ๋ ๊ฐ์ด ์ ๊ฑฐํด์ผ ํจ
โ 4. ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋์
const div = document.createElement("div");
div.addEventListener("click", () => {
alert("ํด๋ฆญ!");
});
document.body.appendChild(div);
โ div๋ฅผ ์ญ์ ํด๋ ์ด๋ฒคํธ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ์์ผ๋ฉด GC๊ฐ ๋ชป ์ง์
โ ํด๊ฒฐ๋ฒ
div.removeEventListener("click", ํธ๋ค๋ฌ๋ช
);
โ 5. GC(Garbage Collector)์ ์๋ ์๋ฆฌ (์ด๊ฐ๋จ)
๐ Mark-and-Sweep ์๊ณ ๋ฆฌ์ฆ
- *๋๋ฌํ ์ ์๋ ๊ฐ(๋ณ์, ๊ฐ์ฒด)**๋ง ์ฐพ๋๋ค (root์์ ๋ฐ๋ผ๊ฐ๋ฉฐ)
- ๋๋จธ์ง๋ โ์ธ๋ชจ ์์โ์ด๋ผ๊ณ ํ๋จํ๊ณ ์ญ์
โ ๊ทธ๋ฐ๋ฐ Ajax ์ฝ๋ฐฑ์ด ํด๋ก์ ๋ก ๋ณ์๋ฅผ ๋ค๊ณ ์์ผ๋ฉด
โ โ์ธ๋ชจ ์๋ค๊ณ ์ฐฉ๊ฐโํด์ ๋ชป ์ง์
โ ์ค์ ์ค๋ฌด ์๋๋ฆฌ์ค ์์ฝ
๋์ ์์ธ | ์ ๋ฌธ์ ์ธ๊ฐ? | ํด๊ฒฐ๋ฒ |
---|---|---|
innerHTML | DOM์ด ๊ณ์ ์๋ก ์๊ธฐ๊ณ ๊ธฐ์กด ์ฐธ์กฐ๋ ๋จ์ | createElement , fragment ์ฌ์ฉ |
์ฝ๋ฐฑ/ํด๋ก์ | ํด๋ก์ ๊ฐ ํฐ ๋ณ์ ๋ค๊ณ ์์ | ์ฐธ์กฐ ์ ๊ฑฐ or null ์ฒ๋ฆฌ |
setInterval | ๋ฉ์ถ์ง ์๊ณ ๊ณ์ ์คํ๋จ | clearInterval ํ์ |
์ด๋ฒคํธ | ์์๋ ์ ๊ฑฐ๋ผ๋ ํธ๋ค๋ฌ๋ ๋จ์ ์์ | removeEventListener ํ์ |
โ ๋ฉด์ ์ง๋ฌธ ์์ + ํด์ค
โ Q. Ajax ์ฐ๋๋ ์น ํ์ด์ง์์ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ ์ ์๋ ๋ํ์ ์ธ ์์ธ๊ณผ ๋์ ๋ฐฉ๋ฒ์?
โ A.
innerHTML
์ฌ์ฉ ์ DOM ๊ฐ์ฒด๊ฐ ์ฐธ์กฐ๋ก ๋จ์ GC๊ฐ ํด์ ํ์ง ๋ชปํจ- ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์์ ํด๋ก์ ๋ก ์ธํด ํฐ ๊ฐ์ฒด๊ฐ ๊ณ์ ์ฐธ์กฐ๋จ
setInterval
์ด๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ Ajax๋ก ์ถ๊ฐ๋ DOM์ ์ฐ๊ฒฐ๋์ด ์ ๊ฑฐ๋์ง ์์- ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ช ์์ ์ฐธ์กฐ ํด์ , ํ์ด๋จธ/๋ฆฌ์ค๋ ์ ๋ฆฌ, DOM ์กฐ์ ์ต์ํ
โ ์์ฝ ํค์๋ ์นด๋
๊ฐ๋ | ์ค๋ช |
---|---|
๋ฉ๋ชจ๋ฆฌ ๋์ | GC๊ฐ ์ง์ฐ์ง ๋ชปํ๋ ์ธ๋ชจ์๋ ๋ฐ์ดํฐ |
innerHTML | ์๋ก ๋ง๋ค์ง๋ง ๊ธฐ์กด ์ฐธ์กฐ๋ ๋จ์ |
ํด๋ก์ | ๋ด๋ถ ํจ์๊ฐ ์ธ๋ถ ๋ณ์๋ฅผ ๊ณ์ ๊ธฐ์ต |
setInterval | ๋ฌดํ ์คํ โ ์ข ๋ฃ ์ ํ๋ฉด ๋์ |
์ด๋ฒคํธ ํธ๋ค๋ฌ | DOM ์ญ์ ์ ํจ๊ป ์ ๊ฑฐํ์ง ์์ผ๋ฉด ์ฐธ์กฐ ์ ์ง๋จ |
โ ๋ค์ ์๊ณ :
2-2๋จ๊ณ: ๋ธ๋ผ์ฐ์ GC์ ์ฐธ์กฐ ๊ด๊ณ, ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์ก์๋ด๋ DevTools Memory ํญ ์ฌ์ฉ๋ฒ์ ๋๋ค.
- Heap Snapshot
- Allocation Timeline
- Detached DOM
- ์ค์๊ฐ ๋์ ์ถ์ ๋ฒ
โ 2-2๋จ๊ณ: ๋ธ๋ผ์ฐ์ GC ๊ด์ ์์ ๋ณธ ๋ฉ๋ชจ๋ฆฌ ํ์
๐ก GC๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ์ ๋ฆฌํ๊ณ , Ajax๊ฐ ์ด๋ป๊ฒ ๊ทธ๊ฑธ ๋ฐฉํดํ๋์ง๋ฅผ ์๋ฒฝํ ์ดํดํ๋ ๋จ๊ณ
โ 1. ๋ธ๋ผ์ฐ์ ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋์ผ๋ก ์ ๋ฆฌํ๋ค
์๋ฐ์คํฌ๋ฆฝํธ๋ delete
๊ฐ์ ๊ฑธ ๊ฑฐ์ ์ ์จ๋ ๊ด์ฐฎ์์.
์๋๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ โ๋ ์ด์ ์ ์ฐ๋ ๋ฐ์ดํฐ๋ ์๋์ผ๋ก ์ญ์ โํด์ฃผ๊ธฐ ๋๋ฌธ์ด์์.
์ด๊ฑธ Garbage Collector (GC, ๊ฐ๋น์ง ์ปฌ๋ ํฐ)๋ผ๊ณ ํด์.
โ 2. GC๊ฐ ์ฐ๋ ๋ฐฉ์: Mark-and-Sweep ์๊ณ ๋ฆฌ์ฆ
๐ฆ ์ด๊ฑด ๋ง์น โ์ ์ฐ๋ ๋ฌผ๊ฑด ์ ๋ฆฌํ๊ธฐโ ๊ฐ์์
1๏ธโฃ โ์ด๊ฑฐ ์์ง ์ฐ๊ณ ์๋ ๊ฑฐ์ผ?โ ํ๊ณ ํ๋์ฉ ํ์ธํ๊ณ
2๏ธโฃ โ์๋ฌด๋ ์ ์ฐ๋ ๊ฑฐ๋ค?โ โ ์ฐ๋ ๊ธฐํต์ผ๋ก ๋ณด๋ด๊ธฐ
๐ ์๋ ์์ (์คํ์ ๋ฒ์ )
- ๋ชจ๋ ๋ณ์/๊ฐ์ฒด๋ฅผ ํ์ธํ๋ค
- ๋๊ฐ ์ฐ๊ณ ์๋์ง ํ์ํ๋ค (๐mark)
- ์๋ฌด๋ ์ ์ฐ๋ ๊ฑด ์ ๋ฆฌํ๋ค (๐งนsweep)
๐ง ์ปดํจํฐ๊ณตํ์ ์ค๋ช
๋จ๊ณ | ์ค๋ช |
---|---|
Mark | โ๋ฃจํธ(root)โ์์ ์์ํด์, ์ฐ๊ฒฐ๋ ๋ณ์/๊ฐ์ฒด๋ค์ ๋ฐ๋ผ๊ฐ๋ฉฐ ํ์ํจ |
Sweep | ํ์๋์ง ์์ ๊ฐ์ฒด๋ค์ โ๋ ์ด์ ์ ๊ทผ ๋ถ๊ฐ๋ฅโ โ ๋ฉ๋ชจ๋ฆฌ์์ ์ ๊ฑฐํจ |
โ 3. ๋ฃจํธ(Root)๋ ๋๊ตฌ์ธ๊ฐ?
GC๋ โ๊ธฐ์ค์ โ์์ ์์ํด์ ์ฐธ์กฐ๋ ์ ๋ค๋ง ๋จ๊ฒจ์.
๋ํ์ ์ธ Root๋ค
window
globalThis
- ํ์ฌ ์คํ ์ค์ธ ํจ์
- ํ์ฑ ์ด๋ฒคํธ ํธ๋ค๋ฌ
- DOM์ ์ฐ๊ฒฐ๋ ์์
โ ์ด Root์์ ์์ํด์ ๋ฐ๋ผ๊ฐ ์ ์๋ ์ ๋ค์ ์ง์์!
โ 4. ๋๋ฌ ๊ฐ๋ฅ์ฑ (reachability) ๊ฐ๋
GC ์ ์ฅ์์ โ์ด ๊ฐ์ฒด์ ๋๋ฌํ ์ ์์ด?โ โ YES๋ฉด ์ด๋ฆฌ๊ณ , NO๋ฉด ์ง์์
์์ 1: ๋๋ฌ ๊ฐ๋ฅ
let a = {name: "ํ๊ธธ๋"};
let b = a; // ๐ b๋ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํด
- a์ b ๋ชจ๋
{name: "ํ๊ธธ๋"}
๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์์ผ๋ โ GC๋ ์ด๊ฑธ ์ง์ฐ์ง ์์์
์์ 2: ๋๋ฌ ๋ถ๊ฐ๋ฅ
let a = {name: "ํ๊ธธ๋"};
a = null; // ๐ ๋ ์ด์ ์๋ฌด๋ ์ ๊ฐ๋ฆฌํด
- GC๋ โ์ด๋ผ, ์๋ฌด๋ ์ด ๊ฐ์ฒด๋ฅผ ์ ์ฐ๋ค?โ โ โ ๋๋ฌ ๋ถ๊ฐ๋ฅ โ ๋ฉ๋ชจ๋ฆฌ์์ ์ ๊ฑฐ
โ 5. Ajax ์ฝ๋ฐฑ ํจ์์ ์ฐธ์กฐ ๋ฌธ์
โ ์ด๋ฐ ์ฝ๋๊ฐ ๋ฌธ์ ์ ๋๋ค:
function loadData() {
let bigData = new Array(1000000).fill("๐ฑ");
$.ajax({
url: "/data",
success: function() {
console.log(bigData[0]); // ๐ ์์ง๋ bigData๋ฅผ ์ฐธ์กฐํ๊ณ ์์
}
});
}
- ์ด ์ฝ๋๋ฅผ ์คํํ๋ฉด
bigData
๋ Ajax ์๋ต์ ๋ฐ์ ๋๊น์ง ์ด์ ์์ด์ผ ํด์ - ๊ทธ๋ฐ๋ฐ Ajax ์๋ต์ด ๋๋ฆฌ๊ฑฐ๋ ์คํจํ๋ฉดโฆ โ
bigData๋ ์ฌ์ ํ โ๋๊ฐ ๋๋ฅผ ์ฐ๊ณ ์์ด์!โ๋ผ๊ณ ์ฐฉ๊ฐ์ํด
โ GC๋ ์ ๋ ์ด๊ฑธ ์ ๋ฆฌ ๋ชป ํจ โ โ ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์
โ 6. ํด๋ก์ ์ ์ฐธ์กฐ ์นด์ดํธ ๋ฌธ์
๐ ํด๋ก์ ๋?
function outer() {
let secret = "๋น๋ฐ";
return function inner() {
console.log(secret);
};
}
inner()
๋ ์ธ๋ถ์secret
์ ๊ธฐ์ตํ๊ณ ์์ด์ โ ์ด๊ฒ ํด๋ก์
๐ฅ ํด๋ก์ ๊ฐ ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋ ๊ฒฝ์ฐ:
- Ajax ์ฝ๋ฐฑ ์์์ ์ธ๋ถ ํฐ ๊ฐ์ฒด(
bigArray
, DOM ๋ฑ)๋ฅผ ์ฐธ์กฐํ ๊ฒฝ์ฐ - GC๋ ํด๋ก์ ์์ ์ธ๋ถ ๋ณ์๋ โ์์ง ์ฐ๋ ์คโ์ด๋ผ๊ณ ํ๋จํด์ ๋ชป ์ง์
โ 7. ์ด๋ป๊ฒ ํ๋ฉด GC๊ฐ ์ ์๋ํ๊ฒ ๋์์ค๊น?
๋ฌธ์ | ํด๊ฒฐ๋ฒ |
---|---|
ํด๋ก์ ๊ฐ ํฐ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐ | ์๋ต์ด ๋๋๋ฉด ๋ณ์ null ์ฒ๋ฆฌ |
Ajax ์์ฒญ ์คํจ ์ ์๋ต ๋๊ธฐ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ ์ ๋จ | AbortController ๋ก ์ทจ์ ์ฒ๋ฆฌ |
DOM ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ฐธ์กฐ ๋จ์ | removeEventListener() ๋ก ์ ๊ฑฐ |
setInterval์ด ๊ณ์ ์คํ | clearInterval() ๋ก ์ ๋ฆฌ |
โ 8. ๊ณ ๊ธ ๊ฐ๋ ์์ฝ (์ธํฐ๋ทฐ์ฉ ํ ์ค ์ ๋ฆฌ)
- ์๋ฐ์คํฌ๋ฆฝํธ์ GC๋ ๋๋ฌ ๊ฐ๋ฅ์ฑ ๊ธฐ๋ฐ(Reachability) Mark-and-Sweep ๋ฐฉ์์ผ๋ก ์๋ํ๋ค.
- Ajax ์ฝ๋ฐฑ ๋ด ํด๋ก์ ๋๋ DOM ์ฐธ์กฐ๊ฐ GC์ ๋๋ฌ ๊ฒฝ๋ก์ ๊ฑธ๋ฆฌ๋ฉด ๋ฉ๋ชจ๋ฆฌ ํ์๊ฐ ๋ถ๊ฐ๋ฅํด์ง๋ค.
- ์ค๋ฌด์์๋ ์ฝ๋ฐฑ ์ต์ํ, null ์ฒ๋ฆฌ, ์ด๋ฒคํธ/ํ์ด๋จธ ์ ๊ฑฐ๋ก GC ํ์๋ฅผ ์ ๋ํด์ผ ํ๋ค.
โ ๋ฉด์ ์ง๋ฌธ ์์ + ํด์ค
โ Q. Ajax๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ ์ ์๋ ์ด์ ๋ฅผ GC ๊ด์ ์์ ์ค๋ช ํ์์ค.
โ A.
- GC๋ ๋๋ฌ ๊ฐ๋ฅํ ๊ฐ์ฒด๋ง ๋จ๊ธฐ๊ณ , ๋๋ฌ ๋ถ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ์ ๋ฆฌํจ
- Ajax ์ฝ๋ฐฑ ์์์ ํด๋ก์ ๋ก ์ธ๋ถ ๋ณ์(์: ํฐ ๋ฐฐ์ด, DOM)๋ฅผ ์ฐธ์กฐํ๋ฉด ํด๋น ๊ฐ์ฒด๊ฐ ๋๋ฌ ๊ฐ๋ฅํ๋ค๊ณ ํ๋จ
- ์๋ต์ด ๋๋ฆฌ๊ฑฐ๋ ์คํจํ๋๋ผ๋ ์ด ์ฐธ์กฐ๊ฐ ๋จ์ GC๊ฐ ์ ๊ฑฐํ์ง ๋ชปํจ โ ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์
- ์ด ๋ฌธ์ ๋ฅผ ๋ง๊ธฐ ์ํด์ ์๋ต ํ ์ฐธ์กฐ ์ ๊ฑฐ, ์์ฒญ ์ทจ์, ๋ฆฌ์ค๋ ํด์ ๋ฑ์ด ํ์
โ ์์ฝ ํ ์ปท ์นด๋
๊ฐ๋ | ์ฌ์ด ์ค๋ช |
---|---|
GC | ์ ์ฐ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋์ผ๋ก ์ ๋ฆฌ |
Mark-and-Sweep | ์ฐ๋ ๊ฑด ํ์ํ๊ณ , ์ ์ฐ๋ ๊ฑด ์ง์ฐ๋ ๋ฐฉ์ |
๋๋ฌ ๊ฐ๋ฅ์ฑ | ๋ณ์/๊ฐ์ฒด์ ๋ฐ๋ผ๊ฐ ์ ์์ผ๋ฉด ์ญ์ ์ ํจ |
Ajax ์ฝ๋ฐฑ ๋์ | ์ฝ๋ฐฑ ์์ ํฐ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ๋ฉด GC๊ฐ ์ญ์ ๋ชป ํจ |
ํด๊ฒฐ | null ์ฒ๋ฆฌ, AbortController, ๋ฆฌ์ค๋ ํด์ ๋ฑ |
โ ๋ค์ ์๊ณ :
2-3๋จ๊ณ: ์ค๋ฌด ๋ฉ๋ชจ๋ฆฌ ๋์ ์์ ๋ถ์ + Chrome DevTools ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง ์ค์ต
- Heap Snapshot ๋ณด๋ ๋ฒ
- Detached DOM ์ฐพ๋ ๋ฒ
- ์ค์๊ฐ ๋์ ํ์ง & ๋ฉ๋ชจ๋ฆฌ ๊ทธ๋ํ ํด์๋ฒ
โ 2-3๋จ๊ณ: ์ค๋ฌด ๋ฉ๋ชจ๋ฆฌ ๋์ ์์ ๋ถ์ + Chrome DevTools ๋ฉ๋ชจ๋ฆฌ ๋ถ์๋ฒ
๐ฅ Ajax ์์ฒญ์ ๋ง์ด ๋ณด๋ด๋ฉด ์ ๋ธ๋ผ์ฐ์ ๊ฐ ๋๋ ค์ง๊น?
๐จ๐ปโ๐ซ ๊ทธ๊ฑธ ์ฐพ์๋ด๋ ์ค๋ฌด ๋๋ฒ๊น ์คํฌ์ ๋ง์คํฐํ๋ ๋จ๊ณ์ ๋๋ค.
โ 1. ์ํฉ ์๋๋ฆฌ์ค: โUI๊ฐ ์ ์ ๋๋ ค์ ธ์โ
๐จ๐ปโ๐ป ๋ฌธ์ ์ค๋ช
for (let i = 0; i < 1000; i++) {
$.ajax({
url: "some_api.jsp",
success: function(data) {
const div = document.createElement("div");
div.innerHTML = data;
document.body.appendChild(div);
}
});
}
๐ฅ ์ ์ฝ๋๋ฅผ ์คํํ๋ฉดโฆ
- ์์ฒญ์ 1000๋ฒ ๋ณด๋
- ์๋ต ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์ 1000๊ฐ ๋ถ์
- ๐ ๋ช ์ด ์ง๋๋ฉด ๋ฒ๋ฒ ๊ฑฐ๋ฆผ, ๋ , ํด๋ฆญ ๋ฐ์ ์ ํ
โ 2. ์ ๊ทธ๋ด๊น? ๋ฉ๋ชจ๋ฆฌ ๋์์ ํํ ์์ธ๋ค
์์ธ | ์ค๋ช |
---|---|
๐ DOM์ด ๊ณ์ ์ถ๊ฐ๋จ | appendChild() ๋ก ๊ณ์ ํ๋ฉด ์์๊ฐ ์์ |
๐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๊ฐ์ด ์๊น | ์๋ต HTML์ onclick , onchange ๊ฐ ๋ค์ด ์์ผ๋ฉด ์ฐธ์กฐ๋ ๊ฐ์ด ์์ |
๐ Ajax ์ฝ๋ฐฑ ์์์ ํด๋ก์ ๋ก ์ธ๋ถ ๋ณ์ ์ฌ์ฉ | GC๊ฐ ํด๋น ์ฝ๋ฐฑ์ ํด์ ํ์ง ๋ชปํจ |
๐ ์๋ต์ ์บ์ฑ ์์ด ๊ณ์ ์์ | ์๋ต ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง์ง ์์ |
โ 3. ์ฆ์ ์ ๋ฆฌ
์ฆ์ | ์ค๋ช |
---|---|
CPU ์ฌ์ฉ๋ ์ฆ๊ฐ | ๊ณ์ DOM ์ถ๊ฐ โ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ ๋๋ง์ ๊ณผ๋ถํ |
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ง์ ์ฆ๊ฐ | GC๊ฐ ํด์ ๋ชปํ๋ ๊ฐ์ฒด๊ฐ ๋จ์ |
UI ๋ฐ์ ์ ํ | ์ด๋ฒคํธ/DOM์ด ๋ง์์ง์๋ก ํด๋ฆญ ๋ฐ์, ๋ ๋๋ง ์๋ ์ ํ |
โ 4. ํด๊ฒฐ์? ๋จผ์ โ์ด๋๊ฐ ๋ฌธ์ ์ธ์ง ์ฐพ์์ผโ ํฉ๋๋ค
๊ทธ๋ด ๋ ์ฐ๋ ๋๊ตฌ๊ฐ ๋ฐ๋ก ๐ Chrome DevTools์ Memory ํญ
โ 5. Chrome DevTools - Memory ํญ ์ฌ์ฉ๋ฒ (์คํ์๋ ์ดํด ๊ฐ๋ฅ)
๐ ์ฌ์ฉ ๋ฐฉ๋ฒ ์์ฝ
- F12 ๋๋ฅด๊ธฐ (๊ฐ๋ฐ์ ๋๊ตฌ ์ด๊ธฐ)
- ์๋จ ํญ์์ Memory ์ ํ
- ์ข์ธก์์
Heap snapshot
์ ํ ํ โ ๐ธTake snapshot
ํด๋ฆญ
๐งช ๊ฒฐ๊ณผ ํด์ ํฌ์ธํธ
์ฉ์ด | ๋ป | ์ฝ๊ฒ ๋งํ๋ฉด |
---|---|---|
JS Heap | ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ์ฌ์ฉํ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ | ๋ด ์์ ๊ณต๊ฐ |
Detached DOM Tree | ๋ ์ด์ ํ๋ฉด์ ์์ง๋ง, ๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ์์ | โ์ญ์ ๋ ์ค ์์๋๋ฐ ์์ง ์ด์์๋ ํ๊ทธโ |
Object Count | ํน์ ๊ฐ์ฒด์ ๊ฐ์ | ์: <div> ๊ฐ 1000๊ฐ์ฉ ์์ |
Retainers | ์ด ๊ฐ์ฒด๋ฅผ ๋๊ฐ ๋ถ์ก๊ณ ์๋๊ฐ | ํด๋ก์ , ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ ์ฐธ์กฐ ์ถ์ |
๐ฅ ์ค๋ฌด ๋์ ์์ ์ฐพ์๋ด๊ธฐ
- Snapshot์ ํ๋ ์ฐ๋๋ค (์์ ์ )
- ๋์ ๋๋ Ajax ์คํ (
for
๋ฌธ ๋ฑ์ผ๋ก 1000๋ฒ) - ๋ค์ Snapshot ์ฐ๊ธฐ
- ๐ ๋ณํ ๋น๊ต
โ Detached DOM
์ด ๋ง๊ณ ์ค์ง ์์ผ๋ฉด ๋์
โ Array
, Function
, Object
์๊ฐ ๊ณ์ ์ฆ๊ฐํ๋ฉด ์ฐธ์กฐ ๋์
โ 6. ์ค๋ฌด ๋๋ฒ๊น ๊ฟํ
๐ก ์์ฃผ ๋ณด๋ ๋์ ํญ๋ชฉ๋ค
ํญ๋ชฉ | ํด์ |
---|---|
Detached DOM Tree |
Ajax๋ก ๋ง๋ ์์๊ฐ ์ฌ๋ผ์ง์ง ์์ |
Array(1000) |
ํฐ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ๋ฐฐ์ด์ด ์ฐธ์กฐ๋ก ์ด์ ์์ |
Closure |
์ฝ๋ฐฑ ๋ด๋ถ์์ ์ธ๋ถ ๋ณ์๋ฅผ ๊ธฐ์ต ์ค |
Timer |
setInterval() ์ด clear๋์ง ์์ |
Listener |
์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ ๊ฑฐ๋์ง ์์ |
โ 7. ๋์๋ฅผ ์๋ฐฉํ๋ ์ค์ ํจํด
โ๏ธ ์ ๋ฆฌ ๋ฃจํด
const handler = function() {
// ์ด๋ฒคํธ ๋์
};
element.addEventListener("click", handler);
// ๋์ค์ ์ ๊ฑฐ
element.removeEventListener("click", handler);
โ๏ธ ์๋ต ์ดํ ์ฐธ์กฐ ์ ๊ฑฐ
let bigArray = [...];
$.ajax({
url: "some.jsp",
success: function() {
// ์์
ํ ์ฐธ์กฐ ์ ๊ฑฐ
bigArray = null;
}
});
โ 8. ์์ฝ ์ ๋ฆฌ
ํญ๋ชฉ | ์ค๋ช |
---|---|
๋ฉ๋ชจ๋ฆฌ ๋์ | GC๊ฐ ์ ๊ฑฐํ์ง ๋ชปํ ๋ฉ๋ชจ๋ฆฌ ์ฐ๊บผ๊ธฐ |
Ajax ๋์ ์์ธ | DOM ์ถ๊ฐ, ํด๋ก์ ์ฐธ์กฐ, ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ฐฉ์น |
ํด๊ฒฐ | ์ฐธ์กฐ ์ ๊ฑฐ, ์ด๋ฒคํธ ํด์ , innerHTML ๋์ createElement ์ฌ์ฉ |
DevTools Memory ํญ | ๋์ ์ถ์ ์ ์ต์ ํ๋ ๋ถ์ ๋๊ตฌ |
Snapshot ๋น๊ต | ๋ฉ๋ชจ๋ฆฌ ์ฆ๊ฐ ์ถ์ด ํ์ธ ๊ฐ๋ฅ |
Detached DOM | ํ๋ฉด์ ์๋๋ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ์์ โ ๋์ ๋ํ ์ฃผ์ |
โ ๋ฉด์ ์ง๋ฌธ ์์
โ Q. 1000๊ฐ์ Ajax ์์ฒญ ์ดํ ๋ธ๋ผ์ฐ์ UI๊ฐ ๋๋ ค์ก์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋ถ์์ ํตํด ์ด๋ค ๋ฌธ์ ๋ฅผ ํ์ธํ ์ ์๋์?
โ A.
Memory โ Heap snapshot
์ ํตํด DOM Tree, Object ์ ์ฆ๊ฐ ํ์ธDetached DOM
์ด ๋ง์ผ๋ฉด GC๊ฐ ํด์ ํ์ง ๋ชปํ DOM์ด ๋จ์ ์๋ ๊ฒ- Ajax ์๋ต ์ฒ๋ฆฌ ํ ์ด๋ฒคํธ ํด์ , ์ฐธ์กฐ ์ ๊ฑฐ ๋ฑ์ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ ๋ฃจํด ํ์