가비지 컬렉터

개발 log·2021년 9월 6일
0

JS 지식

목록 보기
7/36
post-thumbnail

메모리 생명주기

메모리 할당(allocate)

프로그램이 사용할 수 있도록 운영체제가 메모리를 할당함
저수준언어(C 등등)에서는 개발자가 명시적으로 처리해줘야함
하지만 고수준 언어에서는 개발자가 신경쓸 필요 없음

메모리 사용(use)

할당된 메모리를 실제로 프로그램이 사용하는 단계
개발자가 코드 상에서 할당된 변수를 사용함으로써 읽기와 쓰기 작업이 이루어짐

메모리 해제(release)

프로그램에서 필요하지 않은 메모리 전체를 되돌려주어 다시 사용가능하게 만드는 단계
메모리 할당작업과 마찬가지로 저수준언어에서는 명시적으로 처리해줘야함

JS에서의 메모리 할당

var s1 = 'sessionstack';
var s2 = s1.substr(0, 3); // s2는 새로운 문자열이 됨
// 문자열은 불변(immutable)이므로 자바스크립트는 메모리를 할당하지 않고 
// [0, 3]의 범위만 저장할 수도 있음

var a1 = ['str1', 'str2'];
var a2 = ['str3', 'str4'];
var a3 = a1.concat(a2); 
// 4개의 요소를 가진 새로운 배열은 a1과 a2 요소의 연결이 됨

가비지 컬렉션

어떤 메모리가 더 이상 필요없음을 알아내는 것은 결정불가능한 문제이기 때문에 가비지컬렉션은 특정 제한적인 해결책만을 구현함

참조횟수계산 가비지컬렉션

객체가 가리키는 참조가 하나도 없는 경우 가비지컬렉션 대상으로 간주됨

var o1 = {
  o2: {
    x: 1
  }
};
// 두 객체가 생성됨
// 'o2'는 'o1'이 자신의 속성으로서 참조함
// 둘 다 가비지컬렉션 될 수 없음
var o3 = o1; // 'o3' 변수는 'o1'이 가리키는 오브젝트에 대한 참조를 갖는 두 번째임
o1 = 1;      // 이제 'o1'에 있던 객체는 하나의 참조만 남게 되고
             // 그것은 'o3' 변수에 들어 있음
var o4 = o3.o2; // 'o2' 속성에 대한 참조
                // 이제 이 객체는 두개의 참조를 가짐. 하나는 속성으로서 
                // 다른 하나는 'o4' 변수로서
o3 = '374'; // 원래 'o1'에 있던 객체는 이제 참조를 하는 곳이 없음 
            // 따라서 가비지컬렉션 될 수 있음
            // 하지만 'o2' 속성은 'o4' 변수가 참조하므로 가비지컬렉션 될 수 없음
o4 = null; // 원래 'o1'객체 내에 있던 'o2'속성은 이제 참조하는 곳이 없으므로
           // 가비지컬렉션 될 수 있음

순환 참조로 인해 생기는 문제

function f() {
  var o1 = {};
  var o2 = {};
  o1.p = o2; // o1은 o2를 참조함
  o2.p = o1; // o2는 o1을 참조함. 이를 통해 순환 참조가 만들어짐.
}
f();

위 예제에서는 서로 각 객체가 서로 참조하므로 순환참조 생성

하지만 함수가 호출된 후 스코프를 벗어나게 되기에 실질적으로는 쓰레기 값이 됩니다.

하지만 참조횟수계산 알고리즘에서는 두 객체가 적어도 한 번은 참조한 것으로 간주하기에 해당 알고리즘으로는 둘 다 가비지컬렉션 될 수 없음

마크스위프 알고리즘

객체가 쓰레기 값이 아닌지 판단하기 위해 해당 객체에 닿을 수 있는지를 판단하는 알고리즘

  1. Root : 일반적으로 Root는 코드에서 참조되는 전역 변수

    • JS는 window 객체
    • node.js는 global 객체
      가비지컬렉터는 모든 루트의 완전한 목록을 만들어냄
  2. 모든 루트와 자식들을 검사하여 활성화 여부 표시(활성상태면 쓰레기 값(가비지)이 아님)

    • 루트에서 닿을 수 없는 것들은 가비지로 표시
  3. 활성으로 표시되지 않은 모든 메모리를 os에 반환


가비지 컬렉터 수행시기

개발자는 가비지컬렉션이 언제 작동하는지 알기 어렵다
이 말은 프로그램이 실제로 필요한 것 보다 더 많은 메모리를 사용할 수 도 있다는 뜻

비결정주의가 가비지컬렉션이 언제 수행될지 확실히 알 수 없다는 뜻이기는 하지만
대부분의 가비지 컬렉터들의 구현은 공통적으로 메모리 할당 중에 가비지 컬렉션을 넘겨줌
할당이 일어나지 않으면 대부분의 가비지컬렉터는 아무일도 하지 않음

참조사이트

profile
프론트엔드 개발자

0개의 댓글