작성이유
- 메모리 Leak 발견했고 해결했다!
- 메모리 Leak과 찾는방법(개발자도구)에 대해서 정리하고 싶어
트러블 슈팅
전체 로직 없으니... 아주 작은 문제같다.. ㅜㅜ
// websocket으로 받는 데이터: newTransactions
const data = [...newTransactions, data (1일치 데이터)]
- 화면에 표시될 데이터 : 24시간전부터 지금까지 데이터
- 문제
- 시간이 지날수록 outdated 데이터가 늘어났다.
- 개발환경에서는 노출되지 않았지만, 배포 후 급격히 늘어나는 Heap...(개발자 도구)
- 해결방법
- outdated 데이터 삭제
Memory Life Cycle
- 할당 : Allocate the memory you need, malloc()
- 사용 : Use the allocated memory (read, write)
- 해제 : Release the allocated memory when it is not needed anymore , free()
JS Variable Memory
- 함수 실행컨텍스트내에
VO(ariable object)
에 해당 변수가 선언 - reference의 경우, Heap에 할당이 되어 포인터로 해당 변수를 가르키게 된다.
- main context에 할당된 변수를
전역 변수
라고 한다.
- main context에 할당된 변수를
JS GC Algorithm(Mark And Sweep)
- 참조되고 있는 메모리(Marking)를 제외하고 제거(사용되지 않는 메모리)
Memory Leak
더 이상 사용하지 않는 메모리를 정리하지 못할때 ㅠㅠ..
1. 전역변수
function foo(arg) {
bar = 'this is an explicit global variable'
}
2. 타이머와 콜백
const someResource = getData();
setInterval(function() {
const node = document.getElementById('Node');
if(node) {
// Do stuff with node and someResource.
node.innerHTML = JSON.stringify(someResource));
}
}, 1000);
3. DOM 외부의 참조
const detachedTree;
function create() {
const ul = document.createElement('ul');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
ul.appendChild(li);
}
detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);
4. 클로져
var theThing = null
var replaceThing = function () {
var originalThing = theThing
var unused = function () {
if (originalThing) console.log('hi')
}
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage)
},
}
}
setInterval(replaceThing, 1000)
Memory 관련 개발자도구
1. Heap snapshot
- 현재 Heap영역의 메모리 할당 내역을 보여준다.
2. Allocation instrumentation on timeline
var x = []
function grow() {
x.push(new Array(1000000).join('x'))
}
document.getElementById('grow').addEventListener('click', grow)
3. Console Performance Monitor
이 자료를 가지고 내가 지금 할 수 있는거?
-
불필요한 노드(페이지에 없는 노드 또는 해제되어야 할 노드)를 찾을 수 있다.
var detachedTree function create() { var ul = document.createElement('ul') for (var i = 0; i < 10; i++) { var li = document.createElement('li') ul.appendChild(li) } detachedTree = ul } document.getElementById('create').addEventListener('click', create)
- 클릭 이벤트가 발생할때마다, Node와 Heap의 크기가 증가 하고 있다.