Java 在几个内部循环中使用大量内存
我编写了一个静态方法,它使用4个内部循环,如下所示。我一直在对堆运行时使用的堆进行大量测试。它似乎生成了成千上万个“int[]”对象,我认为这些对象来自于我所设置的循环 我似乎找不到解决这个内存问题的方法,我需要循环,但我不需要为每个循环创建很多int[]对象,这只是一种浪费!这些是导致这些错误的循环本身吗?还有我能做些什么来减少内存使用,我在考虑增强for循环,但这可能是同样的问题 谢谢大家!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
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。是的。。。这会更简单。