JavaScript内存泄漏的处理方式(2)

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
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/786.html