-
[자바스크립트] 가비지 컬렉션javascript 2021. 4. 27. 14:10반응형
더이상 사용되지 않는 메모리 를 지워 주는것
메모리 : 어떤값을 0과1 로바뀌어서 저장을 하는데 그때 의 그값과 그값을 저장한 위치
저수준언어에서는 코드를 통해서 쓰지 않는 변수나 함수 객체 등을 지워줌
그러나 고수준언어 (managed language 에서는 가비지 컬렉터가 그역할을 대신함)
그렇다면 가비지 컬렉터는 어떠한 기준으로 필요없는 메모리를 구분할수 있을까?
1. 레퍼런스 카운팅
:참조하고 있는곳이 있느지 카운트를 하고 없으면 제거
> 순환 참조시 문제가 있음
2.mark and sweep
: 루트를 기준으로 참조값의 사용여부를 mark 하고 mark 되지 않는값을 지운다
> 순환참조시에도 루트에서 닿지 않는경우라면 제거됨
가비지 컬렉터에는 GC Root라는 것이 있다. GC Root들은 힙 외부에서 접근할 수 있는 변수나 오브젝트를 뜻한다. GC Root는 말그대로 가비지 컬렉션의 Root라는 뜻이다. GC Root에서 시작해 이 Root가 참조하는 모든 오브젝트, 또 그 오브젝트들이 참조하는 다른 오브젝트들을 탐색해 내려가며 마크(Mark)한다. 이게 바로 가비지 컬렉션의 첫번째 단계인 Mark단계이다.
+루트들은 일반적으로 코드에서 참조가 계속 유지되는 전연 변수들입니다. 자바스크립트에서는 “window” 객체가 root가 되는 글로벌 변수의 대표적인 예입니다.
출처: https://itstory.tk/entry/자바스크립트에서-메모리-누수의-4가지-형태 [덕's IT Story]
출처: https://imasoftwareengineer.tistory.com/103 [삐멜 소프트웨어 엔지니어]메모리 누수 (memory leak) 란
> 가비지인데 컬렉팅이 안된거
C 언어같은 저수준 언어에서는 메모리 관리를 위해 malloc() 과 free()를 사용한다. 반면, 자바스크립트는 객체가 생성되었을 때 자동으로 메모리를 할당하고 쓸모 없어졌을 때 자동으로 해제한다(가비지 컬렉션). 이러한 자동 메모리 관리는 잠재적 혼란의 원인이기도 한데, 개발자가 메모리 관리에 대해 고민할 필요가 없다는 잘못된 인상을 줄 수 있기 때문이다.
>> 더좋은 알고리즘이 있을수는 있어도 완벽하기는 어렵다 (어떤알고리즘도 코드작성자의 의도를 완전히 파악할수는 없기때문에)
예상치 못한 참조는 개발자는 더 이상 사용되지 않을 것이라 생각했지만, 어떠한 이유로 활성화 상태인 루트 트리 안에 존재하는 메모리 조각들입니다
1 . 변수선언 키워드를 사용하지 않고 값을 할당한 경우
function foo(arg) { abc = "this is a global variable"; } >> window.abc = "this is a global variable" function foo(arg) { this.abc = "this is a global variable"; } >> window.abc = "this is a global variable"
let , var , const 를 사용하지 않고 값을 할당을 하게되면
window 의 프로퍼티로 값이 할당된다. >>> use strict 를 명시해주면 예방할수있음
2 . 타이머함수나 이벤트 가 종료된경우
많은 라이브러리에서 callback을 가지는 기능들을 가지고 있습니다. 이러한 라이브러리의 대부분은 더 이상 사용이 안되면 자체적으로 callback에 대한 참조를 해제하도록 구현되어 있습니다.
많은 라이브러리에서 콜백을 가지고 있거나 특정환경시 발생되는 코드들이 있는데 이러한 경우 라이브러리 내부적으로 더이상 사용이 안되면 callback 에 대한 참조를 해재 한다.
그러나 setInterval 과 같은 경우는 직접 없애줘야 한다.
var someResource = getData(); setInterval(function() { var node = document.getElementById('Node'); if(node) { // Do stuff with node and someResource. node.innerHTML = JSON.stringify(someResource)); } }, 1000);
위 예와 같은 상황에서 node 에 할당된 객체는 없어질지도 모르는 값이다.
만약에 node 가 없어진다면 내부의 핸들러 없시 불필요한 코드가 된다 그러나 핸들러 내부에서는 여전히 필요한 객체들은 참조 하고 있기때문에 불필요한 참조가 일어날수있다.
따라서 필요가 없어지는 상황을 가정해서 clearInterval 을 이용해 없애줘야한다.
var someResource = getData(); let repeat = setInterval(function() { var node = document.getElementById('Node'); if(node) { node.innerHTML = JSON.stringify(someResource)); }else{ clearInterval(repeat) } }, 1000);
3.클로져
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);
4. 돔에서 요소를 가져와서 할당을 하고나서 이후에 돔요소를 지워줬다면 할당한 값도 반드시 null 값을 할당해줘야한다.
var elements = { button: document.getElementById('button'), image: document.getElementById('image'), text: document.getElementById('text') }; function doStuff() { image.src = 'http://some.url/image'; button.click(); console.log(text.innerHTML); } function removeButton() { document.body.removeChild(document.getElementById('button')); // 여기서 elements 에서 여전히 button 참조를 가지고 있습니다. // 이 경우 button element는 여전히 메모리에 상주하게 되며 GC에 의해 수집될 수 없습니다. elements.button:null; } 출처: https://itstory.tk/entry/자바스크립트에서-메모리-누수의-4가지-형태 [덕's IT Story]
auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/
'javascript' 카테고리의 다른 글
[javascript] deep copy / shallow copy (0) 2021.05.10 [자바스크립트] try catch 문을 통한 에러 처리 (0) 2021.05.03 [자바스크립트] 이벤트 루프에 대해서 (0) 2021.04.26 [javascript] promise 에 대하여 (0) 2021.04.23 [자바스크립트] this 에 대해서 (call,apply,bind) (0) 2021.04.13