I wrote a static method that uses 4 inner loops set-up like the ones below. I have been doing lots and lots of testing on the heap used when it runs. It seems to generate thousands and thousands of "int[]" objects, I think that these are coming from the loops I have put in place.
I can't seem to find a way around this memory problem, I need the loops but I don't need lots of int[] objects created for every loop its just a waste! Are these the loops themselves that are causing these errors? And is there anything I can do to reduce the memory usage, I was thinking about enhanced-for-loop, but that might be the same problem...
Thank you!
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,开发者_Go百科 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;
}
There are four places where arrays are created (or probably created) in that method:
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);
(It is also possible that some of the other methods you call create ... and discard ... temporary arrays. It should be easy to spot them.)
The first three happen once per call of your method and are probably not a significant problem. The last one occurs in a 2nd level loop, and (if my reading is correct) will be executed O(N**2)
times where N
is number of cards.
What to do about it? (The obvious answer is to just leave it alone, unless you have clear evidence that it effects application performance. But I assume you are past that.)
The best I can think of is to refactor your code so that filter2Cards
takes an existing array as an argument, and fills it with the filtered cards. It would need to return an int
giving the number of values added to the array, and the following code would need to use this value instead of the array's length. Then move the creation of the array to before the outermost loop.
Obviously, this makes your code more complicated. That's the penalty you pay ...
My guess is a heap inflation like your talking about would have been caught as part of the development of the VM. Its not impossible that you are seeing a VM issue, but without you posting the rest of your code, my guess is that the problem isn't just the loops and is more likely something you've introduced in your other code. If you post that, perhaps we can be of more help.
精彩评论