int n; // 4个字节 int x [4]; // 4个元素的数组,每一个占4个字节 double m; // 8个字节
编译器插入与操作系统进行交互的代码,以便在堆栈中请求所需的字节数来存储变量。
在上面的例子中,编译器知道每个变量的确切内存地址。实际上,每当我们写入这个变量n,它就会在内部翻译成“内存地址4127963”。
注意,如果我们试图访问x[4],我们将访问与m关联的数据。这是因为我们正在访问数组中不存在的元素 - 它比数组中最后一个数据实际分配的元素多了4个字节x[3],并且可能最终读取(或覆盖)了一些m比特。这对其余部分会产生不利的后果。
当函数调用其它函数时,每个函数被调用时都会得到自己的堆栈块。它会保留所有的局部变量和一个程序计数器,还会记录执行的地方。当功能完成时,其内存块会被释放,可以再次用于其它目的。
动态分配
如若我们不知道编译时,变量需要的内存数量时,事情就会变得复杂。假设我们想要做如下事项:
int n = readInput(); //读取用户的输入 ... //用“n”个元素创建一个数组
在编译时,编译器不知道数组需要多少内存,因为它是由用户提供的输入值决定的。
因此,它不能为堆栈上的变量分配空间。相反,我们的程序需要在运行时明确地向操作系统请求适当的空间。这个内存是从堆空间分配的。下表总结了静态和动态内存分配之间的区别:
在JavaScript中分配内存
现在来解释如何在JavaScript中分配内存。
JavaScript使得开发人员免于处理内存分配的工作。
var n = 374; // allocates memory for a number var s = 'sessionstack'; // allocates memory for a string var o = { a: 1, b: null }; // allocates memory for an object and its contained values var a = [1, null, 'str']; // (like object) allocates memory for the // array and its contained values function f(a) { return a + 3; } // allocates a function (which is a callable object) // function expressions also allocate an object someElement.addEventListener('click', function() { someElement.style.backgroundColor = 'blue'; }, false);
一些函数调用也会导致对象分配:
var d = new Date(); // allocates a Date object var e = document.createElement('div'); // allocates a DOM element
方法可以分配新的值或对象:
var s1 = 'sessionstack'; var s2 = s1.substr(0, 3); // s2 is a new string // Since strings are immutable, // JavaScript may decide to not allocate memory, // but just store the [0, 3] range. var a1 = ['str1', 'str2']; var a2 = ['str3', 'str4']; var a3 = a1.concat(a2); // new array with 4 elements being // the concatenation of a1 and a2 elements
内容版权声明:除非注明,否则皆为本站原创文章。