如何避免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 + 10381025
的int
数组。 由于int是4个字节的大,你只需要为那个调用获得大约40兆字节的数据。 我假设其他调用复制了那些数据,因此你获得了很高的内存消耗。