如何避免java.lang.OutOfMemoryError?

我有两个简单的java代码。第一个定义恒定功率为power = a.pow(b);

import java.math.BigInteger; public class FermatOne { public static void main(String[] args) { BigInteger a = new BigInteger ("2"); BigInteger k = new BigInteger ("15"); BigInteger c = new BigInteger ("1"); int b = 332192810; BigInteger n = new BigInteger ("2"); BigInteger power; power = a.pow(b); BigInteger exponent; exponent = k.multiply(power); BigInteger mod; mod = exponent.add(c); BigInteger result = n.modPow(exponent,mod); System.out.println("Result is ==> " + result); } } 

第二个定义恒定功率为power = BigInteger.ONE.shiftLeft(b)

 import java.math.BigInteger; public class FermatOne { public static void main(String[] args) { BigInteger k = new BigInteger ("15"); BigInteger c = new BigInteger ("1"); int b = 332192810; BigInteger n = new BigInteger ("2"); BigInteger power; power = BigInteger.ONE.shiftLeft(b); BigInteger exponent; exponent = k.multiply(power); BigInteger mod; mod = exponent.add(c); BigInteger result = n.modPow(exponent,mod); System.out.println("Result is ==> " + result); } } 

在命令行中设置内存标志-Xmx1024m第一个代码工作正常,但对于第二个代码我收到错误:java.lang.OutOfMemoryError:Java堆空间

我的问题:我应该在第二个代码中更改什么来避免java.lang.OutOfMemoryError?

你试图计算一个像2 ^ (15 * 2 ^ 332192809) 。 我不知道你是否能在宇宙中适应这样的数字!! 或许,答案很简单…… 42 ? 😉

更严重的是,你真的很麻烦,计算这个数字。 以比特编码, 15 * 2 ^ 332192810本身几乎需要几千兆字节。 然后再次提高2力量,我不想知道……

更严重的是,当你深入研究java.math.BigInteger的实现时,我认为你只是使用左移更快地遇到这样的错误,因为它比power方法更有效地实现。 话虽如此,您是否尝试使用System.gc()强制在代码中进行垃圾收集?

更新 :我原来的推理可能是错的。 2 ^ 332192809可以用1GB计算。 整个结果可能会被java.math.BigInteger有效地“修改”,虽然我相信这个计算可能需要一段时间……

这只是一个猜测,但BigInteger.ONE.shiftLeft(332192810); 将在内部创建一个长度为x + 10381025int数组。 由于int是4个字节的大,你只需要为那个调用获得大约40兆字节的数据。 我假设其他调用复制了那些数据,因此你获得了很高的内存消耗。