노드엔진 뚜껑 아래 js#9: 쓰레기 수집

Jilbert Ebrahimi의 Unsplash 사진
우리 시스템에서 우리는 바이트 코드를 겪었다!이제 좀 더 깊이 있는 내용을 봅시다!

쓰레기 수집


한때 사람들은 메모리 관리를 고려하기 위해 코드를 작성해야 했지만, 시간의 추이에 따라 우리는 더 이상 이 문제를 걱정할 필요가 없다.이것은 Garbage Collector (GC)라고 불리는 신기한 도구 덕분이다.
쓰레기 수집은 대부분의 언어에서 메모리 관리의 흔한 방법이다.aGC의 유일한 임무는 사용하지 않은 대상이 차지하는 메모리를 회수하는 것이다.그것은 1959년에 처음으로 LISP에서 사용되었다.
그러나 대상이 언제 다시 사용하지 않는지 어떻게 알 수 있습니까?

노드의 메모리 관리.회사 명


메모리를 걱정할 필요가 없기 때문에, 완전히 컴파일러가 처리합니다.따라서 우리가 새로운 변수를 분배해야 할 때, 메모리 분배는 자동으로 완성되고, 이 메모리가 더 이상 필요하지 않을 때, 메모리 분배는 자동으로 정리된다.
GC 대상이 언제 더 이상 사용하지 않는 방식이 그들의 인용이나 서로 어떻게 인용하는지 안다.대상이 인용되지 않고 다른 대상에 인용되지 않을 때, 쓰레기로 수집된다.이 그림을 보십시오.

몇 개의 대상이 인용되고 인용되고 있는 것을 볼 수 있지만, 두 개의 대상은 인용되거나 인용되지 않았습니다.따라서 이것들은 삭제되고 메모리를 회수합니다.이것은 GC 스캔한 그림입니다.

쓰레기 수집기를 사용하는 단점은 성능에 큰 영향을 미칠 수 있고 예측할 수 없는 정지가 발생할 수 있다는 것이다.

실제 메모리 관리


메모리 관리가 어떻게 작동하는지 설명하기 위해 간단한 예를 들겠습니다.
function add (a, b) {
  return a + b
}
add(4, 5)
우리는 몇 가지 단계를 이해해야 한다.

  • 스택: 스택은 모든 국부 변수, 대상을 가리키는 바늘이나 응용 프로그램이 흐름을 제어하는 위치입니다.우리의 함수에서 두 개의 매개 변수는 모두 창고에 배치될 것이다.

  • 더미: 더미는 프로그램에서 인용 형식 대상 (예를 들어 문자열이나 대상) 을 저장하는 부분입니다.따라서 아래Point 대상은 더미 위에 놓여 있다.
  • function Point (x, y) {
      this.x = x
      this.y = y
    }
    
    const point1 = new Point(1, 2)
    
    만약 우리가 더미 속의 메모리가 차지하는 것을 본다면, 우리는 다음과 같은 결과를 얻을 수 있을 것이다.
    root -----------> point1
    
    이제 몇 가지를 더 추가하겠습니다.
    function Point (x, y) {
      this.x = x
      this.y = y
    }
    
    const point1 = new Point(1, 2)
    const point2 = new Point(2, 3)
    const point3 = new Point(4, 4)
    
    우리는 이것을 가지고 있다.
         |-------------------> point1
    root |-------------------> point2
         |-------------------> point3
    
    현재, GC 가 실행된다면, 우리의 모든 대상은 루트 대상에 대한 인용을 저장하기 때문에 아무 일도 일어나지 않을 것이다.
    중간에 객체를 추가합니다.
    function Chart (name) {
      this.name = name
    }
    
    function Point (x, y, name) {
      this.x = x
      this.y = y
      this.name = new Chart(name)
    }
    
    const point1 = new Point(1, 2, 'Chart1')
    const point2 = new Point(2, 3, 'Chart2')
    const point3 = new Point(4, 4, 'Chart3')
    
    이제 우리는 이것이 생겼다.
         |-------------------> point1 ----> Chart1
    root |-------------------> point2 ----> Chart2
         |-------------------> point3 ----> Chart3
    
    지금 우리가 point2undefined 로 설정하면 어떻게 됩니까?
         |-------------------> point1 ----> Chart1
    root |                     point2 ----> Chart2
         |-------------------> point3 ----> Chart3
    
    루트 객체 point2 에 액세스할 수 없습니다.따라서 다음 GC 실행 시 제거됩니다.
         |-------------------> point1 ----> Chart1
    root
         |-------------------> point3 ----> Chart3
    
    이것은 GC의 기본 작업 원리입니다. 루트를 모든 대상에 옮겨다니고, 대상 목록에 어떤 대상이 옮겨다니지 않으면 루트에 접근할 수 없기 때문에 삭제됩니다.
    GC 다른 방법을 채택할 수 있다.

    GC 방법


    GC를 처리할 수 있는 많은 방법이 있다.
    새로운 공간과 낡은 공간
    이것은 Node.js 사용하는 방법이다.
    두 가지 주요 부분이 쌓여 있는데 그것이 바로 새로운 공간과 낡은 공간이다.새로운 공간은 분배가 적극적으로 진행되고 있는 곳이다.이곳은 우리가 쓰레기를 가장 빨리 수집하는 곳으로 새로운 공간은 대략 1 ~ 8MB이다.새로운 공간 속의 모든 물체를 젊은 세대라고 부른다.
    반면 낡은 공간은 지난번 쓰레기 수집에서 살아남은 대상이 있는 위치로 우리의 예시에서 point1point3 대상은 낡은 공간에 있다.그들은 기성세대라고 불린다.그러나 낡은 공간에서의 분배 속도는 상당히 빠르고GC 매우 비싸기 때문에 거의 실행된 적이 없다.
    그러나 20퍼센트의 젊은 세대만 살아남고 기성세대로 승진했기 때문에 이런 낡은 우주 스캐닝을 자주 할 필요는 없다.이것은 이 공간이 다 소모되었을 때만 실행됩니다. 이것은 약 512mb를 의미합니다. 노드의 --max-old-space-size 로고를 사용하여 이 제한을 설정할 수 있습니다.js.낡은 공간 메모리를 회수하기 위해 GC 두 가지 다른 수집 알고리즘을 사용했다.
    스캔 컬렉션 지우기 및 표시
    제거 수집 속도가 빨라 젊은 세대에서 실행되고 스캐닝 수집 방법의 속도가 느려 기성세대에서 실행된다.
    태그 및 스캔 알고리즘은 몇 단계만 거치면 됩니다.
  • 루트 객체에서 시작합니다.루트는 코드에서 참조하는 전역 변수입니다.JS에서 이것은 window 대상이거나 노드에서 global 대상일 수 있다.이 모든 루트의 전체 목록은 GC 에서 구축됩니다.
  • 그리고 이 알고리즘은 모든 뿌리와 그 모든 자대를 검사하여 모든 뿌리를 활동적이라고 표시한다. 따라서 이것은 뿌리가 아직 쓰레기가 아니라는 것을 의미한다. 논리적으로 뿌리가 도달할 수 없는 그 어떠한 내용도 활동적이라고 표시하지 않는다. 이것은 쓰레기
  • 이후 비활성 개체를 모두 방출합니다.

  • 결론


    우리는 시리즈가 끝날 때까지 또 한 편의 문장이 있다.본고에서 우리는 메모리 처리와 쓰레기 수집을 토론했고 다음 글에서 컴파일러가 전체 코드를 어떻게 최적화하는지 토론할 것이다!침착해!

    좋은 웹페이지 즐겨찾기