Java 内存不足错误与黑客问题:反向素数

Java 内存不足错误与黑客问题:反向素数,java,optimization,out-of-memory,primes,Java,Optimization,Out Of Memory,Primes,生成尽可能多的不同素数p,以便反向(p)是 也是素数且不等于P 输出:每行打印一个整数(≤ 10^15 ). 打印的内容不要超过 总共10^6个整数 评分:让N=正确的输出。 M=输出不正确。您的分数将最大(0,N-M)。 注意:只有p和反向(p)中的一个被视为正确。如果两个都在文件中,则其中一个将被视为不正确。 样本输出107 13 31 17 2 解释 分数为1。由于13107,17是正确的。31是不正确的,因为 已经有13个了。2是不正确的 下面是我编写的代码,它在Eclipse中为我提供

生成尽可能多的不同素数p,以便反向(p)是 也是素数且不等于P

输出:每行打印一个整数(≤ 10^15 ). 打印的内容不要超过 总共10^6个整数

评分:让N=正确的输出。 M=输出不正确。您的分数将最大(0,N-M)。

注意:只有p和反向(p)中的一个被视为正确。如果两个都在文件中,则其中一个将被视为不正确。

样本输出107 13 31 17 2

解释

分数为1。由于13107,17是正确的。31是不正确的,因为 已经有13个了。2是不正确的

下面是我编写的代码,它在Eclipse中为我提供了内存不足的输出

由于内存需求是256MB,我设置了
-Xmx256M
,但由于它给了我一个
内存不足的错误,我一定是误解了这个问题,或者我的代码在内存利用率方面有缺陷。我做错了什么?我得到了较小的
lONGMAX
的期望输出,如
10000
1000000

public class ReversePrime {
    final static long lONGMAX=1000000000000000L;
    final static int MAXLISTSIZE=1000000;
    final static boolean[] isPrime=isPrime();
    public static void main(String...strings ){

        Set<Long> reversedCheckedPrime = new LinkedHashSet<Long>();
        int isPrimeLength=isPrime.length;
        for(int i = 0; i < isPrimeLength ; i++){
            if( isPrime[i]){
                long prime = 2 * i + 3;
                long revrse= reversePrime(prime);
                if ( (!(prime==revrse)) && (!reversedCheckedPrime.contains(revrse)) && 
                        (reversedCheckedPrime.size()<=MAXLISTSIZE)){
                    reversedCheckedPrime.add(prime);
                }
                if (reversedCheckedPrime.size()==MAXLISTSIZE){
                    break;
                }
            }
        }   

        for (Long prime : reversedCheckedPrime){
            System.out.println(prime);
        }

    }
    private static long reversePrime(long prime) {
        long result=0;
        long rem;
        while(prime!=0){
            rem = prime % 10;
            prime = prime / 10;
            result = result * 10 + rem ;
        }
        return result;
    }
    private static boolean[] isPrime() {
        int root=(int) Math.sqrt(lONGMAX)+1;
        root = root/2-1;
        int limit= (int) ((lONGMAX-1)/2);
        boolean[] isPrime=new boolean[limit];
        Arrays.fill(isPrime, true);
        for(int i = 0 ; i < root ; i++){
            if(isPrime[i]){
                for( int j = 2 * i * (i + 3 ) + 3, p = 2 * i + 3; j < limit ; j = j + p){
                    isPrime[j] = false;
                }
            }

        }
        return isPrime;
    }
}
公共类反向时间{
最终静态长最大长度=10000000000000L;
最终静态int MAXLISTSIZE=1000000;
最终静态布尔值[]isPrime=isPrime();
公共静态void main(字符串…字符串){
Set reversedCheckedPrime=new LinkedHashSet();
int isPrimeLength=isPrime.length;
对于(int i=0;i(reversedCheckedPrime.size()实际上,您应该将布尔值[]替换为一个列表,因为内存不足可能来自此表。您没有使用最佳策略,因为您正在为每个长期存在的值堆叠所有值。

你最好只记住素数,试着重新思考素数的定义,然后进行迭代推导。

你实际上应该替换布尔值[]如果将列表作为内存不足的原因,则可能来自此表。您没有使用最佳策略,因为您正在为每个长期存在的值叠加所有值。
你最好只记住素数,试着重新思考素数的定义,然后进行迭代推导。

有两种可能性:

  • 您使用
    -Xmx256M
    ,这意味着一个256 MB的堆。但是,堆不仅仅是堆,当您的虚拟机试图获取更多时,它可能会被杀死


  • 您为虚拟机提供了256 MB,但您的程序需要更多的内存,因此会被终止。
    有两种可能性:

    • 您使用
      -Xmx256M
      ,这意味着一个256 MB的堆。但是,堆不仅仅是堆,当您的虚拟机试图获取更多时,它可能会被杀死

    • 您为虚拟机提供了256 MB,但您的程序需要更多的内存,因此被终止。
      您声明:

      final static long lONGMAX=1000000000000000L;
      
      然后在分配布尔数组时,计算:

      int limit= (int) ((lONGMAX-1)/2);
      
      根据该定义,
      limit
      将为
      1382236159
      。假设布尔值为一个字节,则为1.3Gb。您可能会认为VM仅为每个布尔值分配一位,但它不是这样工作的

      考虑改用a。

      您声明:

      final static long lONGMAX=1000000000000000L;
      
      然后在分配布尔数组时,计算:

      int limit= (int) ((lONGMAX-1)/2);
      
      根据该定义,
      limit
      将为
      1382236159
      。假设布尔值为一个字节,则为1.3Gb。您可能会认为VM仅为每个布尔值分配一位,但它不是这样工作的


      考虑改用a。

      你试过进入调试模式吗?@GarySEBASTIANI现在我有一件事
      boolean[]isPrime=new boolean[limit]
      占用了这么多内存13822366159字节,这意味着它大约是
      1382.236159MB
      如果我没有错,我应该使用
      位集
      ,但是除以
      8
      在内存方面不会有任何区别吗?是的,看看我下面的评论。你可以看看@ankura,你不需要那么多。对于1M的结果,100万个数字就足够了(我的答案)。+++位集将有助于因子8,但我认为你不需要它。@sébastienlecallonec Title hackedHave你尝试过进入调试模式吗?@GarySEBASTIANI现在我有一件事
      boolean[]isPrime=new boolean[limit]
      占用了这么多内存13822366159字节,这意味着它大约是
      1382.236159MB
      如果我没有错,我应该使用
      位集
      ,但是除以
      8
      在内存方面不会有任何区别吗?是的,看看我下面的评论。你可以看看@ankura,你不需要那么多。对于1M的结果,1亿个数字就足够了(我的答案)“++”
      位集
      将有助于因子8,但我认为你不需要它。@Sébastienlecallonec Title hackedNo,他正在进行筛选,每2个数字有1个字节,它的密度大约与你的
      列表
      一样,而且速度快得多。他只是不必要地分配了太多。是的,这正是我试图解释的,当我说的是堆叠所有数字可能不是一个好的解决方案。我建议使用列表,因为使用它,他可以获得相同的结果,只保留素数值,但列表中的每个值至少需要8个字节用于对象,4个字节用于引用。因此,每个素数为12个字节,而每个数字为0.5个字节,这在平均每24个字节的范围内是相等的数字是素数。+++更糟糕的是:你不能对列表进行有效的筛选。不,他在进行筛选,每2个数字有1个字节,它的密度大约与你的
      列表的密度一样,它是