Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在几个内部循环中使用大量内存_Java_Android_For Loop_Int_Heap Memory - Fatal编程技术网

Java 在几个内部循环中使用大量内存

Java 在几个内部循环中使用大量内存,java,android,for-loop,int,heap-memory,Java,Android,For Loop,Int,Heap Memory,我编写了一个静态方法,它使用4个内部循环,如下所示。我一直在对堆运行时使用的堆进行大量测试。它似乎生成了成千上万个“int[]”对象,我认为这些对象来自于我所设置的循环 我似乎找不到解决这个内存问题的方法,我需要循环,但我不需要为每个循环创建很多int[]对象,这只是一种浪费!这些是导致这些错误的循环本身吗?还有我能做些什么来减少内存使用,我在考虑增强for循环,但这可能是同样的问题 谢谢大家! public static double[] calculateHand(final int

我编写了一个静态方法,它使用4个内部循环,如下所示。我一直在对堆运行时使用的堆进行大量测试。它似乎生成了成千上万个“int[]”对象,我认为这些对象来自于我所设置的循环

我似乎找不到解决这个内存问题的方法,我需要循环,但我不需要为每个循环创建很多int[]对象,这只是一种浪费!这些是导致这些错误的循环本身吗?还有我能做些什么来减少内存使用,我在考虑增强for循环,但这可能是同样的问题

谢谢大家!

    public static double[] calculateHand(final int card1, final int card2, final int card3,
        final int card4, final int card5)
{
    int ahead = 0, tied = 1, behind = 2;
    int[][] HP = new int[3][3];
    int[] HPTotal = new int[3];

    int ourrank = HandEval.hand5Eval(HandEval.encode(card1, card2, card3, card4, card5));

    int[] remainingCards = filterCardsFromDeck(card1, card2, card3, card4, card5);

    int kM = 1

    for (int i = 0; i < remainingCards.length; i++)
    {

        for (int k = kM; k < remainingCards.length; k++)
        {
            int index = -1;
            int oCard1 = remainingCards[i];
            int oCard2 = remainingCards[k];

            int opprank = HandEval.hand5Eval(HandEval
                    .encode(oCard1, oCard2, card3, card4, card5));

            if (ourrank > opprank)
            {
                index = ahead;
            }
            else if (ourrank == opprank)
            {
                index = tied;
            }

            else
            {
                index = behind;
            }

            HPTotal[index]++;
            int[] newArray = filter2Cards(remainingCards, oCard1, oCard2);

            int riverMinimumIndex = 1;
            for (int turnIndex = 0; turnIndex < newArray.length; turnIndex++)
            {

                for (int riverIndex = riverMinimumIndex; riverIndex < newArray.length; riverIndex++)
                {

                    int turnCard = newArray[turnIndex];
                    int riverCard = newArray[riverIndex];
                    int ourbest = HandEval.hand7Eval(HandEval.encode7(card1, card2, card3, card4,
                            card5, turnCard, riverCard));

                    int oppbest = HandEval.hand7Eval(HandEval.encode7(oCard1, oCard2, card3, card4,
                            card5, turnCard, riverCard));

                    if (ourbest > oppbest)
                    {
                        HP[index][ahead]++;
                    }

                    else if (ourbest == oppbest)
                    {
                        HP[index][tied]++;
                    }

                    else
                    {
                        HP[index][behind]++;
                    }
                }
                riverMinimumIndex++;
            }
        }
        kM++;
    }

    .....

    return result;
}
public static double[]calculateHand(最终整数卡1、最终整数卡2、最终整数卡3、,
最终积分卡4,最终积分卡5)
{
前面的整数=0,后面的整数=2;
int[]HP=新int[3][3];
int[]HPTotal=新int[3];
intourrank=HandEval.hand5Eval(HandEval.encode(card1、card2、card3、card4、card5));
int[]剩余卡片=来自卡片组的过滤器卡片(卡片1、卡片2、卡片3、卡片4、卡片5);
整数公里=1
for(int i=0;iopprank)
{
指数=前进;
}
else if(ourrank==opprank)
{
指数=平局;
}
其他的
{
指数=落后;
}
HPTotal[索引]+;
int[]newArray=filter2Cards(剩余卡片、OCAD1、OCAD2);
int-riverMinimumIndex=1;
对于(int turndex=0;turndex我们最好的)
{
惠普[指数][领先]++;
}
else if(ourbest==oppbest)
{
惠普[指数][平局]++;
}
其他的
{
惠普[指数][落后]++;
}
}
riverMinimumIndex++;
}
}
kM++;
}
.....
返回结果;
}

我猜是堆膨胀,就像您所说的那样,在VM的开发过程中可能会被捕获。并非不可能您看到了一个VM问题,但是如果您没有发布其余的代码,我猜问题不仅仅是循环,更可能是您在其他代码中引入的东西。如果您发布了这篇文章,或许我们可以提供更多帮助。

有四个地方可以使用该方法创建(或可能创建)数组:

int[][] HP = new int[3][3];
int[] HPTotal = new int[3];
...
int[] remainingCards = filterCardsFromDeck(card1, card2, card3, card4, card5);
...
int[] newArray = filter2Cards(remainingCards, oCard1, oCard2);
(您调用的其他一些方法也可能创建…和放弃…临时数组。应该很容易找到它们。)

前三种情况在方法的每次调用中发生一次,可能不是什么大问题。最后一个循环发生在第二级循环中,并且(如果我的读数正确)将执行
O(N**2)
次,其中
N
是卡数

怎么办?(显而易见的答案是不要管它,除非你有明确的证据表明它会影响应用程序的性能。但我认为你已经超越了这一点。)

我能想到的最好办法是重构代码,以便
filter2Cards
将现有数组作为参数,并用过滤后的卡片填充它。它需要返回一个
int
,给出添加到数组中的值的数量,下面的代码需要使用这个值而不是数组的长度。然后将数组的创建移动到最外层循环之前


显然,这会使代码更加复杂。这是您要支付的惩罚…

您需要显示“操作”位中的内容显然…已完成,无法准确定位罪犯可能是这一行:int[]newArray=filter2Cards(剩余卡片、OCAD1、OCAD2)@Mitch Wheat,剩下的卡片不应该包含超过47(可能更少)的整数,这就像2200次迭代,HandEval.hand7Eval和特别是HandEval.encode7处于最内部的循环中,这是我的错。我刚开始写“有什么问题”,就注意到了“android”。我不知道它的JVM是如何工作的,所以我不能真正地提供一些建议。但是,如果在最里面的循环中有分配,请通过在方法的开头分配int[]来重用它。“它需要返回一个int,给出添加到数组中的值的数量,下面的代码需要使用这个值而不是数组的长度。”只需使用ArrayList。是的。。。这会更简单。