기본 유형은 스택에 저장되고 참조 유형은 힙에 저장됩니다. JavaScript는 변수(객체, 문자열 등)가 생성될 때 자동으로 메모리를 할당하고, 사용되지 않을 때 "자동으로" 해제합니다. 릴리스 프로세스를 가비지 수집이라고 합니다.
가비지 수집기가 수행해야 하는 모든 작업
공간에 활성(라이브) 개체와 비활성(비라이브) 개체를 표시
비활성 객체가 차지하는 메모리를 재활용 또는 재사용
메모리 조각화 발생을 방지하기 위한 메모리 구성
일반적으로 참조되지 않는 객체는 가비지이므로 삭제해야 합니다. 루트부터 시작하여 객체를 탐색합니다.
예외
여러 개체 참조가 링을 형성하고 서로를 참조하지만 루트에서 액세스할 수 없는 경우 이러한 개체도 가비지이므로 지워야 합니다.
루트 개체
에는 명백한 이유로 삭제할 수 없는 본질적으로 도달 가능한 기본 값 세트가 있습니다.
라이브 개체
루트에서 참조 또는 참조 체인에 액세스할 수 있는 경우 다른 값에 액세스할 수 있는 것으로 간주됩니다.
힙 분할 신세대와 구세대를 위해.
신세대는 생존 시간이 짧은 객체를 저장하고, 구세대는 생존 시간이 긴 객체를 저장합니다.
은 힙 메모리를 두 부분으로 나눕니다. 하나는 사용 영역, 다른 하나는 사용 가능한 공간입니다. 유휴 상태의 공간.
새로 추가된 개체는 사용 영역에 저장됩니다 사용 영역이 거의 가득 차면 쓰레기 청소 작업이 필요합니다.
신세대 가비지 컬렉터는 사용 영역의 활성 개체개체를 표시합니다. 표시가 완료된 후 사용 영역의 활성 개체를 자유 영역으로 복사합니다. 메모리 블록이 분산되는 문제를 해결했습니다.
사용 공간에서 비활성 물체가 차지하는 공간을 정리하세요. 마지막으로 역할이 바뀌어 원래 사용 영역은 새로운 무료 영역이 되고, 원래 무료 영역은 새로운 사용 영역이 됩니다.
오브젝트가 Old Generation으로 이동됨
전체 일시 중지 문제
JavaScript는 메인 스레드에서 실행되는 단일 스레드 언어로 가비지 수집이 수행되면 JavaScript 스크립트의 실행을 차단하고 가비지 수집이 완료될 때까지 기다려야 합니다.
GC가 너무 오래 걸리면 페이지 정지가 발생할 수 있습니다.
병렬 재활용 메커니즘
메인 스레드에서 가비지 수집기가 실행되는 동안 여러 보조 스레드가 동시에 동일한 재활용 작업을 수행하기 시작합니다.
scavenge 방법 사용 문제
1. 살아남은 객체가 많아, 살아남은 객체를 자주 복사하면 효율성이 떨어집니다
2. 공간의 절반을 낭비합니다
주로 mark-clear 방법을 사용하고, 메모리 할당이 부족할 경우 mark-organize 방법
을 사용하여 구세대 가비지 수집 기간
1. 먼저 mark-clear를 사용하여 가비지 공간 재활용을 완료합니다. 공간을 확보하려면 mark-organize를 사용하세요. 최적화
3. 효율성 최적화를 위해 최적화-증분 표시 및 지연 정리를 사용하세요.
살아있는 객체는 신세대에서 작은 부분만을 차지하고, 죽은 객체는 구세대에서 작은 부분만을 차지하기 때문에 두 가지 재활용 방법 모두 효율적으로 처리할 수 있습니다.
단점 메모리 조각화가 너무 많습니다. 큰 메모리를 할당해야 하는 경우 조각난 나머지 공간이 할당을 완료하기에 충분하지 않고 이 수집이 필요하지 않기 때문에 미리 가비지 수집이 시작됩니다.
-> 마킹-구성 알고리즘 살아남은 객체를 메모리 공간의 한쪽 끝으로 이동한 후 경계 밖의 모든 메모리를 지웁니다.
증분 마킹
오브젝트가 많아 전체 오브젝트 세트를 한 번에 순회하여 마킹하려고 하면 시간이 좀 걸리고 실행이 다소 지연될 수 있습니다. 따라서 엔진은 가비지 수집을 여러 부분으로 나누려고 시도합니다. 그런 다음 각 부분이 별도로 실행됩니다.
V8은 구세대 가비지 수집기를 최적화하여 전체 일시 중지 표시에서 증분 표시로 전환했습니다.
가비지 수집을 짧은 GC 가비지 수집 기간으로 전환
흑백(생존 및 사망) 표시 전략을 채택하는 경우 가비지 수집기가 증분 수집 기간을 수행한 후 잠시 후 메인 스레드가 활성화됩니다. 애플리케이션에서 JavaScript 코드 조각을 실행한 후 가비지 컬렉터가 다시 시작되면 메모리가 흑백이 되어 다음에 어디로 가야할지 알 수 없습니다
Lazy cleanup
증가 표시 완료되면 , 게으른 정리가 시작됩니다. 증분 마킹이 완료되면 현재 사용 가능한 메모리가 코드를 빠르게 실행하기에 충분하다면 실제로 메모리를 즉시 정리할 필요가 없으며 정리 프로세스를 약간 지연시키고 JavaScript 스크립트 코드가 먼저 실행되도록 할 수 있습니다. 한 번에 모두 정리할 필요가 없습니다. 비활성 개체 메모리를 모두 지운 후 필요에 따라 비활성 개체 메모리가 모두 지워질 때까지 하나씩 정리한 다음 증분 마킹
3색 표시 이 방법의 표시 작업은 매번 전체 메모리 공간을 스캔하지 않고 점진적으로 실행할 수 있습니다. 일시 중지 및 복구의 일부 작업을 수행하기 위해 증분 재활용과 잘 조화될 수 있습니다. 흰색: 표시되지 않음 개체
회색: 자체 표시됨, 해당 개체의 참조 개체가 표시되지 않음
회색으로 표시할 수 있는 개체가 없을 때까지, 즉 도달할 수 있는 개체가 없을 때까지 계속됩니다. 나머지 흰색 개체는 연결할 수 없으며 재활용을 기다리고 있습니다.
첫 번째 증분 분할에서 모든 ABC가 검은색으로 표시되고 JavaScript 스크립트가 B->D로 실행되어 두 번째 증분 분할이 시작된다고 가정합니다. 새 개체 D는 처음에는 흰색이지만 현재는 회색 개체가 없습니다. 이는 모든 표시가 완료되었으며 정리 단계에서 D가 재활용되어야 함을 의미합니다. 이것은 옳지 않습니다.
동시 재활용
증분 표시는 총 일시 중지 시간을 늘리고 애플리케이션 처리량을 감소시킵니다
위 내용은 JS의 가비지 수집 메커니즘에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!