패스트캠퍼스/자습
자바스크립트로 하는 자료구조와 알고리즘(7장) - 메모리 관리
sunnykim91
2019. 10. 24. 17:18
메모리 누수 : 버려진 메모리를 해제하지 못한 경우 -> 성능이 저하되고 프로그램 자체가 주앋ㄴ되기도함
자바스크립트에는 가비지컬렉터가 있어서 이러한 문제를 해결해주기도 한다.
하지만, 가비지컬렉터가 올바른 방식으로 해제하지 않은 경우에 메모리 누수가 발생한다.
객체가 참조 중이면 해당 객체는 메모리에 존재한다.
마찬가지로 HTML DOM 객체들은 삭제된 이후에는 참조돼서는 안 된다.
함수에서 객체를 참조할 때 필요한 부분만 참조해야 한다.
연습 문제
1.
function someLargeArray() {
return new Array(1000000);
}
let exampleObject = {
'prop1' : someLargeArray(),
'prop2' : someLargeArray()
}
function printProperty(obj) {
console.log(obj['prop1']);
}
printProperty(exampleObject);
printProperty에서 과다한 양의 메모리가 사용된다. 전체 객체를 printProperty함수에 전달했기 때문이다.
이를 해결하기 위해서는 출력하고자 하는 속성만 함수의 매개변수로 전달해야한다.
function someLargeArray() {
return new Array(1000000);
}
let exampleObject = {
'prop1' : someLargeArray(),
'prop2' : someLargeArray()
}
function printProperty(prop) { // 속성을 받아서 그대로 출력
console.log(prop);
}
printProperty(exampleObject['prop1']); // 속성만 전달
2.
let RED = 0;
let GREEN = 1;
let BLUE = 2;
function redGreenBlueCount(arr) {
let counter = new Array(3).fill(0);
for (let i = 0; i < arr.length; i++) {
let curr = arr[i];
if(curr === RED){
counter[RED]++;
} else if (curr === GREEN) {
counter[GREEN]++;
} else if (curr === BLUE) {
counter[BLUE]++;
}
}
return counter;
}
console.log(redGreenBlueCount([0,1,1,1,2,2,2]));
필요하지 않은 곳에서 전역변수를 사용돼었다.
전역변수를 함수안에 써줌으로서 쓸데없는 메모리 낭비를 줄일 수 있다.
(전역변수는 실행시간이 끝나기 전까지 메모리에 들고있으므로 함수안에 써준다)
3.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button id="one">Button 1</button>
<button id="two">Button 2</button>
<script>
let one = document.querySelector("#one");
let two = document.querySelector("#two");
function callBackExample() {
one.removeEventListener("", callBackExample);
}
one.addEventListener('click', function() {
two.remove();
console.log(two);
});
two.addEventListener('click', function() {
one.remove();
console.log(one);
});
</script>
</body>
</html>
DOM 메모리 누수 문제가 있다.
항목들을 제거했지만 여전히 콜백함수에서 참조한다.
이를 수정하기 위해서는 one변수와 two변수를 콜백 범위 내로 이동하고 항목을 제거 한후 이벤트 리스너를 제거한다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button id="one">Button 1</button>
<button id="two">Button 2</button>
<script>
let one = document.querySelector("#one");
let two = document.querySelector("#two");
function callBackOne() {
let two = document.querySelector("#two");
if(!two)
return;
two.remove();
one.removeEventListener('click', callBackOne);
}
function callBackTwo() {
let one = document.querySelector("#one");
if (!one)
return;
one.remove();
two.removeEventListener('click', callBackOne);
}
one.addEventListener('click', callBackOne);
two.addEventListener('click', callBackTwo);
</script>
</body>
</html>
반응형