JavaScript 如何解决堆超出内存的问题
正如’heap out of memory’错误信息所提示的那样,当任何JavaScript代码占用的内存超过分配的内存时,它就会发生,当我们运行任何JavaScript程序时,计算机会分配特定的内存给JavaScript程序。
当我们运行JavaScript或任何编程语言的代码时,我们的计算机会创建一个进程并分配固定的内存。当一个程序需要更多的内存大小时,它就会产生一个错误,如堆出内存。例如,如果我们创建一个大小为1020的数组,并试图用一些值来初始化每个数组索引,那么堆就会超出内存并引发错误。
在本教程中,我们将学习如何解决JavaScript堆超出内存的问题,同时寻找非常多的数值的质因数。
用户可以按照下面的例子来直观地了解堆超出内存的错误。
例子(可视化的错误)
在下面的例子中,我们创建了getPrimeFactors()函数,用来返回任何数值的质因数。当我们传递一个小的数字(接近103 )时,它工作得很好,但是当我们传递一个大的数字(接近109 )作为参数来寻找质因数时,它就会出现错误,而且浏览器窗口变成了黑屏。
在这个例子中,出现内存错误是因为我们使用了两个嵌套循环来迭代数组,程序的时间复杂度变成了O(N2 ),所占用的内存比分配的内存还要多。
<html>
<body>
<h2>Visualizing the <i>Process out of memory</i> while finding all prime factors of a number in JavaScript </h2>
</body>
<script>
try {
function getPrimeFactors(num) {
var factor = [];
let primes = [];
for (let m = 2; m <= num; m++) {
if (!factor[m]) {
primes.push(m);
for (let n = m << 1; n <= num; n += m) {
factor[n] = true;
}
}
}
return primes;
}
getPrimeFactors(1212121212323)
} catch (err) {
console.log(err.message)
}
</script>
</html>
在上述例子的输出中,用户可以观察到堆超出内存的错误。为了摆脱它,我们需要优化代码的时间和空间复杂性。
下面,我们将优化例1中写的代码的时间复杂度,以找到给定数字的所有唯一素因子。
语法
用户可以按照下面的语法写出优化的代码来寻找给定数值的唯一质因数。
for (let m = 2; m * m <= value; m++) {
if (value % m === 0) {
// store factor to array
while (value % m === 0) {
value /= m;
}
}
}
if (value > 2) {
// store factor to array
}
在上面的语法中,我们进行迭代,直到m*m小于使用for循环的值。这意味着我们进行迭代,直到值的平方根大于m。
操作步骤
第1步 - 使用for循环进行迭代,直到值的平方根大于m,其中m是for循环的初始化变量。
第2步 - 在for循环中,如果值能被m整除,就意味着m是该值的质因数,并将其存储在因子数组中。
第3步 - 之后,用m除以该值,如果能被m多次除以,则用while循环进行多次除法。在这里,我们需要存储唯一的质因数,所以我们在数组中只存储m的值一次。
第4步 - 一旦for循环的所有迭代完成,检查该值是否大于2。如果是,意味着该值是最大的质因数,并将其存储在数组中。
例子 (解决错误)
下面的例子使用数组来存储质因数。此外,我们还实现了上述算法来寻找质因数。
用户可以尝试寻找大数值的唯一质因数,如1020,并看到代码给出的输出没有任何错误。
<html>
<body>
<h2>Solving the <i> Process out of memory </i> while finding all prime factors of a number in JavaScript</h2>
<div id = "output"> </div>
</body>
<script>
let output = document.getElementById('output');
function getPrimeFactors(value) {
let initial = value;
var factors = [];
for (let m = 2; m * m <= value; m++) {
// if the value is divisible by m, it is a prime factor
if (value % m === 0) {
factors.push(m);
// divide value by m until it is divisible
while (value % m === 0) {
value /= m;
}
}
}
// push largest prime factor at last
if (value > 2) {
factors.push(value);
}
output.innerHTML += "The prime factors of " + initial + " are : " + factors + "<br/>";
}
getPrimeFactors(100000000002);
getPrimeFactors(65416841658746141122);
</script>
</html>
例子
在下面的例子中,我们使用了集合来存储质因数,而不是使用数组,因为我们需要得到唯一的质因数。此外,我们还使用了for-of循环来打印存储在集合中的所有质因数。
<html>
<body>
<h2>Solving the <i> Process out of memory </i> while finding all prime factors of a number in JavaScript</h2>
<div id = "output"> </div>
</body>
<script>
let output = document.getElementById('output');
function getPrimeFactors(value) {
let initial = value;
var factors = new Set();
for (let m = 2; m * m <= value; m++) {
if (value % m === 0) {
factors.add(m);
while (value % m === 0) {
value /= m;
}
}
}
if (value > 2) {
factors.add(value);
}
output.innerHTML += "The prime factors of " + initial + " are : <br/>";
// print values of a set
for (let fac of factors) {
output.innerHTML += fac + "<br/>";
}
}
getPrimeFactors(44352747207453165);
</script>
</html>
我们学习了如何在寻找数字的质因数时解决堆超出内存的错误。每当我们遇到像堆出内存这样的错误时,我们需要优化我们的代码,就像我们在本教程中所优化的那样。