所属分类:web前端开发
正如“堆内存不足”错误信息所示,当任何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 }
在上述语法中,我们使用for循环进行迭代,直到m*m小于该值为止。这意味着我们进行迭代,直到该值的平方根大于m。
步骤 1 − 使用 for 循环进行迭代,直到值的平方根大于 m,其中 m 是 for 循环的初始化变量。
步骤 2 - 在 for 循环中,如果值可以被 m 整除,那么意味着 m 是该值的一个质因数,并将其存储在因数数组中。
步骤 3 − 在此之后,将该值除以 m,并使用 while 循环多次除以 m,如果可以多次整除。在这里,我们需要存储唯一的质因数,所以我们只在数组中存储 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>
在下面的示例中,我们使用了set来存储质因数,而不是使用数组,因为我们需要获取唯一的质因数。此外,我们使用了for-of循环来打印存储在set中的所有质因数。
<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>
我们学会了在寻找数值的质因数时解决堆内存溢出错误。每当我们遇到堆内存溢出等错误时,我们需要优化我们的代码,就像我们在本教程中优化的那样。