νλμ μΈ νλ‘κ·Έλλ° νκ²½μμ λ©λͺ¨λ¦¬ λμ(Memory Leak)λ μ¬μ ν μ ν리μΌμ΄μ μ μ±λ₯ μ νμ μΆ©λμ μΌμΌν€λ μ£Όμ μμΈ μ€ νλμ λλ€. λ©λͺ¨λ¦¬ λμλ₯Ό νλ§λλ‘ μ μνλ©΄, βλ μ΄μ νμνμ§ μμ λ°μ΄ν°κ° λ©λͺ¨λ¦¬μμ ν΄μ λμ§ μκ³ λ¨μ μλ νμβμ λλ€.
μ»΄ν¨ν°μ λ©λͺ¨λ¦¬(RAM)λ νλ‘κ·Έλ¨μ΄ μ€νλλ λμ λ°μ΄ν°λ₯Ό μμλ‘ μ μ₯νλ μμ 곡κ°μ λλ€. μ΄ μμ 곡κ°μ νμ λμ΄ μμ΅λλ€.
π λ₯νκ²: λ©λͺ¨λ¦¬ λμλ κ°λ°μκ° λͺ μμ μΌλ‘ λ©λͺ¨λ¦¬λ₯Ό ν΄μ ν΄μΌ νλ μΈμ΄(C, C++)μμ ννμ§λ§, κ°λΉμ§ 컬λ ν°(Garbage Collector, GC)κ° μλ μΈμ΄(Java, JavaScript, Python λ±)μμλ GCκ° βμ΄ λ°μ΄ν°λ μ¬μ ν νμνλ€βκ³ μ€ν΄νκ² λ§λ€ λ λ°μν©λλ€.
JavaScript κ°μ κ³ κΈ μΈμ΄μμλ κ°λ°μκ° λ©λͺ¨λ¦¬ ν΄μ μ λν΄ μ κ²½ μΈ νμκ° μλλ‘ κ°λΉμ§ 컬λ ν°(GC)λΌλ μλ λ©λͺ¨λ¦¬ κ΄λ¦¬ λκ΅¬κ° μλν©λλ€.
JavaScript μμ§(μ: V8 μμ§)μ Mark-and-Sweep λ±μ μκ³ λ¦¬μ¦μ μ¬μ©νμ¬ GCλ₯Ό μνν©λλ€. λ€μμ μ΄ GCλ₯Ό λ°©ν΄νλ λνμ μΈ ν¨ν΄μ λλ€.
μλμΉ μκ² λ³μλ₯Ό μ μ μ€μ½νμ μ μΈνκ±°λ, varλ let/const μμ΄ λ³μλ₯Ό μ¬μ©ν λ λ°μν©λλ€. μ μ κ°μ²΄(λΈλΌμ°μ μμλ window κ°μ²΄)μ ν λ² λ±λ‘λ λ³μλ νλ‘κ·Έλ¨μ΄ λλ λκΉμ§ GCμ λμμ΄ λμ§ μμΌλ―λ‘, ν° κ°μ²΄λ₯Ό μ¬κΈ°μ μ μ₯νλ©΄ λμκ° λ°μν©λλ€.
JavaScript
function createGlobalLeak() {
// let, const, var ν€μλ μμ΄ μ μΈνλ©΄ μ μ κ°μ²΄(window)μ μμ±μ΄ λ©λλ€.
// μ΄λ μλμΉ μκ² μ μ κ°μ²΄λ₯Ό μ€μΌμν€κ³ λ©λͺ¨λ¦¬μμ ν΄μ λμ§ μκ² ν©λλ€.
leakyData = new Array(1000000).fill('leak');
}
// leakyDataλ ν¨μκ° μ’
λ£λ νμλ window.leakyDataλ‘ κ³μ μ°Έμ‘°λ©λλ€.
DOM μμμ μ΄λ²€νΈ 리μ€λλ₯Ό μΆκ°νμ§λ§, λμ€μ κ·Έ DOM μμ μ체λ₯Ό μ κ±°ν λ 리μ€λλ₯Ό ν΄μ νμ§ μμ λ°μν©λλ€.
window κ°μ²΄μ κ°μ μμ κ°μ²΄μ μν΄ μ°Έμ‘°λ μ μμ΅λλ€.removeEventListenerλ₯Ό μ¬μ©νμ¬ λ¦¬μ€λλ₯Ό λͺ
μμ μΌλ‘ μ κ±°ν΄μΌ ν©λλ€.JavaScript
const button = document.getElementById('myButton');
const dataStore = {}; // ν° λ°μ΄ν°κ° μλ€κ³ κ°μ
button.addEventListener('click', function onClick() {
// μ΄ μ½λ°± ν¨μλ dataStore κ°μ²΄λ₯Ό μ°Έμ‘°νκ³ μμ΅λλ€.
console.log(dataStore.value);
});
// λ§μ½ λμ€μ button μμλ₯Ό DOMμμ μ κ±°ν΄λ, onClick ν¨μμ
// κ·Έ ν¨μκ° μ°Έμ‘°νλ dataStoreλ μ¬μ ν λ©λͺ¨λ¦¬μ λ¨μ λμκ° λ°μν©λλ€.
// β ν΄κ²°μ±
: button.removeEventListener('click', onClick);
setInterval λλ setTimeoutμ΄ μ€μ λμμ§λ§, λμ€μ λͺ
μμ μΌλ‘ ν΄μ λμ§ μμ κ²½μ°μ λ°μν©λλ€.
clearIntervalμ΄λ clearTimeoutμ μ¬μ©ν΄μΌ ν©λλ€.JavaScript
let count = 0;
// ν° κ°μ²΄λ₯Ό μ°Έμ‘°νλ ν΄λ‘μ λ₯Ό ν¬ν¨ν μΈν°λ²
const bigData = new Array(10000).fill('heavy');
const intervalId = setInterval(() => {
count++;
// μ΄ ν¨μλ bigDataλ₯Ό μ°Έμ‘°νκ³ μμ΄, bigDataλ GC λμμ΄ λ μ μμ΅λλ€.
console.log(count, bigData.length);
}, 1000);
// μ΄ μ½λκ° μ€νλμ§ μμΌλ©΄, bigDataλ λ©λͺ¨λ¦¬μμ ν΄μ λμ§ μμ΅λλ€.
// β ν΄κ²°μ±
: clearInterval(intervalId);
λ©λͺ¨λ¦¬ λμλ₯Ό λ°©μ§νλ κ°μ₯ μ’μ λ°©λ²μ βνμ μλ μ°Έμ‘°λ μ¦μ λμ΄μ£Όλ κ²βμ λλ€.
let λλ constλ₯Ό μ¬μ©νκ³ , μ μ λ³μ μ¬μ©μ μ΅μνν©λλ€.setInterval, setTimeoutμ μ€μ νλ€λ©΄, ν΄λΉ μμ
μ΄ λλ λ removeEventListener λλ clearInterval/clearTimeoutμ ν΅ν΄ λ°λμ ν΄μ ν©λλ€.WeakMapμ΄λ WeakSetμ μ¬μ©νλ©΄ ν€κ° GC λμμ΄ λ μ μμ΅λλ€. μ΄λ βμ½ν μ°Έμ‘°βλ₯Ό μμ±νμ¬ GCκ° κ°μ²΄λ₯Ό μ κ±°νλ κ²μ λ°©ν΄νμ§ μμ΅λλ€.λ©λͺ¨λ¦¬ λμλ λΉμ₯ λμ λμ§ μμ§λ§, μ₯μκ° μ€νλλ μλΉμ€λ νΈλν½μ΄ λ§μ μΉ μ ν리μΌμ΄μ μμλ μΉλͺ μ μΈ μ±λ₯ λ¬Έμ λ₯Ό μΌμΌν΅λλ€. μ£ΌκΈ°μ μΈ νλ‘νμΌλ§ ν΄(μ: Chrome κ°λ°μ λꡬμ Performance, Memory ν)μ μ¬μ©νμ¬ μ ν리μΌμ΄μ μ λ©λͺ¨λ¦¬ μ¬μ©λμ λͺ¨λν°λ§νλ κ²μ΄ μ€μν©λλ€.
λ‘컬 λ€νΈμν¬ νκ²½μ μ‘°κΈμ΄λΌλ λ€λ€λ³Έ μ¬λμ΄λΌλ©΄ ν λ²μ―€μ λ§μ£ΌμΉλ μ΅μν λ¨μ΄κ° μμ΅λλ€. λ°λ‘ NetBIOSμ NBTμ λλ€.…
μλ νμΈμ! νλ μΉ κ°λ°μμ λ°μ΄ν° κ΅νμ ν΅μ¬μΈ JSON(JavaScript Object Notation)μ λμ± κ°λ ₯νκ³ μμ μ μΌλ‘ λ§λ€μ΄μ£Όλ λꡬ,…
β ECMAScript 3(E3)λ 무μμΌκΉ ECMAScript 3λ 1999λ μ 곡μνλ μλ°μ€ν¬λ¦½νΈ νμ€μ΄λ€. μ§κΈ 보면 μ€λλ κΈ°μ κ°μ§λ§,…
CoffeeScriptλ νλ νλ‘ νΈμλ κ°λ° μνκ³μμ λ§€μ° μΈκΈ° μμλ μΈμ΄μκ³ , μ§κΈλ νΉμ νλ‘μ νΈλ λ κ±°μ μμ€ν , κ°κ²°ν…
(Critical Rendering Path, ν΅μ¬ λ λλ§ κ²½λ‘ μλ²½ μ΄ν΄) μΉ λΈλΌμ°μ μ μ£Όμλ₯Ό μ λ ₯νκ³ μν°λ₯Ό λλ₯΄λ μκ°,…
μΉ κ°λ°μ νλ€ λ³΄λ©΄ λꡬλ ν λ²μ―€ λΆμμ κΈμ¨μ CORS μ€λ₯(Cross-Origin Resource Sharing Error)λ₯Ό λ§λκ²…