如何避免java.lang.OutOfMemoryError?

Peđ*_*zić 1 java out-of-memory

我有两个简单的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);    
     }    
}
Run Code Online (Sandbox Code Playgroud)

第二个定义恒定功率为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);    
     }    
}
Run Code Online (Sandbox Code Playgroud)

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

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

Luk*_*der 6

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

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

更严重的是,当你深入研究实现时java.math.BigInteger,我认为你只是使用左移更快地遇到这样的错误,因为它比power方法更有效地实现.说完这个,你有没有试过在你的代码中强制使用垃圾收集System.gc()

更新:我原来的推理可能是错的.2 ^ 332192809可以用1GB计算.总体结果可能会有效地"修改" java.math.BigInteger,尽管我认为这种计算可能需要一段时间......

  • @pedja这里有另外的解释:那个数字'2 ^(15*2 ^ 332192809)`可以重新排序为`(2 ^ 4)^((15*2 ^ 332192809)/ 4)`=>`16 ^(15*2 ^(332192809-2))`=>`16 ^(15*2 ^ 332192807)`=> 16 ^(15*(2 ^ 4)^(332192807/4))`~~>`16 ^(15*16 ^ 83048201)`.现在进行比较,请阅读:http://en.wikipedia.org/wiki/Googolplex.Googolplex是一个数字10 ^(10 ^ 100).**Carl Sagan估计用数字(即"10,000,000,000 ......")写一个googolplex在物理上是不可能的,因为这样做需要的空间比已知宇宙所提供的要多.**而且你的数字要大得多. (2认同)