>웹 프론트엔드 >JS 튜토리얼 >JS 메모리 관리 메커니즘 및 검증 설명

JS 메모리 관리 메커니즘 및 검증 설명

coldplay.xixi
coldplay.xixi앞으로
2020-12-30 17:34:412747검색

javascript이 칼럼에서는 메모리 관리 메커니즘과 검증을 소개합니다

JS 메모리 관리 메커니즘 및 검증 설명

권장(무료): JavaScript(동영상)

범위 JavaScript 변수의 범위는 제한됩니다. 범위를 초과하면 변수를 더 이상 사용할 수 없습니다.

현재 변수가 전역 변수로 변환되는 것을 방지할 수 있습니다.
  • 변수의 범위와 변수 범위를 효과적으로 제한합니다. 선언 방법에 따라 다른 범위도 생성됩니다.
  • Undeclared: 전역 변수

var 선언됨:

function
  • let, 의 범위 const 선언: 범위는 {}에 있습니다.
  • var 声明:作用域在 函数
  • letconst 声明:作用域在 {}

var 声明的变量

在函数内声明的变量其作用域会被限制在该函数的调用栈中,在外部无法直接得到该作用域内的变量。下面的例子中, fn 函数内的变量在全局下是没有办法查看的。

function fn() {
  var a = 1;
}
fn();
console.log(a); // 无法得到 fn 函数內的 a 变量

所以常用 "立即函数" 来限制变量的作用域,主要是避免全局变量的产生。

(function() {
  var b = 1;
})();
console.log(b); // 无法得到 fn 函数內的 b 变量

let、const 声明的变量

ES6 之后所新增的letconst 作用域则与过去不同,改用 {} 作为作限制用域的方式,这让 for 循环及部分语法避免产生多余的变量来影响作用域。

var 不同的是 const 所定义的变量作用域被限制在 {} 中。所以这个例子中的变量 c 可在外部得到值,d 则无法取到。

{
  var c = 1;
  const d = 1;
}
console.log(c); // 1
console.log(d); // Uncaught ReferenceError: d is not defined,无法取到变量 d

内存管理机制

每当我们新增一个变量时,在内存中就会占用一个位置来保存它的值,以便在程序后续运行时可以多次使用。

下面的代码会在内存中开辟一个 a 的空间来存储数字 1 的值。

var a = 1

流程如下:

  1. 开辟一个内存空间来存放变量  a ,不过这时还没有赋值(原因可参考:Hoisting)

JS 메모리 관리 메커니즘 및 검증 설명

  1. a 赋值。

JS 메모리 관리 메커니즘 및 검증 설명

所有的变量都会占用内存空间,除此之外对象、数组的属性以及函数参数等也会用相同的概念进行占用。调用一个函数时,每一个函数的作用域也都会反复的进行内存占用。随着应用程序越来越复杂的情况下,如果持续的占用内存而没有进行适当的释放,那么内存可能会被耗尽。

JavaScript 引擎具有内存回收的机制,会释放不再使用的变量内存,其基本概念为:当没有任何的引用指向它时就会释放内存。

来自MDN:collectible if there are zero references pointing to it.

内存释放的验证

下面用一个例子来说明及验证内存释放的机制,首先用一段函数来产生一个非常长的字符串,长字符串会占用大量的内存空间。

在调用 randomString 函数后会返回一个很长的字串:

function randomString(length) {
  var result = '';
  var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  var charactersLength = characters.length;
  for (var i = 0; i <h4>案例一:使变量维持在可引用的状态(不会释放内存)</h4><p>定义一个全局变量 <code>demoData</code>,这个变量会持续维持可被引用的状态。</p><pre class="brush:php;toolbar:false">var demoData = []; // 全局变量
function getData() {
  for (let i = 0; i <p>执行这段代码后,进入 Chrome DevTools 中的 Memory 页,这个功能可以得到当前页面所占用的内存状况。接下来点击 "Take snapshot" 按钮。</p><p><img src="https://img.php.cn/upload/image/189/951/684/1609320713198525.png" title="1609320713198525.png" alt="JS 메모리 관리 메커니즘 및 검증 설명"></p><p>可以看到目前执行完这段代码后占用了 6.2MB 的内存空间(注意:任何浏览器环境和插件都会影响所占用的内存状态)。</p><p><img src="https://img.php.cn/upload/image/742/181/269/1609320718742831.png" title="1609320718742831.png" alt="JS 메모리 관리 메커니즘 및 검증 설명"></p><h4>案例二:使变量无法再次被引用(执行后释放内存)</h4><p>限制变量的作用域,使变量无法再被外部引用。</p><p>此段代码依然会执行这个函数,也会将值赋值给变量,但外部无法再次引用 <code>demoData</code></p>🎜var 🎜🎜🎜에 선언된 변수 함수 내에서 선언된 변수의 범위는 다음으로 제한됩니다. 함수의 호출 스택에서 , 이 범위의 변수는 외부에서 직접 얻을 수 없습니다. 다음 예에서 <code>fn</code> 함수 내의 변수는 전역적으로 볼 수 없습니다. 🎜<pre class="brush:php;toolbar:false">function getData() {
  var demoData = []; // 局部变量
  for (var i = 0; i 🎜그래서 "즉시 함수"는 주로 전역 변수 생성을 피하기 위해 변수의 범위를 제한하는 데 사용되는 경우가 많습니다. 🎜rrreee🎜🎜let 및 const 선언 변수🎜🎜🎜ES6 이후 새로 추가된 <code>let</code> 및 <code>const</code> 범위는 이전과 다르므로 대신 <code>{}를 사용하세요. </code> 범위를 제한하는 방법으로 범위에 영향을 미치는 중복 변수 생성을 방지하기 위해 루프와 일부 구문을 허용합니다. 🎜🎜<code>var</code>와의 차이점은 <code>const</code>로 정의된 변수의 범위가 <code>{}</code>로 제한된다는 것입니다. 따라서 이 예의 변수 <code>c</code>는 외부에서 값을 가져올 수 있지만 <code>d</code>는 그럴 수 없습니다. 🎜rrreee🎜🎜메모리 관리 메커니즘🎜🎜🎜변수를 추가할 때마다 변수는 나중에 프로그램이 실행될 때 여러 번 사용할 수 있도록 값을 저장하기 위해 메모리의 한 위치를 차지합니다. 🎜🎜다음 코드는 숫자 1의 값을 저장하기 위해 메모리에 <code>a</code> 공간을 엽니다. 🎜rrreee🎜과정은 다음과 같습니다. 🎜<ol>🎜변수 <code>a</code>를 저장할 메모리 공간을 열었지만 아직 할당된 값이 없습니다. (이유는 Hoisting을 참조하세요.) 🎜</ol>🎜<img src="https://img.php.cn/upload/image/255/233/570/1609320703253175.png" title="1609320703253175.png" alt="JS 메모리 관리 메커니즘 및 검증 설명">🎜<ol>🎜은 <code></code> 과제입니다. 🎜</ol>🎜<img.php.cn title="1609320708403601.png" alt="2a2c245dd1d9d9e210bd692708380d7.p 응">🎜🎜모든 변수는 메모리 공간을 차지합니다. 또한 객체, 배열 속성, 함수 매개변수도 동일한 개념을 사용하여 메모리 공간을 차지합니다. 함수가 호출되면 각 함수의 범위도 메모리를 반복적으로 차지합니다. 응용프로그램이 복잡해짐에 따라 메모리를 적절하게 해제하지 않고 계속 점유하면 메모리가 소진될 수 있습니다. 🎜🎜JavaScript 엔진에는 더 이상 사용되지 않는 변수 메모리를 해제하는 메모리 재활용 메커니즘이 있습니다. 기본 개념은 메모리를 가리키는 참조가 없으면 메모리가 해제된다는 것입니다. 🎜<blockquote>MDN에서: 이를 가리키는 참조가 없으면 수집 가능합니다.</blockquote>🎜🎜메모리 해제 확인🎜🎜🎜다음은 메모리 해제 메커니즘을 설명하고 확인하는 예를 사용합니다. 먼저 함수를 사용합니다. 매우 긴 문자열을 생성하려면 긴 문자열은 많은 메모리 공간을 차지합니다. 🎜🎜<code>randomString</code> 함수를 호출하면 매우 긴 문자열이 반환됩니다. 🎜rrreee<h4>사례 1: 변수를 참조 가능한 상태로 유지(메모리가 해제되지 않음)</h4>🎜 계속 참조될 전역 변수 <code>demoData</code>를 정의하세요. 🎜rrreee🎜이 코드를 실행한 후 Chrome DevTools의 메모리 페이지에 들어가세요. 이 함수는 현재 페이지가 차지하는 메모리 상태를 가져올 수 있습니다. 다음으로 "스냅샷 찍기" 버튼을 클릭하세요. 🎜🎜<img src="https://img.php.cn/upload/image/189/951/684/1609320713198525.png" title="1609320713198525.png" alt="JS 메모리 관리 메커니즘 및 검증 설명"> 🎜🎜예 이 코드를 실행한 후 현재 6.2MB의 메모리 공간이 사용되고 있음을 알 수 있습니다(참고: 브라우저 환경과 플러그인이 메모리 점유 상태에 영향을 미칩니다). 🎜🎜<img src="https://img.php.cn/upload/image/742/181/269/1609320718742831.png" title="1609320718742831.png" alt="JS 메모리 관리 메커니즘 및 검증 설명">🎜<h4> 사례 2: 변수를 다시 참조할 수 없게 만듭니다(실행 후 메모리 해제)</h4>🎜변수를 더 이상 외부에서 참조할 수 없도록 변수의 범위를 제한합니다. 🎜🎜이 코드는 여전히 함수를 실행하고 변수에 값을 할당하지만 <code>demoData</code>의 값은 외부에서 다시 참조될 수 없습니다. 🎜<pre class="brush:php;toolbar:false">function getData() {
  var demoData = []; // 局部变量
  for (var i = 0; i <p>然后回到 Memory 页点击 "Take snapshot" 重新取得内存的状态,接下来会得到与前面不同的结果,这次只占用了 1.2MB 的内存(其中 5MB 被释放掉了)</p><p><img src="https://img.php.cn/upload/image/148/641/618/1609320723163241.png" title="1609320723163241.png" alt="JS 메모리 관리 메커니즘 및 검증 설명"></p><p><strong>总结</strong></p><p>通过前面的例子,我们知道了作用域以及内存之间的关系,而内存管理也是前端打工人必须要掌握的知识(除了控制内存的使用大小,还需在必要时保留而不被释放)。</p>

위 내용은 JS 메모리 관리 메커니즘 및 검증 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제